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

浙公网安备 33010602011771号