Vue3(Vuex 4.x)中useState的封装
在使用vuex的时候,我们经常会想把store中state中的数据结构到组件中方便直接使用,而不是通过store访问,所以我们会想去通过一些手段去使得mapState也像在vuex 3.x中一样使用
废话少说直接上代码
封装useState (/src/hooks/useState.js)
import { computed } from 'vue'
import { mapState, useStore } from 'vuex'
/**
* @param {Array || Object} mapper
* @returns {Array} storeState
*/
export function useState(mapper) {
// vue3的setup中没有绑定this(无法通过this.$store获取到),通过useStore获取store对象
const store = useStore()
// mapState返回的是一系列的function:{name:nameFn,age:ageFn}的对象
const storeStateFns = mapState(mapper)
// 对数据进行转换
// 存放最终可以在模板上使用的数据 {{ name }}
const storeState = []
// 在组件中使用vuex store中的数据,应该将mapState返回的数据存放到computed中
Object.keys(storeStateFns).forEach(fnKey => {
// mapState中获取到的每一个函数内部其实都是通过this.$store.state.name····进行访问的,但是在setup中并没有this.$store,所以通过bind将store对象绑定到每一个mapState中的函数中
const fn = storeStateFns[fnKey].bind({ $store: store })
// 将获取到的所有state存放到storeState中
storeState[fnKey] = computed(fn)
})
return storeState
}
有一定的封装复之后,在组件中就可以直接使用useState来代替mapState了
<template>
<div>
<h4>封装setup中使用mapState</h4>
{{name}}-{{age}}-{{height}}
<hr>
{{sName}}-{{sAge}}
</div>
</template>
<script>
import {useState} from '../hooks/useState'
export default {
setup() {
const storeState = useState(['name','age','height'])
const storeState2 = useState({
sName:state=> state.name,
sAge:state=>state.age
})
return {
...storeState,...storeState2
}
}
}
</script>
<style lang="scss" scoped>
</style>