1.vue2中获取vuex中数据的方式
<template>
<div>
<h2>{{ $store.state.counter }}</h2>
<h2>{{ sCounter }}</h2>
<h2>{{ sName }}</h2>
</div>
</template>
<script>
import { mapState } from 'vuex'
export default {
computed: {
// 方式1: 传入数组对象
// ...mapState(["counter", "name", "age", "height"])
// 方式2: 传入函数对象
...mapState({
sCounter: state => state.counter,
sName: state => state.name
})
}
}
</script>
2.vue3中获取vuex中数据的方式
<template>
<div>
<h2>{{ $store.state.counter }}</h2>
<h2>{{ $store.state.name }}</h2>
<h2>{{ sCounter }}</h2>
<h2>{{ sName }}</h2>
</div>
</template>
<script>
import { useStore } from "vuex";
import { computed } from "vue";
export default {
setup() {
const store = useStore();
const sCounter = computed(() => store.state.counter);
const sName = computed(() => store.state.name);
return {
sCounter,
sName,
};
},中
};
</script>
3.对比vue2中在mapState中传入函数对象
通过 ...mapState({() => {}}) 的方式不难看出此方法返回的是一个个的函数对象,而在vue3中使用vuex的方式是在computed包住一个回调函数,细心地同学可以看出这和vue2中使用mapState时包裹的函数是否有些相似?带着这个疑问,咋们可以试一试能否通过遍历的方式拿到mapState的返回值,再循环这个返回值将其包裹在computed函数中去。
<template>
<div>
<h2>{{ $store.state.counter }}</h2>
<h2>{{ $store.state.name }}</h2>
<h2>{{ counter }}</h2>
<h2>{{ name }}</h2>
</div>
</template>
<script>
import { mapState, useStore } from "vuex";
import { computed } from "vue";
export default {
setup() {
const store = useStore();
const storeStateFns = mapState(["counter", "name"]);
const storeState = {};
Object.keys(storeStateFns).forEach((fnKey) => {
console.log(storeStateFns[fnKey]);
// 在此不使用bind会报错:read properties of undefined (reading '$store')所以在此需要手动为该方法绑定this
const fn = storeStateFns[fnKey].bind({ $store: store });
storeState[fnKey] = computed(fn);
});
return {
...storeState,
};
},
};
</script>
在此时就可以看到一个简单的雏形啦,不用每次获取vuex中的一个数据就又去写一次computed函数。接下来的任务便是将其封装为一个工具函数便可。
4.封装成为一个工具函数
import { computed } from 'vue'
import { mapState, useStore } from 'vuex'
export function useState(mapper) {
// 拿到store
const store = useStore()
// 获取到对应的对象的functions
const storeStateFns = mapState(mapper)
// 对数据进行转换
const storeState = {}
Object.keys(storeStateFns).forEach(fnKey => {
const fn = storeStateFns[fnKey].bind({$store: store})
storeState[fnKey] = computed(fn)
})
return storeState
}
在vue3中的使用方法就变得和使用mapState非常的类似了
setup() {
const storeState = useState(["counter", "name"])
return {
...storeState
}
}
5.总结
到此一个简单的useState hooks就基本实现了,还可以封装一个useGetters hooks,再者可以将这个hooks封装成为兼容modules中获取state的写法。