state和mutations
简单来说, 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: '<App/>'
})
在模板中,我们使用 $store.state.count
引入该全局状态,没错,使用它就是那么简单,只需要 以 $store.state.key
的形式调用。
// App.vue
<template>
<div id="app">
<div>我的vuex测试文件</div>
{{ count }}
<button @click="add">做加法</button>
<button @click="reduce">做减法</button>
<div>
<h3>state的number: {{ number }}</h3>
<a-com></a-com>
</div>
</div>
</template>
<script>
import { mapState,mapMutations } from 'vuex'
import ACom from './components/ACom'
export default {
name: 'App',
methods: {
add() {
this.$store.commit('add')//提交mutations改变state数据
},
reduce() {
this.$store.commit('reduce')//提交mutations改变state数据
},
//mapMutations相当于上面两个方法,返回需要的mutations函数,可注释上面两个函数打开下面这行
//...mapMutations([add,reduce])
},
computed: {
// vuex通过computed计算属性监测数据的变化,进而影响到所有组件中数据的状态
//借助辅助函数mapState实现
...mapState([
'number',
'count'
]),
//下面三行代码相当于上面的mapState
// number(){
// return this.$store.state.number
// }
},
components:{ ACom }
}
</script>
//ACom.vue
<template>
<div id="a">
<h3>A组件的number: {{ number }}</h3>
<button @click="plusNumber">+</button>
</div>
</template>
<script>
import { mapState, mapMutations } from 'vuex'
export default {
name: 'A',
computed: {
...mapState([
'number'
])
},
methods: {
// 返回需要的mutations函数,相当于导入store里mutation的plus方法
...mapMutations([
'plus'
]),
plusNumber () {
// 此处plus是mutations中的方法
// 1. 直接通过store提交mutations
this.$store.commit('plus')
// 2. 使用mapMutations辅助函数
// this.plus()
}
}
}
</script>
Action
action 类似于 mutation ,也相当于一种自定义事件。只不过, action 操作的是 mutation 而不是 state 。
Action 提交的是 mutation,而不是直接变更状态。
Action 可以包含任意异步操作(mutation里边是不能包含异步操作的,因为无法追踪状态改变)。
store.dispatch负责分发
关于action的描述我觉得这篇文章不错
commit 和dispatch的区别
this.$store.commit('toShowLoginDialog', true);
this.$store.dispatch('toShowLoginDialog',false)
主要区别是:
dispatch:含有异步操作,例如向后台提交数据,写法: this.$store.dispatch(‘mutations方法名’,值)
commit:同步操作,写法:this.$store.commit(‘mutations方法名’,值)
getter
如果你看懂了上面的三个属就能总结出:
其实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'
// ...
])
}
}