استفاده از ref$ در قالب‌های HTML

Use $ref in HTML formats

Vue.JS 2: استفاده از ref$ در قالب های HTML - قسمت 23

در قسمت قبل در مورد دو خصوصیت شیء Vue صحبت کردیم که el$ و data$ بودند. در این قسمت می خواهم کمی در مورد خصوصیت ref$ توضیح بدهم. این خصوصیت از آن دسته خصوصیت هایی است که بهتر است با دقت فراوان از آن استفاده شود چرا که استفاده نادرست می تواند باعث بهم ریختن برنامه شما بشود. به کد زیر توجه کنید:

<div id="app1">
  <h1>{{ title }}</h1>
  <button v-on:click="show">Show Paragraph</button>
  <p v-if="showParagraph">This is not always visible</p>
</div>

در حال حاضر اگر دسترسی پیدا کردن به محتوای دکمه بالا (منظورم innerHtml است که می شود عبارت show paragraph) آنچنان کار آسانی نیست. اگر از جاوا اسکریپت ساده استفاده می کردیم، گزینه querySelector را داشتیم و می توانستیم از آن استفاده کنیم اما در Vue اینطور نیست. البته همیشه می توانید جاوا اسکریپت ساده را به همراه Vue استفاده کنید اما من می خواهم در این قسمت فقط از Vue استفاده کنم.

در Vue می توانیم از attribute خاصی به نام ref (مخفف reference و به معنی «ارجاع») استفاده کنیم که در HTML معنا ندارد و مخصوص Vue است:

  <button v-on:click="show" ref="myButton">Show Paragraph</button>

همانطور که می بینید ref یک رشته دریافت می کند که کاملا سلیقه ای است و شما می توانید هر مقداری را (به شرطی که رشته باشد) در آن قرار دهید. من myButton را انتخاب کرده ام. شما می توانید این کار را برای هر تعداد عنصری که دوست دارید، انجام بدهید. تمام این عناصر با استفاده از همان رشته پاس داده شده در ref قابل «ارجاع» هستند. به طور مثال من می گویم:

var vm1 = new Vue({
  el: '#app1',
  data: data,
  methods: {
    show: function () {
      this.showParagraph = true;
      this.updateTitle('The VueJS Instance (Updated)');
      console.log(this.$refs);
    },
// بقیه کدها //

یعنی زمانی که متد Show اجرا شد، تمام ref های ما چاپ بشود تا آن ها را مشاهده کنیم.

نمایش ref های شما در کنسول مرورگر
نمایش ref های شما در کنسول مرورگر

همانطور که مشاهده می کنید، با اجرای این کد (باید روی کلید show paragraph کلیک کنید) یک شیء در کنسول من نمایش داده می شود که با باز کردن آن به تصویر بالا می رسیم. بنابراین myButton از نوع button (دکمه HTML) است (در خط اول نوشته شده است). خصوصیات دیگری نیز در این تصویر وجود دارد که همگی مربوط به دکمه ما است. با این حساب می توان گفت:

    show: function () {
      this.showParagraph = true;
      this.updateTitle('The VueJS Instance (Updated)');
      console.log(this.$refs.myButton);
    }

یعنی می توانیم از مقدار داده شده به Ref به عنوان key برای دسترسی به ref خاص خود استفاده کنیم. بنابراین با تکمیل کردن کد بالا می توان گفت:

    show: function () {
      this.showParagraph = true;
      this.updateTitle('The VueJS Instance (Updated)');
      this.$refs.myButton.innerText = 'Test';
    }

یعنی با اجرا شدن تابع show باید innerHtml دکمه من به Test تغییر پیدا کند. اگر صفحه را refresh کرده و تابع را اجرا کنید، متن دکمه از show paragraph به Test تغییر پیدا خواهد کرد.

حالا اگر این کار را برای عنصری انجام بدهم که محتوای آن تحت کنترل Vue است چه اتفاقی خواهد افتاد؟ به طور مثال:

<div id="app1">
  <h1 ref="heading">{{ title }}</h1>
  <button v-on:click="show" ref="myButton">Show Paragraph</button>
  <p v-if="showParagraph">This is not always visible</p>
</div>

من ref جدیدی به نام heading را به title پاس داده ام اما محتوای title خودش تحت نظر Vue است. حالا اگر خارج از شیء Vue (برای app1) و قبل از تابع setTimeout مقدار heading را تغییر بدهم چه می شود؟

// کدهای مربوط به اپ یک
  watch: {
    title: function (value) {
      alert('Title changed, new value: ' + value);
    }
  }
});

// کد تغییر عنوان //
vm1.$refs.heading.innerText = 'something else';

تابع تایم اوت
setTimeout(function () {
  vm1.title = 'Changed by timer';
  vm1.show();
}, 3000)

// کدهای مربوط به اپ دو
var vm2 = new Vue({
  el: '#app2',
  data: {
    title: 'The second instance'
  },

اگر کدهای بالا را اجرا کنید، عنوان به درستی به something else تغییر می کند اما پس از اجرا شدن setTimeout مقدار آن به The VueJS Instance (Updated) برمی گردد. چرا؟ به دلیل اینکه String interpolation (استفاده از {{ و }} برای نمایش title) باطل و overwrite نمی شود. چرا؟

اگر یادتان باشد به شما گفتم که Vue تغییرات را مستقیما در DOM ایجاد نمی کند بلکه کدهای HTML را گرفته و یک نسخه کپی از کدهای HTML را در حافظه خود نگه می دارد. به همین دلیل است که می توانیم درون کدهای HTML از syntax هایی مانند click@ و ref استفاده کنیم – ما آن ها را واقعا در HTML نمی نویسیم، بلکه کدهای HTML بعدا توسط Vue تولید شده و به کاربر ارائه می شوند. زمانی که ما خارج از Vue و به صورت مستقیم (مانند کد بالا) تغییراتی را برای title ایجاد می کنیم، این تغییرات درون DOM اعمال می شوند اما آن نسخه کپی شده در Vue هیچ تغییری نمی کند. بنابراین نهایتا نسخه کپی Vue جایگزین title می شود.

نکته مهم اینجاست که شما می توانید به صورت مستقیم با عوامل DOM تعامل داشته باشید اما تغییرات شما در نسخه کپی Vue اعمال نشده و واکنش پذیر نخواهند بود بنابراین ممکن است به طور کل حذف شوند. معمولا کدهایی که برای گرفتن یک مقدار نوشته می شوند مشکلی ندارند اما کدهایی که برای اعمال تغییرات هستند، باعث ایجاد مشکل خواهند شد. امیدوارم این نکته را از یاد نبرید.

تمام فصل‌های سری ترتیبی که روکسو برای مطالعه‌ی دروس سری آموزش رایگان Vue js از صفر تا صد توصیه می‌کند:
نویسنده شوید
دیدگاه‌های شما

در این قسمت، به پرسش‌های تخصصی شما درباره‌ی محتوای مقاله پاسخ داده نمی‌شود. سوالات خود را اینجا بپرسید.