一,前言
上一篇介绍了Vuex的安装和使用,接下来针对Vuex核心概念做简单介绍,以加深对vuex的理解
这一篇介绍Vuex核心概念:State
二,Vuex核心概念State
Vuex-State单一状态树,是一个对象,它包含了全部的应用层级状态,
State作为"唯一数据源"存在,每个应用仅包含一个store实例
State中能够直接地定位任一特定的状态片段
调试过程中能轻易地取得整个当前应用状态的快照
三,在Vue组件中获得Vuex状态
由于Vuex的状态存储是响应式的,
从store实例中读取状态最简单的方法就是在计算属性中返回某个状态
创建Counter 组件:
const Counter = {
template: `<div>{{ count }}</div>`,
computed: {
count () {
return store.state.count
}
}
}
当store.state.count改变时, 会重新求取计算属性并更新DOM
问题:
这种模式导致组件依赖全局状态单例
在模块化的构建系统中,每个需要使用state的组件中都需要进行导入,测试组件时需要模拟状态
解决:
Vuex通过store选项,调用Vue.use(Vuex),将状态从根组件“注入”到每一个子组件中
const app = new Vue({
el: '#app',
// 将store对象提供给 “store” 选项,这会将store实例注入到所有的子组件中
store,
components: { Counter },
template: `
<div class="app">
<counter></counter>
</div>
`
})
在根实例中注册store选项,将store实例注入到所有的子组件中
子组件可通过this.$store对store实例进行访问:
const Counter = {
template: `<div>{{ count }}</div>`,
computed: {
count () {
return this.$store.state.count
}
}
}
四,mapState辅助函数
问题:
当一个组件需要获取多个状态时
computed: {
A () {
return this.$store.state.A
},
B () {
return this.$store.state.C
},
B () {
return this.$store.state.C
}
...
...
},
会发现处理命名不同,其他部分都是相同的,这就造成了代码的重复和冗余
解决:
Vuex提供了mapState辅助函数,自动生成计算属性:
import { mapState } from 'vuex'
export default {
// ...
computed: mapState({
count: state => state.count,
// 传字符串参数 'count' 等同于 `state => state.count`
countAlias: 'count',
// 为了能够使用 `this` 获取局部状态,必须使用常规函数
countPlusLocalState (state) {
return state.count + this.localCount
}
})
}
当计算属性名称与state子节点名称相同时,可向mapState传入字符串数组:
computed: mapState([
// 映射 this.count 为 store.state.count
'count'
])
五,对象展开运算符
mapState函数返回一个对象,为了能与局部计算属性混合使用
通常,需要使用一个工具函数将多个对象合并为一个,将最终对象传给computed属性
使用对象展开运算符,可以简化写法:
computed: {
localComputed () { /* ... */ },
// 使用对象展开运算符将此对象混入到外部对象中
...mapState({
// ...
})
}
mapState通过扩展运算符将store.state.xxx 映射this.xxx,
直接映射到当前Vue的this对象上,可以通过this对这些对象进行访问
六,state的使用
使用Vuex并不意味着要将所有状态都放入Vuex,
尽管那样做会使状态变化更显式和易调试,但也会使代码变得冗长和不直观,
如果有些状态严格属于单个组件,最好还是作为组件的局部状态
放入Vuex还是作为组件的局部状态,应根据需要进行权衡
七,结尾
以上对Vuex核心概念State做了全面介绍,,相信再回过头去看前边的例子,state部分理解的更透彻了
下一遍介绍Vuex核心概念Getter