آشنایی و تعامل بیشتر با شیء Vue

Learn More and Interact with Vue Object

Vue.JS 2: آشنایی و تعامل بیشتر با شیء Vue – قسمت 21

به فصل جدید خوش آمدید. در این فصل می خواهیم نگاهی تئوری تر به Vue داشته باشیم و شیء Vue را به طور مفصل بررسی کنیم. متوجه هستم که اکثر شما از مباحث تئوری خوشتان نمی آید اما این مباحث درک عمیقی را نسبت به نحوه کار Vue در پشت پرده به شما خواهد داد و در کل توسعه دهنده بهتری از شما می سازد بنابراین سعی کنید تا حد امکان چند ویدیوی کوتاه این فصل را مرور کنید.

برای این جلسه کدهای ساده ای را برایتان آماده کرده ام. برنامه ای که فقط یک button دارد و با فشردن آن یک پاراگراف نمایش داده می شود. کدهای HTML:

<script src="https://unpkg.com/vue/dist/vue.js"></script>

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

کدهای جاوا اسکریپت:

new Vue({
  el: '#app',
  data: {
    title: 'The VueJS Instance',
    showParagraph: false
  },
  methods: {
    show: function() {
      this.showParagraph = true;
      this.updateTitle('The VueJS Instance (Updated)');
    },
    updateTitle: function(title) {
      this.title = title;
    }
  },
  computed: {
    lowercaseTitle: function() {
      return this.title.toLowerCase();
    }
  },
  watch: {
    title: function(value) {
      alert('Title changed, new value: ' + value);
    }
  }
});

در قسمت data یک خصوصیت به نام title داریم که همان عنوان صفحه ما است و اگر کدهای بالا را اجرا کنید این عنوان را مشاهده خواهید کرد. سپس با v-on یک دکمه را به متد show متصل کرده ایم. همچنین یک v-if را روی پاراگراف گذاشته ام که به صورت مشروط نمایش داده شود. اگر به متد show نگاه کنید، متوجه می شوید که در ابتدا خصوصیت showParagraph را روی true می گذارد و سپس متدی را به نام updateTitle را صدا می زند. این متد فقط title صفحه ما را تغییر می دهد. همچنین در قسمت Watch خصوصیت title را زیر نظر گرفته ایم بنابراین هر زمان که عنوان صفحه تغییر کند یک alert به ما نمایش داده می شود. نهایتا یک خصوصیت computed نیز داریم که مشاهده می کنید (title را با حروف کوچک برمی گرداند).

در کد بالا چهار خصوصیت (property) از شیء Vue را مشاهده می کنید:

  • el
  • data
  • methods
  • computed

یادتان نرود که شیء Vue نهایتا یک شیء جاوا اسکریپتی است بنابراین دارای خصوصیات (property) و متد (method) است. هر چهار موردی که بالاتر گفتم از خصوصیات این شیء می باشند. حتی methods یک خصوصیت است که درون خودش (به عنوان مقدارِ خصوصیت) متد هایی را ذخیره کرده است.

ما با تمام این مسائل تا حدی آشنا شدیم اما دو سوال اصلی بدون پاسخ مانده است:

  • آیا می توانیم چند نمونه از شیء Vue را داشته باشیم؟
  • آیا می توانیم در کدهای جاوا اسکریپت اما خارج از شیء Vue، به آن دسترسی داشته باشیم؟

برای بررسی سوال اول می توانیم کدهای HTML خود را به دو div به شکل زیر تقسیم کنیم:

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

<div id="app2">
  <h1 ref="heading">{{ title }}</h1>
</div>

همانطور که می بینید id اصلی برنامه که app بود را روی app1 گذاشته ام و سپس یک کپی با آیدی app2 از آن ایجاد کرده ام. حالا به کدهای جاوا اسکریپت بروید و el را مطابق با این تغییر، ویرایش کنید:

new Vue({
  el: '#app1',
  data: {
// بقیه کدها //

حالا خارج از این شیء Vue، یک شیء دیگر به شکل زیر می سازیم (من تمام کدها را قرار می دهم تا متوجه شوید منظورم از «خارج از شیء Vue» چیست):

new Vue({
  el: '#app1',
  data: {
    title: 'The VueJS Instance',
    showParagraph: false
  },
  methods: {
    show: function() {
      this.showParagraph = true;
      this.updateTitle('The VueJS Instance (Updated)');
    },
    updateTitle: function(title) {
      this.title = title;
    }
  },
  computed: {
    lowercaseTitle: function() {
      return this.title.toLowerCase();
    }
  },
  watch: {
    title: function(value) {
      alert('Title changed, new value: ' + value);
    }
  }
});

new Vue ({
  el: '#app2',
  data: {
    title: 'The second instance'
  }
});

همانطور که می بینید در کد بالا دو شیء مختلف یا دو نمونه مختلف از کلاس Vue داریم. آیا انجام این کار مشکلی دارد؟ خیر، شما می توانید هر زمانی که خواستید چندین نمونه از شیء Vue را ایجاد کنید.

نکته: دو نمونه مختلف از شیء Vue هیچ ربطی به هم ندارند بنابراین زمانی که در شیء اول از this.title استفاده می کنید، فقط به خصوصیت title درون همان شیء اول اشاره خواهید کرد و هیچ ارتباطی با شیء دوم نخواهید داشت. راه میانبری برای صدا زدن یک متد از یک شیء Vue درون یک شیء دیگر Vue وجود دارد اما به هیچ وجه توصیه نمی شود؛ اگر بین دو شیء Vue شما ارتباطی وجود دارد، آن ها را ادغام کنید.

احتمالا کنجکاو هستید که چطور می توانیم به کدهای یک شیء Vue خارج از آن دسترسی پیدا کنیم (مثلا در یک Vue دیگر). در ابتدا زمانی که یک شیء Vue می سازید باید آن را درون یک متغیر قرار بدهید. مثلا:

var vm1 = new Vue({
  el: '#app1',
  data: {
    title: 'The VueJS Instance',
    showParagraph: false
  },

// بقیه کدها //

این کار را روی نمونه دوم Vue نیز انجام می دهیم:

var vm2 = new Vue ({
  el: '#app2',
  data: {
    title: 'The second instance'
  }
});

حالا یک دکمه را برای app2 تعریف می کنم تا با کلیک روی آن چیزی در app1 تغییر کند. به کدهای HTML من نگاه کنید:

<div id="app2">
  <h1 ref="heading">{{ title }}</h1>
  <button @click="onChange">Change something in Vue 1</button>
</div>

من هیچ چیزی را تغییر ندادم به جز اینکه یک button اضافه کرده ام که در صورت کلیک شدن متدی به نام onChange را اجرا خواهد کرد. این متد تعریف نشده است بنابراین به کدهای جاوا اسکریپت می روم و onChange را درون App2 تعریف می کنم:

var vm2 = new Vue ({
  el: '#app2',
  data: {
    title: 'The second instance'
  },
  methods: {
    onChange: function () {
      vm1.title = 'Changed!';
    }
  }
});

به نظر شما کد بالا کار می کند؟ بله! یادتان باشد که vm1 همان متغیری است که نمونه اول Vue را در خود ذخیره دارد. مسئله کار کردن یا نکردن کد نیست، مسئله اینجاست که اگر واقعا این دو نمونه از کلاس Vue به هم مرتبط هستند، نیازی به جدا کردن آن ها و ایجاد دردسر برای خودتان نیست. همیشه توصیه می شود که شیء های Vue شما از یکدیگر کاملا مستقل باشند.

در ضمن نیازی نیست که حتما از یک شیء دیگر Vue به آن دسترسی پیدا کنیم. بلکه می توانیم با کدهای ساده جاوا اسکریپت نیز این کار را انجام بدهیم:

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

// کدهای ساده جاوا اسکریپتی، خارج از هر دو شیء
setTimeout (function () {
  vm1.title = 'Changed by timer';
}, 3000)

// کدهای مربوط به شیء دوم ویو
var vm2 = new Vue ({
  el: '#app2',
  data: {
    title: 'The second instance'
  },
  methods: {
    onChange: function () {
      vm1.title = 'Changed!';
    }
  }
});

حالا اگر 3 ثانیه صبر کنیم، تابع setTimeout اجرا شده و title را تغییر می دهد. بنابراین می توانیم از هر قسمتی از برنامه به شیء های Vue دسترسی داشته باشیم و هیچ اشکالی در پیاده سازی این روش وجود ندارد اما کارتان را سخت می کند.

نکته: همانطور که می دانید خصوصیت title درون data است بنابراین نحوه صحیح صدا زدن آن باید به شکل vm1.data.title می بود. چرا اینطور نیست؟ به دلیل اینکه Vue خصوصیات ما را proxy می کند، یعنی آن ها را به سطح بالاتری می برد (زمانی که به constructor تحویل داده می شوند به عنوان خصوصیت خود کلاس تعیین می شوند) تا به صورت راحت تری در اختیار ما باشند.

در قسمت بعدی در این رابطه بیشتر صحبت خواهیم کرد.

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

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