关于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

猜你喜欢

转载自www.cnblogs.com/yspace/p/10104957.html