Vuex چیست و چه کاربردی دارد؟ + پروژه عملی

Vuex Tutorial From Scratch

13 مرداد 1402
vuex-in-vuejs

Vuex یک افزونه Vue است که به عنوان یک ذخیره‌ساز مرکزی داده برای تمام بخش‌های برنامه front-end شما عمل می‌کند. یک برنامه Vue از تعداد زیادی کامپوننت مجزا اما هماهنگ تشکیل شده است که وقتی کنار هم قرار می گیرند، یک برنامه کاربردی front-end را ایجاد می کنند. شما ممکن است یک صفحه برای ویرایش کاربران، یک صفحه برای نمایش کاربران و یا یک صفحه برای نشان دادن یک کاربر خاص داشته باشید. همه این صفحه ها و کامپوننت ها باید با هم کار کنند و با یکدیگر ارتباط داشته باشند تا بتوانیم یک برنامه کامل و کاربردی داشته باشیم.

Vue.js یک کتابخانه برای توسعه frontend است که برای طراحی رابط کاربری به کار می رود و امروزه محبوبیت زیادی پیدا کرده است. Vuex یکی از پیاده‌سازی‌های مدل Vue js است، یا به عبارت دیگر می‌توان گفت یک State برای نمایش داده‌ها است.

Vuex چیست؟

Vuex یک الگو یا کتابخانه برای مدیریت state برنامه است و به عنوان یک ذخیره ساز داده های برنامه کار می کند. ایده اصلی برای ساخت آن از کتابخانه Redux و Flux React الهام گرفته شده است. استفاده از Vuex زمانی مطرح می شود که برنامه سمت کلاینت پیچیده و پیچیده تر می شود. اگر برنامه پیچیده نباشد، نباید از Vuex استفاده کرد زیرا اگر به درستی با این کتابخانه کار نشود، استفاده از آن پیچیده و گیج کننده خواهد بود.

یک برنامه ساخته شده با Vuex از بخش های زیر تشکیل شده است:

  • state: برنامه را هدایت و راه اندازی می کند.
  • view: یک نگاشت تعریفی از state است.
  • actions: همه راه‌های ممکنی که state می‌تواند در واکنش به ورودی‌های کاربر تغییر کند، است.

شکل زیر یک نمایش از مفهوم "جریان داده یک طرفه" است:

جریان داده یک طرفه

action ها mutation ها را فراخوانی می کنند و mutation ها شی را تغییر می دهند. بنابراین state با توجه به یک action فعال تغییر می کند. state برنامه تغییر می کند و با توجه به آن کامپوننت تغییرات را مشخص می کند و براساس آن واکنش می دهد.

کامپوننت Vue در واکنش به یک رویداد یک action را آغاز می کند. با توجه به نوع action، mutation رخ می دهد و سپس state تغییر می کند و سایر اجزای Vue از این تغییرات مطلع می شوند.

state

اگر از Vuex استفاده کنید، آنگاه برای هر برنامه ساخته شده با VueJS فقط یک store خواهید داشت. استور Vuex یک منبع یکتا ساخته شده از state است. store دارای یک نمونه از state برنامه است. مدیریت state در VueJS با استفاده از Vuex ساده است. باید state را از طریق فرستادن action تغییر دهید و نه به طور مستقیم، زیرا می‌خواهیم  state ‌های آینده را با استفاده از آن پیش‌بینی کنیم.

mutation ها

تنها راه برای تغییر state در استور Vuex، انجام یک mutation است. می‌توانیم به طور مستقیم state را تغییر دهیم، اما این کار را انجام نمی‌دهیم زیرا برای هر مرحله از پروژه خود به مقدار state نیاز داریم. برای جلوگیری از بروز اشکال، state را به طور مستقیم تغییر نمی دهیم، بلکه این کار را از طریق mutation ها انجام می دهیم.

action ها

action ها مشابه mutation ها هستند ولی تفاوت هایی نیز دارند که در زیر آمده است:

  • action ها به جای تغییر state، تغییر یا mutation ایجاد می کنند.
  • action ها می توانند شامل عملیات ناهمزمان (asynchronous) باشند.

الگوی مدیریت state چیست؟

همان طور که در بالا گفته شد یک برنامه Vue از بخش های state، view و actions تشکیل شده است.به شکل زیر نگاه کنید:

شکل بالا جریان داده یک طرفه داده در یک برنامه Vue را نشان می دهد.

وقتی چندین کامپوننت داریم که state مشترکی دارند، سادگی از بین می رود:

  • view های متعدد ممکن است به state یکسان وابسته باشند.
  • action هایی که از view های مختلف هستند ممکن است نیاز به تغییر یک state واحد داشته باشند.

برای مشکل اول، فرستادن prop ها می تواند برای کامپوننت های تو در تو خسته کننده باشد و برای کامپوننت هایی که پدر مشترکی دارند کار نمی کند.

برای مشکل دوم دو راه حل داریم:

  • دستیابی به ارجاع های مستقیم پدر/فرزند
  • تغییر و همگام‌سازی چندین نسخه از state با استفاده از رویدادها

هر دو این راه‌حل‌ها شکننده هستند و به کدهای غیرقابل نگهداری منجر می شوند.

پرسش: چرا state اشتراکی را از کامپوننت استخراج نکنیم و آن را به صورت سراسری (global) مدیریت نکنیم؟

با این کار، درخت کامپوننت به یک «View» بزرگ تبدیل می‌شود و هر کامپوننتی در هر جایی از درخت که باشد به state دسترسی پیدا می کند و ممکن است action لازم را راه‌اندازی کند.

با تعریف و جداسازی مفاهیم دخیل در مدیریت state و اجرای قوانینی که استقلال بین view ها و state ها را حفظ می کند، به کد خود قابلیت نگهداری بیشتری می دهیم.

چرا به Vuex نیاز داریم؟

نمودار جریان داده که تصویر آن در پایین آمده است به توسعه دهندگان کمک می کند تا بفهمند که آیا برای برنامه خود به Vuex نیاز دارند یا خیر:

همچنین در اسناد Vuex بخشی وجود دارد که به طور خلاصه توضیح می دهد چه زمانی باید از Vuex استفاده کنید.زمانی که چندین کامپوننت داشته باشیم که یک state مشترک دارند جریان داده قبلی به سرعت از بین می رود:

  • view های متعدد ممکن است به یک state یکسان بستگی داشته باشند.
  • action ها از دیدگاه‌های مختلف ممکن است نیاز به تغییر در یک state واحد داشته باشند.

این زمانی است که Vuex به کمک می آید.

Vuex یک سیستم مدیریت state است. بنابراین، برای درک آنچه Vuex انجام می دهد، ابتدا باید درک خوبی از مفهوم state در یک SPA و نحوه تعامل آن با سایر عناصر داشته باشید.

state داده‌هایی است که کامپوننت های برنامه به آن وابسته هستند. به عنوان مثال، کارهای موجود در لیست کارهای روزانه، یا پست های یک وبلاگ. هر کامپوننت Vue تنها می تواند یک state داشته باشد.

همان طور که برنامه رشد می کند، ممکن است تعداد کامپوننت ها نیز افزایش یابند. اگر از کتابخانه مدیریت state مانند Vuex استفاده نکنید، هر یک از این کامپوننت ها با استفاده از API های Vue.js که برای این منظور طراحی شده اند، state خود را مدیریت می کنند.

به خاطر داشته باشید که Vue یک معماری کامپوننت درختی را همانطور که در بالا نشان داده شده است حفظ می کند و همچنین ارتباط پدر-فرزند را از طریق prop ها و ارتباط فرزند-پدر را از طریق رویدادها امکان پذیر می کند. می توان تصور کرد دو state که پدر یکسانی دارند برای واکنش نشان دادن به تغییر داده‌های یکسان چه مراحل پیچیده ای را باید پست سر بگذارند. باید داده‌ها را از فرزند به پدر منتقل کنیم تا از آن جا به نزدیک‌ترین جد و سپس از آن جد به یک فرزند خاص فرستاده شود.(نگاه کنید به اجزای برجسته شده در شکل بالا).

این کار بسیار پر زحمت و دارای خطاهای احتمالی زیادی است.

این دقیقا همان جایی است که Vuex وارد می‌شود. Vuex کار نگهداری state یک ماژول و نگهداری آن را در یک store متمرکز را انجام می‌دهد، که از الگوی مدیریت استیت Vuex پیروی می‌کند و بر این اساس با کامپوننت های شما ارتباط برقرار می‌کند.

به همین دلیل است که اغلب از آن به عنوان «the single source of truth یا منبع واحد حقیقت» یاد می شود. اگرچه Vuex به این شکل نامیده می شود، اما این واقعیت را تغییر نمی دهد که کامپوننت ها همچنان می توانند state های خود را داشته باشند.

اکنون که فهمیدید چرا ممکن است به یک سیستم مدیریت state مانند Vuex نیاز داشته باشیم، می‌توانیم دو دلیل اصلی که آیا state را باید با استفاده از Vue مدیریت کنیم یا نه را بررسی کنیم.

دلیل اول: اندازه برنامه

اغلب گفته می شود که «با رشد برنامه، به Vuex نیاز خواهید داشت». در واقع این بستگی به نحوه رشد آن دارد. برنامه شما ممکن است رشد کند اما جریان داده‌های شما هسته‌ای باقی می‌ماند (یعنی پدر-فرزند و خواهر و برادر نزدیک).

در نهایت، می‌توانید از ابزارها و رویدادها برای به اشتراک گذاشتن این داده‌ها استفاده کنید، بدون اینکه نیازی به اضافه کردن Vuex داشته باشید.

از طرف دیگر، به محض اینکه متوجه شدید که کامپوننت شما نیاز به یک منبع داده انتزاعی (یعنی یک منبع داده مشترک که قابلیت دسترسی به آن توسط سایر کامپوننت ها وجود داشته باشد) دارند، عاقلانه است که استفاده از prop ها و رویدادها را متوقف کنید و از Vuex کمک بگیرید. این باعث صرفه جویی در زمان می شود، زیرا هر چه دیرتر از Vuex استفاده کنید، نیاز بیشتری به دوباره نویسی کد دارید.

دلیل دوم : منطق و پیچیدگی داده

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

Vuex یک روش محبوب برای کنترل احراز هویت یک برنامه پیچیده در Vue است. با Vuex، می‌توانید در دسترس بودن توکن و مجوز ها و مسیرها را در سراسر برنامه خود مدیریت کنید. mutation ها، getter ها و setter ها به این کار کمک می کنند.

این الگو به شما کمک می کند منطق احراز هویت را به طور کامل از منطق برنامه جدا کنید. دارد.

چرا باید از Vuex استفاده کنیم و چرا نباید این کار را نکنیم؟

Vuex به ما کمک می کند تا با مدیریت state مشترک، دامنه مفاهیمی که باید بدانیم را کمتر کنیم. در واقع یک مبادله بین بهره وری کوتاه مدت و بلند مدت است.

اگر هرگز یک SPA در مقیاس بزرگ ایجاد نکرده اید و به طور مستقیم از Vuex استفاده نکرده اید، ممکن است ترسناک به نظر برسد. این کاملا طبیعی است. اگر برنامه شما ساده باشد، به احتمال زیاد بدون Vuex عملکرد خوبی خواهد داشت. یک الگوی store ساده ممکن است تمام چیزی باشد که برای ساخت برنامه به آن نیاز داشته باشید.

اما اگر در حال ساخت یک SPA در مقیاس متوسط تا بزرگ هستید، به احتمال زیاد با موقعیت‌هایی روبه رو شده‌اید که باعث شده است به مدیریت بهتر state کامپوننت های Vue فکر کرده باشید. Vuex انتخاب بعدی شما برای مدیریت state خواهد بود. نقل قول خوبی از دن آبراموف، سازنده Redux وجود دارد:

«کتابخانه های Flux مانند عینک هستند زمانی که به آن ها نیاز دارید، بسیار ضروری است که آن را پیاده سازی کنید.»

همچنین می گوید: "اگر برنامه شما دارای state های بسیار زیادی است و نمی توانید یک کتابخانه باز را مدیریت کنید، پس باید از Redux استفاده کنید." در مورد Vue باید از Vuex استفاده کرد.

به چند نکته زیر دقت کنید:

  • اگر برنامه بزرگتر شود و رشد کند، Vuex می تواند داده ها را به طور موثر مدیریت کند و هر action را در استور Vuex ثبت کند.
  • برنامه های کوچک نیازی به Vuex ندارند.
  • اگر می‌خواهید state را با سایر کامپوننت های برنامه اشتراک بگذارید، باید از Vuex استفاده کنید.

دلیل اصلی دوری برنامه نویسان از Vuex این است که کدهای زیادی دارد. باید این طور باشد. برای اطمینان از این که تغییرها در state شما اتفاق می‌افتد، باید از یک الگو پیروی کند. در زیر دو کامپوننت todo  آمده است که یکی از آن ها از Vuex استفاده می کند و دیگری از Vuex استفاده نمی کند:

تصویر بالا نشان می دهد که هنگام استفاده از Vuex برای مدیریت state خود در یک برنامه بسیار ساده، کد شما چقدر زیاد می شود. در مواردی مانند این، بهتر است از Vuex صرف نظر کنید و از prop ها و رویدادها یا یک الگوی ساده مدیریت state کمک بگیرید.

نصب Vuex

روش های نصب Vuex را در زیر بررسی می کنیم.

روش نخست: دانلود/CDN

Unpkg.com لینک‌های CDN مبتنی بر NPM را ارائه می‌دهد. این لینک همیشه به آخرین نسخه در NPM اشاره می کند. همچنین می‌توانید از طریق آدرس‌هایی مانند https://unpkg.com/vuex@4.0.0/dist/vuex.global.js از یک ورژن/تگ خاص استفاده کنید.

vuex را بعد از Vue قرار دهید تا به طور خودکار نصب شود:

NPM

npm install vuex@next --save

Yarn

yarn add vuex@next --save

DEV Build

اگر می‌خواهید از آخرین نسخه dev استفاده کنید، باید به طور مستقیم آن را از GitHub کلون کنید و خودتان vuex را بسازید.

git clone https://github.com/vuejs/vuex.git node_modules/vuex

cd node_modules/vuex

yarn

yarn build

یادگیری Vuex با ساخت یک پروژه

همه آموخته های خود را تا این جا در قالب یک پروژه پیاده خواهیم کرد. با این کار یادگیری ما کامل می شود و دیرتر از یاد می رود.

پروژه ای که این جا می سازیم یک برنامه todo ساده است.آموزش زیر را گام به گام دنبال کنید تا در پایان یک برنامه کارهای روزانه یا todo app داشته باشید.تصویر پروژه در زیر آمده است:

پیش نیازها

Node.js

ابتدا باید Vue CLI را نصب کنید. اگر Node.js را نصب نکرده اید، آن را از نشانی دانلود و نصب کنید.

اگر Node.js را نصب کرده اید، با خط node --version می توانید ورژن آن را بررسی کنید. همچنین با دستور npm install -g npm@latest می توانید آن را به روزرسانی کنید.

Vue CLI

از Vue CLI 3 برای ساخت استخوان بندی برنامه استفاده خواهیم کرد. اگر قبلا Vue CLI را نصب کرده اید، با دستور vue --version می توانید ورژن آن را بررسی کنید. اگر آن را نصب نکرده اید با دستور npm install -g @vue/cli آن را نصب کنید.

ایجاد پروژه با Vue CLI

اکنون که از ورژن های مناسب Node و Vue CLI استفاده می کنیم، می توانیم پروژه خود را ایجاد کنیم.

در ترمینال خود، به دایرکتوری که می خواهید پوشه پروژه شما در آن قرار گیرد، بروید. یا می  توانید یک پوشه ایجاد کنید و آن را با ویرایشگر کد خود باز کنید. من نام این پوشه را todo-app گذاشته ام و در Desktop من قرار دارد.سپس ترمینال vscode را باز کنید و دستور  . vue create  را اجرا می کنیم.

پس از این کار منویی برای پیکربندی پروژه به شما نمایش داده می شود. در نخست از شما خواسته می شود که آیا پروژه در این همین مسیر ایجاد شود یا نه. برای تایید y را ترمینال می نویسیم و سپس Enter را می زنیم:

پس از این کار باید گزینه Manually select features را انتخاب کنیم و Enter را بزنیم:

بعد از بین گزینه های ظاهر شده Vuex را انتخاب می کنیم و دوباره Enter را می زنیم:

بعد از گزینه های ظاهر شده ESLint + Standard config را انتخاب می کنیم:

پس از همه کارهای بالا منتظر می شویم تا پروژه ساخته شود. این کار ممکن است کمی طول بکشد. پس از نصب پروژه پیام زیر باید در ترمینال ظاهر شود:

مرور سریع Vuex

پیش از این که به کدنویسی را شروع کنیم، اجازه دهید Vuex را یکبار دیگر مرور کنیم:

در Vuex، چیزی به نام store داریم که یک شی global یا سراسی است که خود شامل چهار چیز اصلی است که برای مدیریت state در برنامه Vue به آن ها نیاز دارد. آن چیزها عبارتند از:

  • state: شی ای که داده های برنامه را نگه می دارد.
  • getter ها: توابعی که داده های موجود در state را برمی گرداند.
  • mutation: توابعی که مستقیما state را تغییر می دهند.
  • action ها: توابعی که mutation ها را فراخوانی می کنند. action ‌ها می‌توانند چندین mutation، action های دیگر و حتی سایر عملیات ناهمزمان را فراخوانی کنند.

یک کاربر با برنامه Vue تعامل خواهد داشت و این تعاملات باعث ایجاد action هایی می شود که باعث تغییر در state می شود. پس از تغییر state ،Vue کامپوننت های تغییر کرده را بر اساس این state جدید دوباره رندر می‌کند.

ساخت استور Vuex

اولین قدم در استفاده از Vuex این است که تصمیم بگیریم برنامه ما به چه داده هایی در state نیاز دارد. این برنامه مجموعه‌ای از کارهای روزانه (todo ها) را ردیابی می‌کند، بنابراین تنها چیزی که در state خود به آن نیاز داریم  todo ها هستند.

هر آیتم در آرایه باید چند تا چیز داشته باشد:

  • id: یک شماره شناسه یکتا برای متمایز کردن کارها
  • description: شرح کاری که باید انجام شود
  • flag: یک پرچم که به برنامه اطلاع دهد آیا کار انجام شده است یا خیر.

ساخت store

در پوشه src پروژه، یک پوشه جدید به نام store ایجاد کنید.یک فایل به نام store.js را در پوشه store ایجاد کنید.

در پوشه store، یک پوشه جدید به نام modules ایجاد کنید. سپس یک فایل جدید در پوشه modules به نام todos.js ایجاد کنید:

state

ابتدا یک آرایه خالی برای todo ها در فایل todos.js ایجاد می کنیم:

export const state = {
  todos: []
};

getter ها

بعد یک تابع Getter خواهیم ساخت که آرایه todos را برمی گرداند.

export const getters = {  getTodos: state => state.todos};

mutation ها

اکنون باید تصمیم بگیریم که state در کدام mutation قرار بگیرد. سه تغییر برای state وجود دارد که در نظر خواهیم گرفت:

  1. افزودن یک آیتم جدید: پس از تایپ یک مورد جدید، باید بتوانیم آن را به آرایه اضافه کنیم.
  2. کامل کردن یک آیتم: باید بتوانیم state تکمیل شده را بین true و false تغییر دهیم.
  1. حذف یک آیتم: زمانی که دیگر به آن نیاز نداریم باید بتوانیم یک آیتم را از آرایه حذف کنیم.
export const mutations = {
  ADD_TODO: (state, payload) => {
    const newTask = {
      id: payload.newId,
      task: payload.task,
      completed: false
    };
    state.todos.unshift(newTask);
  },
  TOGGLE_TODO: (state, payload) => {
    const item = state.todos.find(todo => todo.id === payload);
    item.completed = !item.completed;
  },
  DELETE_TODO: (state, payload) => {
    const index = state.todos.findIndex(todo => todo.id === payload);
    state.todos.splice(index, 1);
  }
};

mutation ها همچنین یک payload دریافت می کنند که اطلاعات مورد نیاز برای ایجاد تغییرات است. برای ADD_TODO، payload یک شی است که شامل id بعدی و شرح کار (description) است. TOGGLE_TODO و DELETE_TODO فقط به id کار نیاز دارند، بنابراین تنها چیزی است که به mutation ها می فرستیم.

کاری که در این سه تابع انجام می شود در زیر آمده است:

  • ADD_TODO: یک شی جدید ایجاد می شود و سپس به ابتدای آرایه اضافه می شود (با استفاده از متد unshift) بنابراین جدیدترین آیتم در بالای لیست ظاهر می شود.
  • TOGGLE_TODO: کاری که مطابق با id ارسال شده در payload است پیدا می شود و مقدار بولی state آن completed می شود.
  • DELETE_TODO: کاری که مطابق با id ارسال شده در payload است پیدا می شود و سپس آن را حذف می کنیم (با استفاده از متد splice)

action ها

در نهایت می‌توانیم توابع Action را ایجاد کنیم، که برای فراخوانی توابع mutation  هستند. گاهی اوقات آن ها می توانند چندین mutation یا Action دیگر را فراخوانی کنند، اما برای این برنامه فقط یک mutation  فراخوانی می شود.

export const actions = {

addTodo: (context, payload) => {

context.commit("ADD_TODO", payload);

},

toggleTodo: (context, payload) => {

context.commit("TOGGLE_TODO", payload);

},

deleteTodo: (context, payload) => {

context.commit("DELETE_TODO", payload);

}

};

تابع mutation  را با استفاده از تابع context.commit  فراخوانی می کنیم. اولین پارامتر commit نام mutation و دومین پارامتر payload است. payload داده ای خواهد بود که به خود توابع action فرستاده داده می شود.

کد کامل فایل todos.js:

export const state = {

todos: []

};




export const getters = {

getTodos: state => state.todos

};




export const mutations = {

ADD_TODO: (state, payload) => {

const newTask = {

id: payload.newId,

task: payload.task,

completed: false

};

state.todos.unshift(newTask);

},

TOGGLE_TODO: (state, payload) => {

const item = state.todos.find(todo => todo.id === payload);

item.completed = !item.completed;

},

DELETE_TODO: (state, payload) => {

const index = state.todos.findIndex(todo => todo.id === payload);

state.todos.splice(index, 1);

}

};




export const actions = {

addTodo: (context, payload) => {

context.commit("ADD_TODO", payload);

},

toggleTodo: (context, payload) => {

context.commit("TOGGLE_TODO", payload);

},

deleteTodo: (context, payload) => {

context.commit("DELETE_TODO", payload);

}

};

پیاده سازی store

کد زیر را در فایل store.js قرار می دهیم:

import Vue from "vue";

import Vuex from "vuex";

import * as todos from "@/store/modules/todos.js";




Vue.use(Vuex);




export default new Vuex.Store({

state: todos.state,

getters: todos.getters,

mutations: todos.mutations,

actions: todos.actions

});

ماژول todos.js وارد فایل می شود و استور Vuex با استفاده از آن تعریف می شود.

ویرایش فایل main.js

کد زیر را در فایل main.js قرار می دهیم:

import Vue from "vue";

import store from "./store/store";

import App from "./App.vue";




Vue.config.productionTip = false;




new Vue({

store,

render: h => h(App)

}).$mount("#app");

ساخت کامپوننت ها

store بزرگترین بخش برنامه است. اکنون به ساخت رابط کاربری می پردازیم. دو کامپوننت (برای فهرست کردن کارها یا todo ها و افزودن یک todo جدید) و کامپوننت اصلی را خواهیم داشت که شامل کل برنامه است.

ابتدا در پوشه components، فایل HelloWorld.vue  را که Vue CLI به طور پیش فرض در آن جا ایجاد کرده است را حذف کنید.

TodoList.vue

به جای آن یک فایل جدید به نام TodoList.vue ایجاد کنید. ابتدا بیایید اسکلت را برنامه بنویسیم:

<template> </template> 
<script></script> 
<style></style>

بین تگ‌های <script> کد زیر را اضافه می‌کنیم:

<script>

export default {

computed: {

todos() {

return this.$store.getters.getTodos;

}

},

methods: {

toggleTodo: function(id) {

this.$store.dispatch("toggleTodo", id);

},

deleteTodo: function(id) {

this.$store.dispatch("deleteTodo", id);

}

}

};

</script>

یک تابع ()todos به عنوان یک ویژگی محاسبه شده ایجاد می شود و تنها کاری که انجام می دهد این است که آیتم های موجود را از store بازگرداند.

همچنین متدهایی برای جابجایی و حذف آیتم ها تعریف می کنیم. آن ها متد dispatch() را برای فرستادن یک action فراخوانی می‌کنند.

در تگ template کد زیر را قرار می دهیم:

<template>

<ul class="tasks">

<li

v-for="todo in todos"

:key="todo.id"

:class="{ completed: todo.completed }"

class="task"

@click="toggleTodo(todo.id)"

>

{{ todo.task }}

<span class="delete" @click="deleteTodo(todo.id)">ⓧ</span>

</li>

</ul>

</template>

لیست توسط دستور v-for با تگ های li ایجاد می شود و در آرایه todos حلقه می زند. متدهای خود را به ترتیب برای تغییر و حذف ایجاد می‌کنیم. همچنین یک کلاس completed نیز برای نشان دادن کامل شدن کار اضافه می کنی.

برای استایل می توانیم کدهای زیر را بین تگ های style قرار دهیم:

<style>

.tasks {

padding: 0;

list-style-type: none;

}

.task {

padding: 10px;

margin-bottom: 0.5rem;

border: 0.5px solid #999;

border-radius: 5px;

color: #34495e;

font-weight: bold;

}

.task:before {

content: "\2002";

}

.task:hover {

cursor: pointer;

}

.completed {

text-decoration: line-through;

color: #41b883;

}

.completed:before {

content: "\2714";

}

.delete {

display: block;

float: right;

color: #d22;

width: 1.25rem;

height: 1.25rem;

text-align: center;

}

</style>

TodoNew.vue

یک فایل جدید در پوشه components ها به نام TodoNew.vue ایجاد کنید. همان کارهایی که برای فایل TodoList.vue انجام دادیم را برای TodoNew.vue انجام می دهیم:

<template> </template>
<script></script> 
<style></style>

بین تگ script کد های زیر را قرار می دهیم:

<script>

export default {

data() {

return {

task: "",

newId: 0

};

},

methods: {

addTodo: function() {

this.$store.dispatch("addTodo", this);

this.newId++;

this.task = "";

}

}

};

</script>

داده های کامپوننت یک شی را با مقادیر پیش فرض یک آیتم To-Do جدید برمی گرداند. همچنین یک متد addTodo وجود دارد که اکشن addTodo را ارسال می کند و سپس newId را افزایش می دهد و description را بازنشانی یا reset می کند که با این کار فیلد متنی را پاک می کند.

بین تگ های template کد زیر را قرار می دهیم:

<template>

<form @submit.prevent="addTodo">

<input

class="todo-input"

type="text"

placeholder="Enter a new task"

v-model="task"

/>

</form>

</template>

این کامپوننت فقط یک فرم با یک تگ input دارد. یک description برای انجام کار در ورودی تایپ می شود و هنگامی که کلید Enter فشار داده می شود، متد addTodo فراخوانی می شود و آیتم To-Do را در Store ایجاد می کند. همچنین از طریق v-model به ویژگی task متصل می‌شود، بنابراین وقتی متن توسط کاربر یا متد اصلی تغییر می‌کند، تغییرات آن در هر دو مکان منعکس می‌شود.

استایل برای فایل TodoNew.vue را بین تگ‌های style قرار می دهیم:

<style>

.todo-input {

font-family: "Open Sans", sans-serif;

width: 100%;

padding: 0.5rem;

font-size: 1rem;

outline: none;

border-radius: 0.25rem;

border-style: none;

border: solid 1px lightgray;

box-sizing: border-box;

}

</style>

App.vue

در پوشه src، فایل App.vue را باز کرده و محتویات آن ویرایش می کنیم. در تگ‌های script دو کامپوننتی را که ساخته‌ایم وارد می کنیم:

<script>

import TodoNew from "@/components/TodoNew.vue";

import TodoList from "@/components/TodoList.vue";

export default {

components: {

TodoNew,

TodoList

}

};

</script>

در تگ template کد زیر را قرار می دهیم:

<template>

<div class="container">

<h1>To-Do List</h1>

<div id="app">

<div>

<TodoNew />

<TodoList />

</div>

</div>

<img src="@/assets/logo.png" class="vue-logo" alt="Vue.js Logo" />

</div>

</template>

در تگ style کد زیر را اضافه می کنیم:

<style>

@import url("https://fonts.googleapis.com/css?family=Open+Sans");

html {

font-family: "Open Sans", sans-serif;

background: linear-gradient(45deg, #5189c1 25%, #41b883);

height: 100%;

color: #333;

}

body {

display: flex;

height: 100%;

margin: 0;

}

.container {

width: 24rem;

margin: auto;

background-color: white;

border-radius: 1rem;

padding: 1rem;

box-shadow: 0 0 1rem rgba(0, 0, 0, 0.5);

}

h1 {

text-align: center;

margin-top: 0;

}

.vue-logo {

display: block;

width: 50px;

margin: 0 auto;

}

</style>

کد کامل برنامه در این نشانی قرار دارد.


منابع: وب سایت های logrocket و romig

نویسنده شوید
دیدگاه‌های شما

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