封装自定义hooks
一般在组件内拿到vuex中的数据通常的做法
setup() {
const store = useStore()
//通过computed拿到vuex里面的数据
const scounter = computed((state) => store.state.counter)
return {
scounter,
}
这种做法在对少量数据进行处理还是比较方便的,但是数据一多的话需要多个computed进行处理,存在大量冗余
setup() {
const storeState = mapState(['counter', 'name', 'age'])
return {
//对数组进行展开运算
...storeState,
}
},
当我们利用mapState直接取,在模板里面直接使用时,会在页面上看到如下信息
每一个数据都是一个函数,说明直接取出的数据格式是不对的,在页面上的数据最好是ref对象,
现在需要将原来的数据格式{counter:function} 转换为 { counter : ref }
setup() {
const store = useStore()
//通过computed拿到vuex里面的数据
const scounter = computed((state) => store.state.counter)
const storeStateFn = mapState(['counter', 'name', 'age'])
//原始数据格式 {counter :function ,name:function, age:function}
//将counter里面的function取出来,然后利用computed进行包裹,转为ref对象
//counter => function ->computed(function) =>counter
const storeState = {}
//获取mapstate里面的key,将key进行遍历
Object.keys(storeStateFn).forEach((fnkey) => {
//利用遍历的key取到对应的value值(function),并且绑定this(store)
const fn = storeStateFn[fnkey].bind({ $store: store })
//将取到的function用computed进行包裹,computed包裹之后为ref对象 ,原理就是第四行
//保存在storeState数组里面
storeState[fnkey] = computed(fn)
//通过转化之后数据变为 {counter : ref , name : ref , age : ref}
})
return {
scounter,
...storeState,
}
},
将上面的步骤封装为自定义hooks
import { mapState, useStore } from 'vuex'
import { computed } from 'vue'
export function useState(mapper) {
const store = useStore()
const storeStateFn = mapState(mapper)
const storeState = {}
Object.keys(storeStateFn).forEach((fnkey) => {
const fn = storeStateFn[fnkey].bind({ $store: store })
storeState[fnkey] = computed(fn)
})
return storeState
}
使用
import { useState } from '../hooks'
export default {
setup() {
//可以使用数组也可以使用函数
const storeState = useState(['counter', 'name', 'age'])
const storeState2 = useState({
sCounter: (state) => state.counter,
sName: (state) => state.name,
sAge: (state) => state.age,
})
return {
...storeState,
...storeState2,
}
},
}
扩展
当需要取出Getters里面的数据时可以稍稍修改一下
import { useStore } from 'vuex'
import { computed } from 'vue'
//参数变为两个,第二个参数数可以传入mapstate和mapGetters
export function useMapper(mapper, mapFn) {
const store = useStore()
const storeStateFn = mapFn(mapper)
const storeState = {}
Object.keys(storeStateFn).forEach((fnkey) => {
const fn = storeStateFn[fnkey].bind({ $store: store })
storeState[fnkey] = computed(fn)
})
return storeState
}