Store 及基本使用
Store 就是一个单一状态管理容器;
Store 中可以配置 State、getter、mutation 等属性,而Store 的属性涵盖了对一个数据的初始化、获取及更新操作。
Store 维护了一套响应式的状态存储机制,也就是当 Store 的数据发生变化是,会通知 Vue 组件,进行响应式的更新。
定义一个 Store 的过程基本如下:
引入 Vue 及 Vuex,并启用 Vuex:
import Vue from 'vue';
import Vuex from 'vuex';
Vue.use(Vuex);
一定要确保 Vue.use(Vuex);
在 new Vuex.Store({})
之前调用, 否则你会收到这样一个错误:
[vuex] must call Vue.use(Vuex) before creating a store instance.
定义 Store 的 state:
const state = {
count: 0
}
定义 Store 的 getters:(如果需要)
const getters = {
getCount(state) {
return state.count;
}
}
这样可以不通过 this.$store.state.count
的形式访问,而是可以通过 this.$store.getters.getCount
的形式访问(当然还有更简洁方式),出了访问方式变动之外,可以在函数中进行一系列操作,然后在返回数据。
定义 Store 的 mutations:
const mutations = {
increment(state){
state.count ++ ;
}
}
getters 是获取数据,而 mutations 则是显示的对数据进行更改。 Store 的 state 是不允许通过 this.$store.state.count = 2
的形式去修改的,必须显示的提交修改才能去执行修改。
提交修改的方式是 this.$store.commit(mutationName)
。
将 state、getters 以及 mutations 作为初始化内容传入 new Vuex.Store({})
:
const store = new Vuex.Store({
state,
getters,
mutations
});
export default store;
最后将 store 导出,然后在 new Vue({})
的地方引入,挂载到 store 属性下即可。
import store from './store';
new Vue({
el: '#app',
router,
store,
render: (c) => {return c(App)}
});
state
Vuex 是一个单一的状态树来管理状态,而 Store 则是Vuex 的存储仓库,每个 Store 中真实表示数据或者状态的则是 Store 的 state
属性。
如果熟悉 React 则就无需强调什么是 state
了, 所有的数据初始化定义都应该在 state
中定义,并且获取数据也可以从 state 中取,只是无法直接去更改某个 state 的值。
比如在模板中读取某个 state 的值的方式:
<p>count is: {{this.$store.state.count}}</p>
console.log(this.$store.state.count)
而在如果你没有使用 getters 的话,一般也会推荐将 state 的值初始化给组件computed 的某个属性,能够简化很多 this.$store.state.xxx
的代码。
比如我将state.count
赋值给 computed
中的 count
:
computed: {
count() {
return this.$store.state.count
}
},
这样在模板中我可以直接使用 count
:
<p>count is: {{count}}</p>
mapState
我本人不觉得 mapState 有什么特别大的帮助,只是在开发上可能少写点代码而已
使用 mapState
需要首先从 vuex 中引入
import {mapState} from 'vuex';
即使每次初始化 computed,也需要写大量的 this.$store.state.xx
因此 vuex 暴露一个 mapState
的属性,用来边界开发,尤其是将 state 的值初始化给 computed 的时候:
computed: mapState({
// 箭头函数可使代码更简练
count: state => state.count,
// 传字符串参数 'count' 等同于 `state => state.count`
countAlias: 'count',
// 为了能够使用 `this` 获取局部状态,必须使用常规函数
countPlusLocalState (state) {
return state.count + this.localCount
}
})
}
上面 computed 的定义中,直接是运行了 mapState
方法, 然后参数是一个对象:
count: state => state.count
:定义一个 computed:count,通过一个函数传入 state 参数,并返回 state.countcountAlias: 'count',
直接对 state.count 进行重命名countPlusLocalState (state) { return state.count + this.loca.... }
如果需要获取 本组件的一些状态,则必须使用常规函数的形式,并且将state
传入函数,其中可以通过this.xxx
获取局部状态。
如果想直接用 state 的名称,可以直接给 mapState
传一个数组:
computed: mapState([
// 映射 this.count 为 store.state.count
'count'
])
而如果本地也有 computed 数据,然后也需要 state 初始化一些本地数据,借助 mapState 实现的话,需要进行对象展开符,当然,mapState
该怎么用还是怎么用,与上面一样。
computed: {
localComputed () { /* ... */ },
// 使用对象展开运算符将此对象混入到外部对象中
...mapState({
// ...
})
}
Getters
getters 只是为了更加方便的获取数据,比如一个 count state,如果不同的组件需要不同结果的 count,则一般都是由业务组件去做这个事情,而 store 也可以把这个事情给做掉。
举例:我需要在每个 state.count 的值前面,在加上一个 state.num,组合成一个新的值给多个组件使用。
如果组件完成这个事情,则需要有组件去实现,(包括金钱、时间的格式化,内容过滤等操作),而通过 getter 则可以提供统一的访问形式。
1、getter 的定义及基本使用
getter 的定义也很简单,定义某个属性,方法中形参是 state:
getters: {
doneTodos: state => {
return state.todos.filter(todo => todo.done)
}
}
通过传入的 state 参数,可以访问当前 store 的状态,进行一系列的判断过滤等。
2、多个 getter 配合
getter 也可以结合其他的 getter 一起使用,getter 定义的第二个参数可以是其他 getter:
getters: {
doneTodos: state => {
return state.todos.filter(todo => todo.done)
},
doneTodosCount: (state, getters) => {
return getters.doneTodos.length
}
}
上面的例子中,首先我已经定义完了 doneTodos
这个 getter,但是比如我还需要获取完成的 todo 的数量,如果我还是使用 state 的话,我还需要写一遍遍历判断最后计数。
而我直接使用当前 getters.doneTodos.length 就不需要再去写那些代码了。
3、getter 传参
除此之外,还可以通过方法访问 getters,所谓的方法访问无非就是传递参数,来进行不同的预期处理:
getters: {
getTodoById: (state) => (id) => {
return state.todos.find(todo => todo.id === id)
}
}
比如上面的 getters 支持通过 id 查找 todo,并且返回。
当定义好之后,就能够直接通过下面的方式查找需要的 todo:
this.$store.getters.getTodoById(2) // -> { id: 2, text: '...', done: false }
而这种定义方式,无非就是一个科里化,没有什么新奇的玩意儿。
4、mapGetter
mapGetter 的使用需要首先引入 import { mapGetters } from 'vuex'
mapGetter 如同 mapState
一样,没什么特别新奇的功能,也是一种辅助作用,写代码比较轻松,必须要写那么多的 this.$store.getters.name
而使用的形式也非常类似于 mapState
:
computed: mapGetter({
// 箭头函数可使代码更简练
count: getters=> getters.getCount,
// 传字符串参数 'count' 等同于 `getters=> getters.getCount`
countAlias: 'getCount',
// 为了能够使用 `this` 获取局部状态,必须使用常规函数
countPlusLocalState (getters) {
return getters.getCount+ this.localCount
}
})
}
暂无评论内容