1. 程式人生 > >關於Vuex的詳解

關於Vuex的詳解

首先Vuex是狀態管理工具,Vuex是應用於Vue中,說一下Vuex吧

 

開始Vuex之前,我們先了解一下一張圖

 

  從圖中能看到幾個關鍵的組成部分,Vue Component,Actions,Mutations,State,是的,其實整個Vuex的狀態管理就是呈現這麼一個類似閉環的結構,

但是有一點需要注意的是,我們想要進行一個操作是,是不能省去某個操作的(Action除外)

   現在大致解釋一下這個圖,首先我們需要定義一個全域性狀態State,當我們的元件進行某些操作時需要改變這個全域性狀態,那就通過dispatch觸發我們的Action,然後再由Action通過Commit請求到Mutations才能改變我們定義的State,這裡需要注意的是,State是不能直接改變的,必須通過Mutation的操作才能改變,與此同時,這是一個非同步的操作。那麼同步的時候是怎麼操作的呢?其實很簡單,同步的時候我們就不可以不用dispatch了,就可以直接commit給Mutations進行狀態的修改了。這裡放一個做的購物車小demo

  開始的第一步肯定是引入vuex

yarn add vuex

 

 

 

  然後是定義我們的store

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

Vue.use(Vuex)

import products from './modules/products'
import cart from './modules/cart'

export default new Vuex.Store({
  modules: {
    products,
    cart
  }
})

 

  為了充分的體現我們vue的元件化思想,這裡我將cart和products進行了拆分

  這裡是cart的部分程式碼

 

  

const getters = {
  beautifulItems (state, getters, rootState) {
    return state.items.map((item, index) => {
      let { title, price } = rootState.products.all.find( product => product.id === item.id)
      return
{ title, price, quantity: item.quantity } }) }, totalPrice (state, getters) { return getters.beautifulItems.reduce((total, product) => { return total + product.price * product.quantity }, 0) } } const mutations = { push (state, item) { state.items.push(item) }, update (state, item) { item.quantity++ } } const actions = { addToCart ({ commit, state }, product) { if (product.inventory > 0) { let item = state.items.find( item => item.id === product.id ) if (!!item) { commit('update', item) } else { commit('push', { id: product.id, quantity: 1 }) } commit('products/update', { id: product.id }, { root: true }) } } }

 

這裡是products

 

const actions = {
  async getAllproducts ({ commit }) {
    let products = await shop()
    commit('setProducts', products)
  }
}

const mutations = {
  setProducts (state, products) {
    state.all = products
  },

  update (state, { id }) {
    let product = state.all.find( product => product.id === id)
    product.inventory--
  }
}

 

 

到這一步的時候別忘了在main.js中引入一下Store,不然元件內是獲取不到的

 

 

  接下來就到元件內的引用了,下面是Products元件的程式碼,

<template>
  <ul>
    <li v-for="product of products" :key="product.id">
      {{ product.title }} - {{ product.price }}
      <br />
      <button :disabled="product.inventory === 0" @click="addToCart(product)">放入購物車</button>
    </li>
  </ul>
</template>

<script>
import { mapState, mapMutations, mapActions } from 'vuex'
export default {
  computed: {
    ...mapState('products', {
      products: 'all'
    })
  },

  methods: {
    addToCart (product) {
      this.$store.dispatch('cart/addToCart', product)
    }
  },

  created () {
    this.$store.dispatch('products/getAllproducts')
  }
}
</script>

 

 

 其實在這裡對狀態的獲取方式有很多種,不一定是上面我寫的這種,

還有就是其實圖裡面是沒有getter的

其實getter就是執行中帶快取的,算是對提升效能方面做了些優化工作,言外之意也是鼓勵大家多使用getter。

 

這裡附上我的demo地址:

https://github.com/yangshu17/vuex-demo-cart