آموزش vuex در Vuejs از صفر تا صد + پروژه شمارنده

09 آبان 1397
vuex-in-vuejs

Vue.js یکی از فریم ورک های جاوا اسکریپت برای طراحی رابط کاربری است و امروزه محبوبیت زیادی را در بین توسعه دهندگان کسب کرده است. Vuex یکی از پیاده سازی های مدل vue.js است که وضعیت داده های یک برنامه را نمایش می دهد. در این مقاله جزئیات آموزش vuex را همراه با ذکر یک مثال ارائه خواهیم کرد. در این آموزش از vue.js 2.0 استفاده می کنیم.

توجه: دوستان عزیزی که با فریم ورک Vuejs آشنایی ندارند می توانند با تهیه دوره آموزشی ویدیویی ویو جی اس، به صورت مقدماتی تا پیشرفته کلیه مفاهیم این فریم ورک را یاد بگیرند. برای دریافت این دوره آموزشی روی لینک زیر کلیک کنید:

از طریق یک مثال نحوه پیکربندی محیط توسعه vuex2.0 و vue.js را توضیح خواهیم داد. در این پست یک پروژه ساده شمارنده ایجاد می کنیم.

سرفصل های آموزش Vuex

  1. هدف این آموزش
  2. نیازمندی ها
  3. vuex
  4. state
  5. Mutationها
  6. اکشن ها
  7. مواقعی که باید از vuex استفاده کرد
  8. آموزش vuex
  9. پیکربندی برنامه vue.js 2.0
  10. ایجاد فایل های index.html و main.js
  11. ایجاد یک vuex store
  12. ایجاد دو کامپوننت: افزودن و حذف شمارنده
  13. ایجاد mutation  و اکشن ها

هدف این آموزش

یکی از اهداف این مقاله، آموزش نحوه کار vuex با فریمورک vue.js است.

نیازمندی ها

در صورتی که با vue.js آشنایی ندارید، لطفا پکیج آموزش فریمورک vue.js را تهیه و یا از مقالات سایت برای یادگیری مقدماتی این فریمورک استفاده کنید.

Vuex چیست؟

Vuex یک کتابخانه جاوا اسکریپت برای مدیریت وضعیت های برنامه است.

این کتابخانه به عنوان یک منبع مرکزی برای داده های برنامه عمل می کند و می توانید در سراسر برنامه از داده های این منبع استفاده کنید.

ایده اولیه اینکار از کتابخانه های React Redux و Flux گرفته شده است. وقتی که برنامه سمت کلاینتی که مشغول توسعه آن هستیم در حال پیچیده تر شدن است، vuex در اینجا وارد عمل می شود.

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

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

  • State: یک منبع مورد اعتماد است که برنامه تان از آن استفاده می کند.
  • View: ویو یک نمایش از state است.
  • Action: راه های ممکنی که یک state بر اساس ورودی های کاربر تغییر می کند.

در زیر نمایش خیلی ساده از مفهوم جریان داده یک طرفه را مشاهده می کنید.

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

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

ابتدا کامپوننت vue یک اکشن را اجرا میکند، که اینکار توسط کلیک روی یک دکمه و در پاسخ به یک درخواست Http اتفاق می افتد.

به این ترتیب یک اکشن فراخوانی می شود، سپس مطابق با نوع اکشن تغییری اتفاق می افتد و وضعیت (state) را تغییر می دهد و کامپوننت های دیگر از این تغییر مطلع می شوند.

State در آموزش Vuex

اگر شما از آموزش vuex استفاده می کنید، تنها یک مخزن برای کامپوننت های vue.js برنامه تان خواهید داشت. این محل ذخیره سازی یک منبع منحصر به فرد از state های برنامه است.

در این محل stateهای برنامه ذخیره می شوند. استفاده از vuex برای مدیریت stateهای برنامه vue.js کار آسانی است. تنها کاری که باید بکنید این است که stateها را توسط ارسال اکشن به آن تغییر دهید و اینکار را باید بطور غیرمستقیم انجام دهید چون ما می خواهیم stateهای بعدی را پیش بینی کنیم.

Mutation ها در آموزش Vuex

تنها راه برای تغییر state در vuex استفاده از mutation ها است. ما می توانیم بصورت مستقیم یک state را تغییر دهیم، اما در اینجا اینکار را انجام نمی دهیم، چون می خواهیم جزئیات هر مرحله ای که در برنامه اتفاق می افتد را به شما نشان دهیم.

ما باید state بعدی را پیش بینی کنیم.

به منظور اشکال زدائی از برنامه (دیباگ کردن)، state را بطور مستقیم تغییر نمی دهیم، بلکه فقط از طریق mutation ها اقدام به تغییر آنها می کنیم.

اکشن ها در آموزش Vuex

اکشن ها همانند mutation ها هستند، با این تفاوت که:

  1. بجای تغییر یک state، اکشن ها mutation را اجرا می کنند.
  2. اکشن ها در صورت تمایل می توانند شامل عملیات غیرهمزمان باشند.

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

اگر برنامه تعداد زیادی state داشته باشد و شما نتوانید همه آنها را مدیریت کنید، بهتر است از Redux و در این مقاله vuex استفاده کنید. اما با این حال موارد زیر را مطالعه بفرمایید:

  1. اگر برنامه دائماً در حال بزرگتر شدن است، vuex یک روش کارآمد برای مدیریت کردن داده های هر عملیات است و اینکار را با vuex store یا مخزن vuex انجام می دهد.
  2. برنامه های کوچک نیاز به vuex ندارند.
  3. اگر state یی دارید که می خواهید با کامپوننت های دیگر به اشتراک بگذارید، آنگاه به vuex نیاز پیدا خواهید کرد. اشتراک گذاری stateها عملی رایج در هنگام استفاده از این قبیل کتابخانه ها است.

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

آموزش Vuex - انجام یک پروژه کاربردی

قدم 1- پیکربندی برنامه vue.js 2.0

ما از یک برنامه ساده vue.js 2.0 در اینجا استفاده می کنیم.

برای شروع یک فایل با نام package.json در روت پروژه تان ایجاد و کدهای زیر را در آن کپی کنید:

{
  "name": "vuexpro",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "start": "webpack-dev-server --inline --hot"
  },
  "author": "Krunal Lathiya",
  "license": "ISC",
  "devDependencies": {
    "babel-core": "^6.25.0",
    "babel-loader": "^7.1.1",
    "babel-plugin-transform-runtime": "^6.23.0",
    "babel-preset-es2015": "^6.24.1",
    "babel-preset-stage-3": "^6.24.1",
    "babel-runtime": "^6.25.0",
    "cross-env": "^5.0.5",
    "vue": "^2.4.2",
    "vue-loader": "^13.0.2",
    "vue-template-compiler": "^2.4.2",
    "vuex": "^2.3.1",
    "webpack": "^3.4.1",
    "webpack-dev-server": "^2.6.1"
  }
}

حال ترمینال (در ویندوز Command Prompt) را باز کرده و دستور زیر را در آن اجرا کنید:

npm install

دستور فوق تمام وابستگی های پروژه که شامل کتابخانه vuex هم می شود را نصب می کند.

سپس یک فایل با نام webpack.config.js برای پیکربندی سرور webpack ایجاد و کدهای زیر را در آن قرار دهید:

// webpack.config.js

module.exports = {
  // This is the "main" file which should include all other modules
  entry: './src/main.js',
  // Where should the compiled file go?
  output: {
    filename: 'bundle.js'
  },
  resolve: {
  alias: {
    vue: 'vue/dist/vue.js'
  }
},
  module: {
    // Special compilation rules
    loaders: [
      {
        // Ask webpack to check: If this file ends with .js, then apply some transforms
        test: /\.js$/,
        // Transform it with babel
        loader: 'babel-loader',
        // don't transform node_modules folder (which don't need to be compiled)
        exclude: /node_modules/
      },
      {
        // Ask webpack to check: If this file ends with .vue, then apply some transforms
        test: /\.vue$/,
        // don't transform node_modules folder (which don't need to be compiled)
        exclude: /(node_modules|bower_components)/,
        // Transform it with vue
      use: {
        loader: 'vue-loader'
      }
    }
  ]
}
}

قدم 2 ایجاد فایل های index.html و main.js

یک فایل با نام index.html ایجاد و کدهای زیر را در آن قرار دهید:

<!-- index.html -->

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <title>Vuex Tutorial Example From Scratch</title>
    <link rel="stylesheet" href="bulma.css" />
  </head>
  <body style="overflow-y: hidden;">
    <div id="app">
    </div>
    <script src="bundle.js"></script>
  </body>
</html>

در آموزش Vuex و این پروژه برای استایل دهی برنامه از فریمورک Bulma استفاده می کنم.

در انتهای این فایل، bundle.js را به برنامه وارد می کنم. این فایل تمام کدهای جاوا اسکریپت استفاده شده در پروژه از طریق این فایل قابل دسترسی است. همچنین یک div با شناسه app ایجاد کردم.

یک فولدر به نام src در داخل روت پروژه ایجاد و داخل این فولدر یک فایل با نام main.js ایجاد کنید:

// main.js

import Vue from 'vue';

new Vue({
  el: '#app'
});

در اینجا من یک آبجکت vue ایجاد کرده و یک پارامتر که شامل یک عنصر Dom است را ارسال می کنم.

در فولدر src یک کامپوننت به نام App.vue ایجاد می کنیم.

// App.vue

<template>
  <div class="container">
    Welcome to App Component.
  </div>
</template>

<script>
export default {

}
</script>

سپس این کامپوننت را در فایل main.js وارد (include) کنید.

// main.js

import Vue from 'vue';
import App from './App.vue';

new Vue({
  el: '#app',
  render: h => h(App)
});
npm start

متن خطای احتمالی: cannot find module ‘is-utf8’

راه حل خطای فوق

فولدر node_module را با دستور زیر uninstall کنید.

rm -rf node_modules

دستور فوق، فولدر را بطور کامل پاک می کند. ترمینال را باز کرده و دستور زیر را اجرا کنید.

npm install

به این ترتیب خطای فوق برطرف خواهد شد.

دستور زیر را در ترمینال اجرا کنید.

npm start

حال آدرس http://localhost:8000 در مرورگر باز خواهد شد و پیام welcome App Component نمایش داده می شود.

قدم 3 ایجاد یک vuex store

قدم بعدی ساخت یک vuex store (مخزن vuex) است. فولدر src را باز و یک فولدر به نام store ایجاد کنید. در این فولدر یک فایل با نام store.js ایجاد کنید. دقت کنید که اسم فولدر و فایل یکی باشند.

// store.js

import Vue from 'vue'
import Vuex from 'vuex'

Vue.use(Vuex)

export default new Vuex.Store({
    
});

در اینجا من vuex store را import کرده و در کتابخانه vue از آن استفاده می کنم. هنگام ایجاد یک نمونه از vue در فایل main.js باید این Store را به آن پاس می دهیم.

// main.js

import Vue from 'vue';
import App from './App.vue';
import store from './store/store.js'

new Vue({
  el: '#app',
  store,
  render: h => h(App)
});

در بالا ما state برنامه را به فایل main.js ارسال کردیم. حال ما می توانیم به داده های آن توسط متدها و چرخه های vuex مناسب دسترسی داشته باشیم.

در اینجا می خواهیم یک برنامه شمارنده ساده بسازیم. برای اینکار باید در فایل store.js یک State تعریف کنیم.

// store.js

import Vue from 'vue';
import Vuex from 'vuex';
Vue.use(Vuex);

const store = new Vuex.Store({
  state: {
    count: 0
  }
})
export default store;

Vuex store مخزن اصلی برنامه است که به عنوان منبع اعتماد هم شناخته می شود. تمام داده های برنامه توسط این مخزن مدیریت می شوند.

ما در این مخزن یک آبجکت state داریم و این آبجکت یک پروپرتی به نام count  دارد. این متغیر بصورت پیش فرض مقدار صفر را دارد، اما در آینده مقدار آن افزایش یا کاهش خواهد داشت.

ما متغیر سراسری Store را به نمونه برنامه vue ایجاد شده پاس می دهیم و به این ترتیب همه کامپوننت های فرزند می توانند به آن دسترسی داشته باشند.

// main.js

import Vue from 'vue';
import store from './store/store';
import App from './App.vue';

const app = new Vue({
  el: '#app',
  store,
  render: h => h(App)
})

قدم 4 ساخت دو کامپوننت : افزایش و کاهش شمارنده

یکی از وظایف برنامه ای که در حال توسعه آن هستیم، افزایش یا کاهش شمارنده است. در واقع قصد داریم مقدار پروپرتی count را افزایش و یا کاهش دهیم.

برای اینکار در فولدر src -> components دو کامپوننت به نام های AddCounter.vue و RemoveCounter.vue ایجاد می کنیم.

// AddCounter.vue

<template>
  <div class="container">
    <div class="field is-grouped">
      <div class="control">
        <button class="button is-primary">Add</button>
      </div>
  </div>
  </div>
</template>

<script>
  export default {
    
  }
</script>

و

// RemoveCounter.vue

<template>
  <div class="container">
    <div class="field is-grouped">
      <div class="control">
        <button class="button is-primary">Remove</button>
      </div>
  </div>
  </div>
</template>

<script>
import store from '../store/store';

  export default {
   
  }
</script>

همچنین یک کامپوننت به نام Counter.vue برای نمایش مقدار شمارنده ایجاد می کنیم.

// Counter.vue

<template>
  <div class="cotainer">
    <div class="notification">
      <h1 class="title" align="center">
        {{ count }}
      </h1>
    </div>
  </div>
</template>
<script>


export default {
 data: {
   count: 0
 }
}
</script>

سپس یک فایل به نام App.vue در مسیر src -> Components ایجاد و کامپوننت هایی که در بالا ایجاد کردیم را در آن وارد میکنیم تا به این ترتیب کل برنامه ساخته شود.

// App.vue

<template>
  <div class="container">
    <Counter></Counter><br />
    <div class="columns">
      <div class="column is-11">
        <AddCounter></AddCounter>
      </div>
      <div class="column auto">
        <RemoveCounter></RemoveCounter>
      </div>
    </div>
 </div>
</template>
<script>

import Counter from './components/Counter.vue';
import AddCounter from './components/AddCounter.vue';
import RemoveCounter from './components/RemoveCounter.vue';

  export default {
    components : {
      Counter,
      AddCounter,
      RemoveCounter
    }
  }
</script>

قدم 5 ایجاد mutation ها و اکشن ها

در فولدر Store یک فولدر دیگر به نام mutationType ایجاد و یک فایل با نام type.js در آن درست کنید.در این فایل نوع mutation یی که در برنامه قصد داریم استفاده کنیم (افزایش یا کاهش شمارنده) را تعریف می کنیم.

// types.js

export const Increment = 'increment';
export const Decrement = 'decrement';

در کد بالا با فشار دادن دکمه، تابع AddCounter فراخوانی شده و سپس نوع اکشنی که باید انجام شود را ارسال می کنند. در فایل store.js باید یک اکشن اضافه کنیم، و این اکشن جدید تغییرات را ثبت خواهد کرد.

// AddCounter.vue

<template>
  <div class="container">
    <div class="field is-grouped">
      <div class="control">
        <button class="button is-primary" v-on:click="addCounter()">Add</button>
      </div>
  </div>
  </div>
</template>

<script>
import store from '../store/store';
import * as type from '../store/mutationTypes/types';

  export default {
    methods: {
        addCounter(){
          store.dispatch({
            type: type.Increment,
            amount: 20
          })
        }
    }
  }
</script>

ما یک mutation به نام increment ایجاد کردیم. دقت داشته باشید که ما نمی توانیم State را در اینجا تغییر دهیم، و باید تابع mutation را برای تغییر دادن یک state فراخوانی کنیم.

// AddCounter.vue

import Vue from 'vue';
import Vuex from 'vuex';
Vue.use(Vuex);

const store = new Vuex.Store({
  state: {
    count: 0
  },
    actions: {
    increment (context, payload) {
      context.commit('increment', payload)
  }
})
export default store;

ما تابع mutation را به همراه payload فراخوانی می کنیم. Payload داده ای است که برای تغییر دادن شمارنده به آن نیاز داریم. در این برنامه، من می خواهم شمارنده را 20 واحد افزایش دهم.

حال باید فایل Counter.vue را برای بروزرسانی شمارنده، مطابق زیر تغییر دهیم:

 // Counter.vue

<template>
  <div class="cotainer">
    <div class="notification">
      <h1 class="title" align="center">
        {{ count }}
      </h1>
    </div>
  </div>
</template>
<script>

import { mapState } from 'vuex';

export default {
  computed: mapState({
      count: state => state.count
})
</script>

حال ترمینال را باز کرده و دستور npm start را در آن اجرا کنید. به این ترتیب فایل index.html در پورت 8000 اجرا می شود.

ایجاد شمارنده در vue.js

قدم 6 پیاده سازی ویژگی کاهش شمارنده

حال می خواهیم ویژگی کاهش شمارنده را پیاده کنیم. برای اینکار فایل RemoveCounter.vue را باز کرده و کدهای زیر را در آن قرار دهید.

// RemoveCounter.vue

<template>
  <div class="container">
    <div class="field is-grouped">
      <div class="control">
        <button class="button is-primary" v-on:click="removeCounter()">Remove</button>
      </div>
  </div>
  </div>
</template>

<script>
import store from '../store/store';
import * as type from '../store/mutationTypes/types';

  export default {
    methods: {
        removeCounter(){
          store.dispatch({
            type: type.Decrement,
            amount: 20
          })
        }
    }
  }
</script>

حال فایل Store.js را باز کرده و اکشن decrement را به همراه mutation مربوط به آن اضافه کنید:

// store.js

import Vue from 'vue';
import Vuex from 'vuex';
Vue.use(Vuex);

const store = new Vuex.Store({
  state: {
    count: 0
  },
  mutations: {
    increment (state, payload){
      return state.count = state.count + payload.amount;
    },
    decrement (state, payload){
      return state.count = state.count - payload.amount;
    }
  },
    actions: {
    increment (context, payload) {
      context.commit('increment', payload)
    },
    decrement (context, payload) {
      context.commit('decrement', payload)
    }
  }
})
export default store;

در قدم آخر یک شرط می گذاریم تا اگر مقدار شمارنده منفی شد، ما آن را برابر صفر قرار بدهیم.

// Counter.vue

<template>
  <div class="cotainer">
    <div class="notification">
      <h1 class="title" align="center">
        {{ count }}
      </h1>
    </div>
  </div>
</template>
<script>

import { mapState } from 'vuex';

export default {
  computed: mapState({
      count: function(state){
        if(state.count < 0){
          state.count = 0;
          return state.count;
        }
       return state.count;
     }
    })
}
</script>

در انتها برنامه ساخته شده باید مطابق تصویر زیر باشد:

آموزش Vuex در Vuejs با پروژه شمارنده

نتیجه گیری

بسیار عالی! دوستان عزیزم در آموزش Vuex‌ نحوه مدیریت موقعیت ها را با یکدیگر بررسی کردیم. در این آموزش یک پروژه شمارنده را ایجاد و خروجی را در قالب یک فایل index.html‌ نمایش دادیم. امیدوارم این آموزش مورد توجه شما عزیزان واقع شده باشد.

همان طور که می بینید می توانیم توسط یک دکمه مقدار شمارنده با افزایش و توسط دکمه دیگر مقدار آن را کاهش دهیم.

در کد بالا می بینید ما از یک helper به نام mapState() استفاده کردیم، چون کامپوننت مان نیاز به استفاده از چندین state دارد تا بتواند به درستی کار کند که اینکار را توسط mapState انجام دادیم

سورس کامل پروژه را می توانید از گیت هاب دانلود کنید.

نویسنده شوید

دیدگاه‌های شما (3 دیدگاه)

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

محمود
19 دی 1399
یک ترجمه ی ضعیف

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

yac
20 مهر 1398
yani chi code r to file copy konim!ma mikhaym yad bgirim,man k aslan motevaje nashodam chi shod!

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

مهدی
09 اردیبهشت 1398
به شدت بد توضیح دادید نوشتار ها باید از لحاظ فنی و ادبیات ویراستاری بشن خیلی تلگرافی صحبت میکنید طوری که مخاطب اصلا متوجه نمیشه چی گفتید

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