先上最终封装的useState.js
import { mapState, createNamespacedHelpers } from 'vuex'
import { useMapper } from './useMapper'
export function useState(moduleName, mapper) {
let mapperFn = mapState
if (typeof moduleName === 'string' && moduleName.length > 0) {
mapperFn = createNamespacedHelpers(moduleName).mapState
} else {
mapper = moduleName
}
return useMapper(mapper, mapperFn)
}
组件获取状态
在前面我们已经学习过如何在组件中获取状态了。
<h2>{{ $store.state.counter }}</h2>
当然,如果觉得那种方式有点繁琐(表达式过长),我们可以使用计算属性:
![](https://img-blog.csdnimg.cn/202108081126110.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzI0NzY3MDkx,size_16,color_FFFFFF,t_70)
但是,如果我们有很多个状态都需要获取话,可以使用mapState的辅助函数:
mapState的方式一:对象类型;
mapState的方式二:数组类型;
也可以使用展开运算符和来原有的computed混合在一起;
vue2中用computed
<template>
<div>
<h2>Home:{{ $store.state.counter }}</h2>
<h2>Home:{{ sCounter }}</h2>
<h2>Home:{{ sName }}</h2>
<!-- <h2>Home:{{ age }}</h2>
<h2>Home:{{ height }}</h2> -->
</div>
</template>
<script>
import { mapState } from 'vuex'
export default {
computed: {
fullName() {
return "Kobe Bryant"
},
// 其他的计算属性, 从state获取
// ...mapState(["counter", "name", "age", "height"])
...mapState({
sCounter: state => state.counter,
sName: state => state.name
})
}
}
</script>
在setup中使用mapState
<template>
<div>
<h2>Home:{{ $store.state.counter }}</h2>
<hr>
<h2>{{sCounter}}</h2>
<h2>{{counter}}</h2>
<h2>{{name}}</h2>
<h2>{{age}}</h2>
<h2>{{height}}</h2>
<hr>
</div>
</template>
<script>
import { mapState, useStore } from 'vuex'
import { computed } from 'vue'
export default {
computed: {
fullName: function() {
return "1fdasfdasfad"
},
...mapState(["name", "age"])
},
setup() {
//方法一
const store = useStore()
const sCounter = computed(() => store.state.counter)
// const sName = computed(() => store.state.name)
// const sAge = computed(() => store.state.age)
//方法二:后续封装
const storeStateFns = mapState(["counter", "name", "age", "height"])
// {name: function, age: function, height: function}
// {name: ref, age: ref, height: ref}
const storeState = {}
Object.keys(storeStateFns).forEach(fnKey => {
const fn = storeStateFns[fnKey].bind({$store: store})
storeState[fnKey] = computed(fn)
})
return {
sCounter,
...storeState
}
}
}
封装useState
hooks下封装的useState.js
import { computed } from 'vue'
import { mapState, useStore } from 'vuex'
export function useState(mapper) {
// 拿到store独享
const store = useStore()
// 获取到对应的对象的functions: {name: function, age: function}
const storeStateFns = mapState(mapper)
// 对数据进行转换
const storeState = {}
Object.keys(storeStateFns).forEach(fnKey => {
const fn = storeStateFns[fnKey].bind({$store: store})
storeState[fnKey] = computed(fn)
})
return storeState
}
在组件中使用
<template>
<div>
<h2>Home:{{ $store.state.counter }}</h2>
<hr>
<h2>{{counter}}</h2>
<h2>{{name}}</h2>
<h2>{{age}}</h2>
<h2>{{height}}</h2>
<h2>{{sCounter}}</h2>
<h2>{{sName}}</h2>
<hr>
</div>
</template>
<script>
import { useState } from '../hooks/useState'
export default {
setup() {
//可以是数组
const storeState = useState(["counter", "name", "age", "height"])
//可以是对象
const storeState2 = useState({
sCounter: state => state.counter,
sName: state => state.name
})
return {
...storeState,
...storeState2
}
}
}
</script>