vue3+ts 使用 vuex辅助函数(mapState,mapMutations,mapGetters,mapActions) 对函数进行二次封装

vue2中的使用方式

...mapState(["abc", "name"])
...mapState({
        name: state => state.name,
      })
 ...mapGetters(["allName"])
  ...mapGetters({
        allAge: "main/allAge",
      })
      
 ...mapMutations("app", ["setImageBgSrc"]), 
 ...mapMutations(["setname", "setabc"),
 
 ...mapActions(["getabc", "getList"]),
 ...mapActions({
        getB: "user/getB"
})

vue3 封装vuex辅助函数

本文辅助函数封装是参考 深入Vue3+TypeScript技术栈-coderwhy大神新课 视频学习改的
这里进行封装
vue3 中对于vuex的支持不是很好
使用hooks进行封装
目录结构如下:
在这里插入图片描述
index.ts

import { useGetters } from './useGetters'
import { useMutations } from './useMutations'
import { useState } from './useState'
import { useActions } from './useActions'

export { useGetters, useState, useMutations, useActions }

useMapper.ts

import { computed } from 'vue'
import { Computed, Mapper, MapperWithNamespace, useStore } from 'vuex'

export function useMapper(
  mapper: any,
  mapFn: Mapper<Computed> & MapperWithNamespace<Computed>,
  mapName:
    | 'mapMutations'
    | 'mapGetters'
    | 'mapState'
    | 'mapActions'
    | undefined = undefined
) {
  // 拿到store独享
  const store = useStore()

  // 获取到对应的对象的functions: {name: function, age: function}
  const storeStateFns = mapFn(mapper)

  // 对数据进行转换
  const storeState = {}
  Object.keys(storeStateFns).forEach((fnKey) => {
    const fn = storeStateFns[fnKey].bind({ $store: store })
    if ((mapName && mapName === 'mapMutations') || mapName === 'mapActions') {
      // storeState[fnKey] = fn
      storeState[fnKey] = computed(() => {
        return fn
      }).value
    } else {
      storeState[fnKey] = computed(fn)
    }
  })

  return storeState
}

useActions.ts

import { mapActions, createNamespacedHelpers } from 'vuex'
import { useMapper } from './useMapper'

export function useActions(moduleName: any, mapper = undefined) {
  const mapName = 'mapActions'
  let mapperFn = mapActions
  if (moduleName && moduleName.length > 0) {
    mapperFn = createNamespacedHelpers(moduleName).mapActions
  } else {
    mapper = moduleName
  }

  return useMapper(mapper, mapperFn, mapName)
}


useGetters.ts

import { mapGetters, createNamespacedHelpers } from 'vuex'
import { useMapper } from './useMapper'

export function useGetters(moduleName: any, mapper = undefined) {
  let mapperFn = mapGetters
  if (typeof moduleName === 'string' && moduleName.length > 0) {
    mapperFn = createNamespacedHelpers(moduleName).mapGetters
  } else {
    mapper = moduleName
  }

  return useMapper(mapper, mapperFn)
}

useMutations.ts

import { mapMutations, createNamespacedHelpers } from 'vuex'
import { useMapper } from './useMapper'

export function useMutations(moduleName: any, mapper = undefined) {
  const mapName = 'mapMutations'
  let mapperFn = mapMutations
  if (moduleName && moduleName.length > 0) {
    mapperFn = createNamespacedHelpers(moduleName).mapMutations
  } else {
    mapper = moduleName
  }

  return useMapper(mapper, mapperFn, mapName)
}

useState.ts

import { mapState, createNamespacedHelpers } from 'vuex'
import { useMapper } from './useMapper'

export function useState(moduleName: any, mapper: any = undefined) {
  let mapperFn = mapState
  if (typeof moduleName === 'string' && moduleName.length > 0) {
    mapperFn = createNamespacedHelpers(moduleName).mapState
  } else {
    mapper = moduleName
  }

  return useMapper(mapper, mapperFn)
}

store目录

store目录 长这样 types 就不写了
在这里插入图片描述

index.ts

import { createStore } from 'vuex'
import main from './module/main/main'

const store = createStore({
  state() {
    return {
      rootCounter: 0
    }
  },
  getters: {
    // doubleRootCounter(state) {
    //   return state.rootCounter * 2
    // }
  },
  mutations: {
    increment(state) {
      state.rootCounter++
    }
  },
  modules: {
    main
  }
})

export default store

main.ts

import { Module } from 'vuex'
import { IRootState, optionsType } from '@/store/types'
import { mainStateType } from './types'

const mainModule: Module<mainStateType, IRootState> = {
  namespaced: true,
  state() {
    return {
      drawer: {
        wmsDrawerShow: true
      },
      abc: 123
    }
  },
  mutations: {
    // 设置子属性
    /**
     * @param state
     * @param data  修改的对象 如:{abc:123}
     */
    setMain(state, data) {
      for (const keyD of Object.keys(data)) {
        for (const keyS of Object.keys(state)) {
          if (keyS == keyD) {
            state[keyS] = data[keyD]
          }
        }
      }
    }
  },
  getters: {
    getabc(state) {
      return state.abc
    }
    // pageListData(state) {
    //   return (pageName: string) => {
    //     return (state as any)[`${pageName}List`]
    //   }
    // },
  },
  actions: {
    setWmsDrawerShow({ commit }, payload: any) {
      commit('setMain', payload)
    }
  }
}

export default mainModule

组件调用辅助函数

import {
  useState,
  useMutations,
  useGetters,
  useActions
} from '../../hooks/vuexHooks'

const storeState: any = useState({
      wmsDrawerShow: (state: any) => state.main.drawer.wmsDrawerShow
    })
    const storeGetters: any = useGetters({
      getabc: 'main/getabc'
    })
    console.log('wmsDrawerShow', storeState.wmsDrawerShow.value)
    console.log('getabc', storeGetters.getabc.value)
    const storeMutations: any = useMutations({
      setMain: 'main/setMain'
    })
    const storeMutations2: any = useMutations(['increment'])
    const storeActions: any = useActions({
      setWmsDrawerShow: 'main/setWmsDrawerShow'
    })
    const { setMain } = storeMutations
    const { increment } = storeMutations2

    const { setWmsDrawerShow } = storeActions
    setTimeout(() => {
      increment()
      setMain({
        drawer: {
          wmsDrawerShow: false
        }
      })
      setWmsDrawerShow({
        abc: 456
      })
    }, 3000)

注意:当前封装 ts类型使用了很多any 使得书写代码是没有代码提示 如果按照vuex官网不使用辅助函数方式是有代码提示的 如各位有更好的封装方式 及ts类型的引入 请告知我,相互学习

结果

在这里插入图片描述
vue.js devtools 查看
在这里插入图片描述
在这里插入图片描述

  • 5
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
Vue3中使用Vuex时,可以借助辅助函数进行封装。你可以参考中提到的深入Vue3 TypeScript技术栈-coderwhy大神新课视频学习来改写你的代码。具体的目录结构可以按照以下方式进行组织: 在index.ts文件中,引入以下辅助函数: ``` import { useGetters } from './useGetters' import { useMutations } from './useMutations' import { useState } from './useState' import { useActions } from './useActions' export { useGetters, useState, useMutations, useActions } ``` 在使用Vuex的地方,你可以参考中给出的示例代码进行修改。在Vue2中,我们使用`...mapState`、`...mapGetters`、`...mapMutations`和`...mapActions`进行映射。在Vue3中,可以通过使用自定义的辅助函数来代替。 对于ts方面的变化,你需要做以下两个改变: 1. 在导入`useStore`时,需要修改为`import { useStore } from '../store'`,具体路径根据你的项目结构来确定。 2. 在定义自己的`useStore`组合式函数时,需要修改为`export function useStore () { return baseUseStore(key) }`,其中`key`可以按照你自己的需求进行导出。 此外,你还需要根据你的具体需求来修改`createStore`中的状态、getters、mutations和actions等。 以上是关于在Vue3中使用Vuex的一些变化和调整,请根据你的具体情况进行相应的修改。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* [vue3+ts 使用 vuex辅助函数(mapState,mapMutations,mapGetters,mapActions) 对函数进行二次封装](https://blog.csdn.net/weixin_43245095/article/details/123380948)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT0_1"}}] [.reference_item style="max-width: 50%"] - *3* [vue3+Ts使用vuex模块化和非模块化管理的2种方式(非pinia)](https://blog.csdn.net/weixin_45441173/article/details/128510971)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT0_1"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值