Vuex 是一个专为 Vue.js 设计的状态管理模式
vuex解决了组件之间同一状态的共享问题。当我们的应用遇到多个组件共享状态时,会需要:
多个组件依赖于同一状态。传参的方法对于多层嵌套的组件将会非常繁琐,并且对于兄弟组件间的状态传递无能为力。这需要你去学习下,vue编码中多个组件之间的通讯的做法。
来自不同组件的行为需要变更同一状态。我们经常会采用父子组件直接引用或者通过事件来变更和同步状态的多份拷贝。以上的这些模式非常脆弱,通常会导致无法维护的代码。来自官网的一句话:Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。
它采用集中式存储管理应用的所有组件的状态。这里的关键在于集中式存储管理。这意味着本来需要共享状态的更新是需要组件之间通讯的,而现在有了vuex,就组件就都和store通讯了。问题就自然解决了。
这就是为什么官网再次会提到Vuex构建大型应用的价值。如果您不打算开发大型单页应用,使用 Vuex
可能是繁琐冗余的。确实是如此——如果您的应用够简单,您最好不要使用 Vuex。
官方文档讲了很多,都是些概念性的东西,云里雾里,但总结下来就以下几点:
- 1.vuex解决了组件之间同一状态的共享问题 (解决了不同组件之间的数据共享)
- 2.组件里面数据的持久化。
- 3.小项目不部建议用vuex
vuex的使用:
1、src目录下面新建一个vuex的文件夹
2、vuex 文件夹里面新建一个store.js
3、安装vuex
cnpm install vuex --save
4、在刚才创建的store.js引入vue 引入vuex 并且use vuex
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
5、state 定义数据
/*1.state在vuex中用于存储数据*/
var state={
count:1
}
6、mutations
在vuex 中,只有mutation 才能改变state. mutation
类似事件,每一个mutation都有一个类型和一个处理函数,因为只有mutation 才能改变state,
所以处理函数自动会获得一个默认参数 state. 所谓的类型其实就是名字,action去commit 一个mutation,
它要指定去commit哪个mutation, 所以mutation至少需要一个名字,commit mutation 之后,
要做什么事情,那就需要给它指定一个处理函数, 类型(名字) + 处理函数就构成了mutation.
var mutations={
/* ncCount--->事件类型 (type)*/
/* { ++state.count; }----> 回调函数 (handler) 默认接受 state 作为第一个参数 */
incCount(){
++state.count;
}
}
提交载荷(Payload)
你可以向 store.commit 传入额外的参数,即 mutation 的 载荷(payload):
mutations: {
increment (state, n) {
state.count += n
}
}
store.commit('increment', 10)
在大多数情况下,载荷应该是一个对象,这样可以包含多个字段并且记录的 mutation 会更易读:
mutations: {
increment (state, payload) {
state.count += payload.amount
}
}
store.commit('increment', {amount: 10})
对象风格的提交方式
提交 mutation 的另一种方式是直接使用包含 type 属性的对象:
store.commit({
type: 'increment',
amount: 10
})
当使用对象风格的提交方式,整个对象都作为载荷传给 mutation 函数,因此 handler 保持不变:
mutations: {
increment (state, payload) {
state.count += payload.amount
}
}
7、优点类似计算属性 , 改变state里面的count数据的时候会触发 getters里面的方法 获取新的值 (基本用不到)
var getters= {
computedCount: (state) => {
return state.count*2
}
}
8、 Action 基本没有用 ,action去commit mutations (异步,方法中还可同时调用其他的mutations)
Action 类似于 mutation,不同在于:
- Action 提交的是 mutation,而不是直接变更状态。
- 提交一个 mutation context.commit
- Action 可以包含任意异步操作。
var actions= {
incMutationsCount(context) { /*因此你可以调用 context.commit 提交一个 mutation*/
context.commit('incCount'); /*执行 mutations 里面的incCount方法 改变state里面的数据*/
}
}
其实actions 还可以简写一下, 因为函数的参数是一个对象,函数中用的是对象中一个方法,我们可以通过对象的解构赋值直接获取到该方法。修改一下 actions
actions: {
increment({commit}){
commit("INCREMENT")
},
decrement({commit}){
commit("DECREMENT")
}
}
所有在actions中定义的方法,他们的第一个参数是约定好的:要么是store的对象context,这样在方法体中可以使用context的所有方法;
var actions= {
incMutationsCount(context) { /*因此你可以调用 context.commit 提交一个 mutation*/
context.commit('incCount'); /*执行 mutations 里面的incCount方法 改变state里面的数据*/
}
}
或者像官方api一样,参数是context的options,用{}的形式列举出需要的options方法或者属性,这样在方法体中只能使用{}中列举出来的属性和方法,而不能使用context的其他方法和属性。而且在使用的使用不能使用context对象来调用这些options:
var actions= {
incMutationsCount({commit,state}) { /* 解构store.context 对象 */
context.commit('incCount'); /*执行 mutations 里面的incCount方法 改变state里面的数据*/
}
}
还有一点需要注意:在actions中的方法只有第一个参数才是约定的参数,从第二个参数以后的参数被称为‘荷载’,通常是一个对象(也有可能是变量)
var actions= {
incMutationsCount({commit,state},context) { /* context 属于普通载荷 */
context.commit('incCount'); /*执行 mutations 里面的incCount方法 改变state里面的数据*/
}
}
9、 Action 与 mutation 比较
action的功能和mutation是类似的,都是去变更store里的state,不过action和mutation有两点不同:
- 1、action主要处理的是异步的操作,mutation必须同步执行,而action就不受这样的限制,也就是说action中我们既可以处理同步,也可以处理异步的操作
- 2、action改变状态,最后是通过提交mutation
10.暴露
const store = new Vuex.Store({
state,
mutations,
getters,
actions
})
export default store;
组件里面使用vuex:
1.引入 store
import store from '../vuex/store.js';
2、注册
export default{
data(){
return {
msg:'我是一个home组件',
value1: null,
}
},
store,
methods:{
incCount(){
this.$store.commit('incCount'); /*触发 state里面的数据*/
}
}
}
3、获取state里面的数据
this.$store.state.数据
4、触发 mutations 改变 state里面的数据
this.$store.commit('incCount');
5、触发 actions里面的方法
this.$store.dispatch('incCount');