美文网首页
封装自定义hooks在setup中取出vuex的state

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

作者: 瓯海 | 来源:发表于2021-08-07 09:42 被阅读0次

    封装自定义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

          本文链接:https://www.haomeiwen.com/subject/wnuwvltx.html