vueX中的state、mapState、...mapState理解
本文于 393 天之前发表,文中内容可能已经过时。
1、state
state是什么?
定义:state(vuex) ≈ data (vue)
vuex的state和vue的data有很多相似之处,都是用于存储一些数据,或者说状态值。这些值都将被挂载数据和dom的双向绑定事件,也就是当你改变值的时候可以触发dom的更新。
虽然state和data有很多相似之处,但state在使用的时候一般被挂载到子组件的computed计算属性上,这样有利于state的值发生改变的时候及时响应给子组件。如果你用data去接收store.state,当然可以接收到值,但由于这只是一个简单的赋值操作,因此state中的状态改变的时候不能被vue中的data监听到,当然你也可以通过watch $store去解决这个问题,那你可以。真是一个杠精~
综上所述,请用computed去接收state,如下
1 2 3 4 5 6 7
| let state = { count: 1, name: 'Jack', from: 'china' } export default state
|
1 2 3 4 5 6 7 8 9 10
| const mutations = { INCREMENT(state) { state.count += 1 }, DECREMENT(state) { state.count -= 1 } } export default mutations
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
| // xxx.vue <template> <div id="example"> <button @click="decrement">-</button> {{ count }} {{ dataCount }} <button @click="increment">+</button> </div> </template> <script> export default { data () { return { dataCount: this.$store.state.count } }, computed: { count () { return this.$store.state.count } }, methods: { increment () { this.$store.commit('INCREMENT') }, decrement () { this.$store.commit('DECREMENT') } } } </script>
|
初始化的时候都能获取到count的值,当对count进行加减操作的时候就会发现,data接收的值不能及时响应更新,computed接收的就可以。
2、mapState 辅助函数
mapState是什么?
表面意思:mapState是state的辅助函数,这么说可能很难理解
抽象形容:mapState是state的语法糖,这么说可能你还想骂我,因为你根本不了解什么叫做语法糖,事实上我说的语法糖有自己的定义。
什么是语法糖?
我对语法糖的理解就是,用之前觉得,我明明已经对一种操作很熟练了,并且这种操作也不存在什么问题,为什么要用所谓的”更好的操作”,用了一段时间后,真香!
实际作用:当一个组件需要获取多个状态时候,将这些状态都声明为计算属性会有些重复和冗余。为了解决这个问题,我们可以使用 mapState 辅助函数帮助我们生成计算属性,让你少按几次键
在使用mapState之前,要导入这个辅助函数。
1
| import { mapState } from 'vuex'
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42
| <template> <div id="example"> <button @click="decrement">-</button> <button @click="increment">+</button> <p>dataCount:{{ dataCount }}</p> <p>count:{{ count }}</p> <p>姓名:{{ name }}</p> <p>{{ from }}</p> </div> </template> <script> import { mapState } from 'vuex'
export default { data () { return { str: '国籍', dataCount: this.$store.state.count } }, created () { setTimeout(() => { this.str = '国家' }, 1000) }, computed: mapState({ count: 'count', name: (state) => state.name, from (state) { return this.str + ':' + state.from } }), methods: { increment () { this.$store.commit('INCREMENT') }, decrement () { this.$store.commit('DECREMENT') } } } </script>
|
使用合并的方式添加非vuex中的计算属性
1 2 3 4 5 6 7 8
| computed: Object.assign({}, mapState({ count: 'count', name: state => state.name }), { doubleCount() { return this.count * 2 } })
|
3、…mapState
事实上…mapState并不是mapState的扩展,而是…对象展开符的扩展。当然如果你把他用在这里会发现他能使得代码看起来变得,更加符合常规逻辑了,为什么这么说,你等下就会知道了。
1 2
| let arr = [1,2,3] console.log(...arr)
|
然后来看一个例子
1 2 3 4 5 6 7 8 9
| let MapState = mapState({ count: 'count', sex: (state) => state.sex }) let json = { 'a': '我是json自带的', ...MapState } console.log(json)
|
这里的json可以成功将mapState的json对象和json自带的a属性成功融合成一个新的对象。你可以将这个称为对象混合
这样,你就可以自由的使用mapState了.
1 2 3 4 5 6 7
| computed:{ fn1(){ return ...}, fn2(){ return ...}, fn3(){ return ...} ........ }
|
引入mapState辅助函数之后
1 2 3 4 5 6 7 8 9 10 11
| computed:{ fn1(){ return ...}, fn2(){ return ...}, fn3(){ return ...} ...... ...mapState({ count:'count' }) }
|