1. 距离上一次使用vuex已经过去两月余,这次项目需要对以前开发的广告系统重构,增删一些新的功能,然后发现以前创建的vuex状态树结构并不是很好,并没有起到太大全局状态树更改的作用,今天捡起来重新用下,使用vuex过程中连基本的几个语法糖 mapState, mapGetters, mapActions 和 mapMutations 都忘得差不多了, 风中凌乱中 …… 还是古人优秀,好记性果然不如烂笔头。
2. vuex状态树简单结构基本创建:
import Vuex from 'vuex'
export default new Vuex.Store({ ...options })
3. 具体 options 解析:(核心)
const store = new Vuex.Store({
state: {
todos: [
{ id: 1, text: '...', done: true },
{ id: 2, text: '...', done: false }
],
user: {},
token: null,
//...
publish: '',
timeList: [],
timelist_cid: -1
},
mutations: {
increment: (state, payload) => {
state.count += payload.amount
},
token: (state, data) => {
localStorage.token = data;
state.token = data;
},
logout: (state) => {
localStorage.removeItem('token');
state.token = null;
},
publish: (state,data) => {
state.publish = data;
}
},
actions: {
// es5
increment: (context) => {
context.commit('increment')
},
// es6
publish({ commit }){
commit('publish')
},
//购物车提交Action示例
checkout ({ commit, state }, products) {
// 把当前购物车的物品备份起来
const savedCartItems = [...state.cart.added]
// 发出结账请求,然后乐观地清空购物车
commit(types.CHECKOUT_REQUEST)
// 购物 API 接受一个成功回调和一个失败回调
shop.buyProducts(
products,
// 成功操作
() => commit(types.CHECKOUT_SUCCESS),
// 失败操作
() => commit(types.CHECKOUT_FAILURE, savedCartItems)
)
}
},
// 可以理解为 store 的计算属性
getters: {
doneTodos: state => {
return state.todos.filter(todo => todo.done)
},
user: state => {
return state.user;
},
token: state => {
return state.token;
},
//...
publish: state => {
return state.publish;
},
timeList: state => {
return state.timeList;
},
timelist_cid: state => {
return state.timelist_cid;
}
}
});
4. 然后把 store 对象引入 main.js 中:
new Vue({
el: '#app',
router,
store, // <- 这里
components: { App },
template: '<App/>'
})
5. 然后就可以在全局使用 this.$store 访问
6. 在组件中使用vuex的方式
(1)将状态中的state值映射到组件中:
//1-1.
this.publish = this.$store.state.publish;
//1-2.
computed: {
localComputed () { },
// 使用对象展开运算符将此对象混入到外部对象中
...mapState({
state_publish: 'publish',
state_cid: 'timelist_cid',
state_tlist: 'timeList'
})
}
//打印
updated(){
console.log(this.state_cid,this.state_tlist); //打印: 3 (6) [{…}, {…}, {…}, {…}, {…}, {…}, __ob__: Observer]
}
//1-3.
computed: {
...mapGetters({
getTimeList: 'timeList',
getCid: 'timelist_cid'
})
}
//打印
updated(){
console.log(this.getCid,this.getTimeList); //打印: 3 (7) [{…}, {…}, {…}, {…}, {…}, {…}, {…}, __ob__: Observer]
}
(2)在组件内部修改提交state中的状态属性值:
//2-1.
this.$store.commit('timelist_cid',$(this).get(0).dataset.id);
//2-2.
//初始化
method:{
...mapMutations({
setTimeList: 'timeList',
setCid: 'timelist_cid'
})
}
//修改状态值
this.setCid($(this).get(0).dataset.id);
7. 项目文件夹目录:
|--src文件夹
|--App.vue
|--main.js
|--store文件夹
|--index.js //必须有index.js,它是我们组装模块并导出 store 的地方
|--actions.js //是我们有动作触发之后,dispatch提交的地方
|--mutations.js //commit提交的地方 *可以合理增加一个 mutation-types.js
|--types.js //存放的是控制数据状态的地方,即控制数据如何变化
|--getters.js //获取数据的目前状态,给mutations使用
8. mapGetters和mapState的区别:
(1)mapGetters获取的是getters.js里面的函数返回值:
export const timeList = function(state){
return Object.assign({a:1,b:2,c:3},state.timeList);
}
(2) mapState获取的是state.js里面的属性值:
const state = {
singer: {},
user: {},
token: null,
title: '',
source: [],
selectid: [],
results: [],
dir: '/',
sdir: '/',
model_type_1: {"file_list":[],"time_list":[]},
model_type_2: {"file_list":[],"time_list":[]},
model_type_3: {"file_list":[],"time_list":[]},
publish: '',
timeList: [],
timelist_cid: -1
}