vuex的mapState()在composition api中使用
问题:
- 最近做项目时在composition api中用vuex的mapState()方法时发现此方法返回的对象键值对中的值是function类型。故页面展示出错误结果。
- 举例代码:
<template>
<p>{{ name }}</p>
<p>{{ age }}</p>
<p>{{ number }}</p>
</template>
<script setup>
import {mapState} from 'vuex'
const storeState =mapState(['name', 'age', 'number'])
const {name,age,number}={...storeState}
console.log(storeState)
</script>
-
页面:
-
正确页面应该为:
-
在vue3之前的option api中使用时因用computed:{ …mapState([‘name’, ‘age’, ‘number’])}处理过则不存在这种问题。现在vuex官方文档中使用mapState()依然叫你使用option api写法。而网上依然少见在composition api中用mapState()批量映射store.state中的数据。
- 最新vuex官方文档:
computed: mapState([ // 映射 this.count 为 store.state.count 'count' ])
我们要达到的效果:
- 网上依然大多人按照官方推荐的以下方法来依次获取我们所需的数据。
const name =computed(()=>store.state.name)
const age =computed(()=>store.state.age)
const number =computed(()=>store.state.number)
- 但我们希望能像之前option api中用mapState来直接批量映射我们所需数据,如下:
computed:{ ...mapState(['name', 'age', 'number'])}
解决办法:
- 可见在composition api中使用mapState()批量映射store.state中的数据时依然应该用computed()来处理一遍,形如:computed( …mapState([‘name’, ‘age’, ‘number’])),但composition api中的computed()方法不像之前option api的computed{}要求是传入一个个键值对,且值要为function。所以应该将mapState([‘name’, ‘age’, ‘number’])中的每个值单独取出来交给computed()方法处理。
- 解决代码:
<script setup>
import { computed } from 'vue'
import { useStore,mapState } from 'vuex'
const store=useStore()
//此为未处理之前的数据
const storeState = mapState(['name', 'age', 'number'])
//此为将上数据处理后放入的对象
const endStoreState = {}
//此为主要处理方法
Object.keys(storeState).forEach(key => {
endStoreState[key] = computed(storeState[key].bind({$store:store})).value
})
console.log(storeState);
console.log(endStoreState);
const { name, age, number } ={...endStoreState}
</script>
-
最终效果:
-
注:以上处理方法中Object.keys()获取原数据对象中的key以之后获取对应的值。加入.bind({¥store:store})是因computed()这个api依然会像之前option api中computed{}一样本质是用this.¥store.state.xxx读取数据。加了就能为其绑定this,不加的话会报错Cannot read properties of undefined (reading ‘state’)说state未定义。而最后加.value是因为不加的话返回对象对应key的值为ComputedRefImpl,我们实际上要用的是ComputedRefImpl中的value的值。虽然不加默认也会取value且不报错。