封装自定义hooks在setup中取出vuex的state

封装自定义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直接取,在模板里面直接使用时,会在页面上看到如下信息


image.png

每一个数据都是一个函数,说明直接取出的数据格式是不对的,在页面上的数据最好是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
}

你可能感兴趣的:(封装自定义hooks在setup中取出vuex的state)