Vuex官方文档
1.简单看图理解
2.状态管理模式,它是集中式存储所有组件的状态的小仓库
- 把各个组件都需要依赖的同一个状态抽取出来,在全局使用单例模式进行管理。
- 在这种模式下,任何组件都可以直接访问到这个状态,或者当状态发生改变时,所有的组件都获得更新。
- 但是刷新会丢失,可以参考 状态持久化 解决方式
3.Vuex安装
npm install vuex --save
配置 vuex,使其工作起来:在src路径下创建store文件夹,然后创建index.js文件
import Vue from 'vue';
import Vuex from 'vuex';
import getters from './getters'
import app from './modules/app'
Vue.use(Vuex);
const store = new Vuex.Store({
modules:{app},
getters
})
export default store;
修改main.js:
import Vue from 'vue';
import App from './App';
import router from './router';
import store from './store'; // 引入我们前面导出的store对象
Vue.config.productionTip = false;
new Vue({
el: '#app',
router,
store, // 把store对象添加到vue实例上
components: { App },
template: '<App/>',
});
4. Module 按功能拆分
以上面 modules:{app}为例
const state = {
name: "xxx",
}
const mutations = {
SET_Name: (state, payload) => {
state.name = payload.name
}
}
const actions = {
setName({ commit }, payload) {
commit('SET_Name', payload)
}
}
export default {
namespaced: true,//命名空间namespaced:true
state,
mutations,
actions
}
namespaced:true 命名空间 因为Module 按功能拆分 会有多个不同模块
export default {
mounted() {
console.log(this.getName);
},
computed: {
getName() {
//不添加namespaced:true 在组件中调用是
return this.$store.state.name;//没有明确的模块区分
//添加namespaced:true 在组件中调用是
return this.$store.state.app.name;//他会对应到app模块下的xxx 指向更明确
},
},
};
使用方式
1.官方建议我们以上操作this.$store.state.XXX最好放在计算属性中
export default {
mounted() {
console.log(this.getName);
},
computed: {
getName() {
return this.$store.state.app.name;
},
},
};
或者...mapState
export default {
mounted() {
console.log(this.name);
console.log(this.aliasName);
},
computed: {
...mapState('app',['name']),//this.name
...mapState('app',{ aliasName: 'name' }), //也可以在解构的时候起别名 this.aliasName
},
};
5.Getter修饰器
在获取某个状态时需要增加或者增加特殊处理
const getters = {
//就会在使用getter调用前面增加 hello
//组件调用 this.$store.getters.name 就会得到 加了hello 的name了
'name': state => `hello${state.app.name}`,
}
export default getters
官方提供了 ...mapGetters
export default {
mounted() {
console.log(this.xxx);
console.log(this.aliasName);
},
computed: {
...mapGetters(['name']),//this.xxx
...mapGetters({ aliasName: 'name' }), //也可以在解构的时候起别名 this.aliasName
//此处getters 因为是公用的 所以不需要区分模块
},
};
6.Mutation:修改值
重要原则:Mutations里面的函数必须是同步操作,不能包含异步操作!
export default {
mounted() {
this.$store.commit('app/SET_Name', { name: '张三' }); // 调用的时候也需要传递一个对象
},
};
或者 ...mapMutations
export default {
mounted() {
this.SETNAME({ name: '张三' });
this.SET_Name({ name: '张三' });
this.SetName({ name: '张三' });
},
methods: {
SETNAME() {
this.$store.dispatch('app/SET_Name')
},
// 注意,mapMutations是解构到methods里面的,而不是计算属性了
...mapMutations('app',['SET_Name']),
...mapMutations('app',{ SetName: 'SET_Name' }),
},
};
7.Action:修改值
Action 类似于 mutation,不同在于:
- Action 提交的是 mutation,而不是直接变更状态。
- Action 可以包含任意异步操作。
export default {
mounted() {
this.$store.dispatch('app/setName',{ name: '张三' }); //调用的时候也需要传递一个对象
},
};
或者 ...mapMutations
export default {
mounted() {
this.SETNAME({ name: '张三' });
this.SET_Name({ name: '张三' });
this.SetName({ name: '张三' });
},
methods: {
SETNAME() {
this.$store.dispatch('app/SET_Name')
},
// 注意,...mapActions是解构到methods里面的,而不是计算属性了
...mapActions('app',['SET_Name']),
...mapActions('app',{ SetName: 'SET_Name' }),
},
};