简单来说, state
表示状态,类似于 vue
中的 data
(其实本质上就是差不多的, vuex
在 vue
的 beforeCreate
钩子中将 state
混入进 data
)。但是,它们又有很大的不同: 在使用者看来, state 是全局的,这得益于 vuex
的设计理念——单一状态树。state 是类似于全局下的 data 。
state
和 data
的另区别在于,你不能直接改变 state
。改变 store
中的状态的唯一途径就是显式地提交 (commit) mutation
。这样使得我们可以方便地跟踪每一个状态的变化,从而让我们能够实现一些工具帮助我们更好地了解我们的应用。
简而言之,我们把 mutations
当做接收 state
作为参数并修改 state
的自定义事件即可,上一段所说的 commit
就是触发 mutaions
这个自定义事件的方法。在各个组件中可以通过提交mutations改变state数据。
接下来我们通过一个简单例子来感受下 state 和mutations:
首先,我们需要修改 store.js
文件,配置 state
。可以看到,我们在生成 Vuex.Store
实例时传入了实例化选项对象,对象包含一个 state 属性, state 对象的属性就是我们定义的全局状态,添加mutations。
// store.js
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
export default new Vuex.Store({ // 添加state
state:{
count:1,
number:0
},
mutations: {//其实是对应vue里面的method
add: state => state.count++,
reduce: state => state.count--,
//上面的两个方法为下面函数的简式写法
plus(state){
state.number--
}
}
})
首先我们在 App.vue 中使用它:
//main.js 项目入口
import Vue from 'vue'
import App from './App'
//导入之间建好的store.js
import store from './store/store'
Vue.config.productionTip = false
new Vue({
el: '#app',
router,
store,//创建的store仓库,并在vue中挂载
components: { App },
template: ' '
})
在模板中,我们使用 $store.state.count
引入该全局状态,没错,使用它就是那么简单,只需要 以 $store.state.key
的形式调用。
// App.vue
我的vuex测试文件
{{ count }}
state的number: {{ number }}
//ACom.vue
A组件的number: {{ number }}
action 类似于 mutation ,也相当于一种自定义事件。只不过, action 操作的是 mutation 而不是 state 。
Action 提交的是 mutation,而不是直接变更状态。
Action 可以包含任意异步操作(mutation里边是不能包含异步操作的,因为无法追踪状态改变)。
store.dispatch负责分发
关于action的描述我觉得这篇文章不错
this.$store.commit('toShowLoginDialog', true);
this.$store.dispatch('toShowLoginDialog',false)
主要区别是:
dispatch:含有异步操作,例如向后台提交数据,写法: this.$store.dispatch(‘mutations方法名’,值)
commit:同步操作,写法:this.$store.commit(‘mutations方法名’,值)
如果你看懂了上面的三个属就能总结出:
其实state对应这我们vue实例的data,当然他们的区别就不细说了,mutations和actions对应了method方法库,区别上面也有描述。那么getter对应的又是什么呢?其实它对应的相当于computed计算属性。
1.getter相当于组件中计算属性,getter 的返回值会根据它的依赖被缓存起来,且只有当它的依赖值发生了改变才会被重新计算。
2.适合当以一个state被多次使用时
3.getters 接受 state作为第一个参数
注意: getter 在通过方法访问时,每次都会去进行调用,而不会缓存结果
mapGetters辅助函数
将 store 中的 getter 映射到局部计算属性
其方法与其他mapXxxx函数用法一样。
import { mapGetters } from 'vuex'
export default {
// ...
computed: {
// 使用扩展运算符将 getter 混入 computed 对象中
...mapGetters([
'doneTodosCount',
'anotherGetter',
// 把'this.doneTodos'映射为'this.$store.getters.doneTodos', 取别名用对象形式
done: 'doneTodos'
// ...
])
}
}