介绍
Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。它利用 Vue.js 的细粒度数据响应机制来进行高效的状态更新。
结构
│ ├──vuex //状态管理 vuex配置目录
│ │ └── actions.js //actions异步修改状态
│ │ └── state.js //数据源定义
│ │ └── types.js //mutations 类型
│ │ └── mutations.js //修改状态
│ │ └── index.js //我们组装模块并导出 store 的地方
│ │ └── utils.js //工具类配置
配置vuex步奏(以购物车功能模块为例)
一.需求分析
购物车的功能:添加购物车,删除购物车,同等商品数量上的增减。
二.实现步奏
(1).在mpvue项目中创建一个文件夹(vuex),在文件夹内分别创建如上述结构的js类。
(2).在vuex/state.js中,定义初始变量(
Vuex 中使用单一状态树,包含了全部应用层级状态,每个应用将仅仅包含一个 store 实例
在 Vue 组件中获得 Vuex 状态
)
const state={
carts: wx.getStorageSync('carts') ? JSON.parse(wx.getStorageSync('carts')) : []
}
export default state
(3).在vuex/utils.js中,频繁调用的工具类
/**
* 存储localStorage
*/
export const setStore = (name, content) => {
if (!name) return;
if (typeof content !== 'string') {
content = JSON.stringify(content);
}
wx.setStorageSync(name, content);
}
/**
* 获取localStorage
*/
export const getStore = name => {
if (!name) return;
wx.getStorageSync(name);
}
/**
* 删除localStorage
*/
export const removeStore = name => {
if (!name) return;
wx.removeItem(name);
}
(4).在vuex/type.js中,mutation 类型用大写常量表示
export const SET_CARTS = 'SET_CARTS'
export const DEL_CARTS = 'DEL_CARTS' //删除购物车数量
export const ADD_CARTS = 'ADD_CARTS' //加入商品到购物车
export const RECORD_SHOP_ADD = 'RECORD_SHOP_ADD' // 同等商品数量加
export const RECORD_SHOP_MINUS = 'RECORD_SHOP_MINUS' // 同等商品数量减
(5).在vuex/mutations.js中,是存放处理数据的方法的集合(购物车数量的增删改)
import state from './state'
import * as type from './type.js'
import {setStore, getStore} from './utils'
const mutations = {
// 购物车
[type.SET_CARTS](state) {
setStore('carts', state.carts);
},
// 数量加
[type.RECORD_SHOP_ADD] (state, index) {
state.carts[index].nums++
setStore('carts', state.carts)
},
// 数量减
[type.RECORD_SHOP_MINUS] (state, index) {
state.carts[index].nums == 1 ? state.carts[index].nums = 1 : state.carts[index].nums--
if( state.carts[index].nums == 1){
console.log("该宝贝不能减少了哟~")
}
setStore('carts', state.carts)
},
// 购物车删除
[type.DEL_CARTS]: (state, index) => {
//MessageBox.confirm('确定删除该商品么?').then(action => {
state.carts.splice(index, 1)
setStore('carts', state.carts)
// })
},
setCart(state){
setStore('carts', state.carts)
},
//加入购物车
[type.ADD_CARTS] (state, data) {
let oldId = data.id
let shopItem = data.item
let cart = JSON.parse(wx.getStorageSync('carts'))
let shops = cart.filter((item, index) => item.id == shopItem.id)
let shop = shops.find((element) => (element.goods.id == shopItem.goods.id))
//购物车添加
if (shops) {
if (oldId != '') {
let oldItem = shops.find((element) => (element.goods.id == oldId))
if(oldItem){
oldItem = Object.assign(oldItem, shopItem);
let size = cart.filter(item => item.goods.id == shopItem.goods.id).length
if(size>1){
cart.forEach((item, index) => {
if (item.id==shopItem.id && item.goods.id==shopItem.goods.id && item.nums==shopItem.nums) {
cart.splice(index,1);
return false;
}
})
}
}
} else {
if (shop) {
shop.nums+=shopItem.nums
} else {
cart.push(shopItem)
}
}
} else {
cart.push(shopItem)
}
state.carts = cart
setStore('carts', state.carts);
}
}
export default mutations
(6).在vuex/actions.js中,异步操作数据(将mutations里面处里数据的方法变成可异步的处理数据的方法,和mutations的不同在于:Action 提交的是 mutation,而不是直接变更状态)
const actions = {
// 购物车
setCart ({commit}, data) {
commit('SET_CARTS', data)
},
}
export default actions
(7).在vuex/index.js中,入口index引入其他文件方式
import Vue from 'vue';
import Vuex from 'vuex';
import state from './state'
import mutations from './mutation'
Vue.use(Vuex);
export default new Vuex.Store({
state,
mutations
})
(8).在全局main.js中引入vuex, 并绑定到Vue构造函数的原型上,这样在每个vue的组件都可以通过this.$store访问store对象。
import store from './vuex/index'
Vue.prototype.$store=store;
使用方法
一. mapMutations 使用(如下两种方式)
(1).在组件中使用 this.$store.commit('方法名','参数') 提交 mutation
this.$store.commit('ADD_CARTS',{item: goodsDetail, id:_this.selectedGoodsId})
this.$store.commit('DEL_CARTS',index)//删除
(2).使用 mapMutations 辅助函数将组件中的 methods 映射
//引用
import {mapGetters, mapMutations} from 'vuex'
methods: {
//映射
...mapMutations(['ADD_CARTS','DEL_CARTS', 'RECORD_SHOP_ADD', 'RECORD_SHOP_MINUS','SET_CARTS'])
}
//使用
this.ADD_CARTS({item: goodsDetail, id:_this.selectedGoodsId})
this. DEL_CARTS(index)//删除
二.actions.js使用(通过 store.dispatch 方法触发)
this.$store.dispatch('SET_CARTS')
注意:
报错原因: 在mpvue中使用vuex和在vue中使用是不一样,在Vue中只需要在main.js引用一下
import store from './vuex',
new Vue({
el: '#app',
router,
store,
data: {
eventHub: new Vue()
},
components: { App },
template: '<App/>'
})
就可在组件中使用this.$store.commit()方法,在mpvue中不可。
解决方案:
import store from './vuex'
Vue.prototype.$store=store;//添加即可
本篇独发金蝶云
推荐阅读