Vue3中全局混入Vuex TypeScript版(Vuex 数据持久化)

imsle 35 0

预期效果

通过 this.$m.vuex(name,value)的方式set,通过 this.vuex_name的方式get

前言

js版本的请看这里: uView简化Vuex写法的基本原理

ts代码出自这篇博客文章:https://www.imsle.com/archives/105.html  (文中有改动)

不推荐大型项目使用该方式,大型项目中全局混入有严重性能问题(如果页面组件超过1000个可能导致页面加载过慢,因为该页面1000个组件都混入了store)

正文

在 store 目录下的 index.ts 内加入如下代码

import { createStore } from 'vuex'

export default createStore({
  state: {
    vuex_name: "这是vuex全局混入的测试变量",
  },
  mutations: {
        $changeStore(state: any,payload: any){
            // 判断是否为多层级调用,state中为对象存在的情况,诸如user.info.name = 'xxx'
            const nameArr = payload.name.split('.');
            const len = nameArr.length;
            if (len >= 2){

                let obj = state[nameArr[0]];
                for (let i = 1 ; i < len - 1 ; i++){
                    obj = obj[nameArr[i]];
                }
                obj[nameArr[len-1]] = payload.value;
            }else {
                state[payload.name] = payload.value;
            }
            localStorage.setItem("store", JSON.stringify(state));
        }
  }
})

之后在 store 目录下创建 maxer.mixin.ts ,使用Vue中的一个特性 Mixin(混入)

import {mapState} from "vuex";
import store from '@/store/index.ts'
import {App} from 'vue'

// 将定义的state变量key全部加载到全局变量中
const $mStoreKey = store.state ? Object.keys(store.state) : [];
export class Maxer{
    vuex = (name: string, value: any): void=>{
        store.commit('$changeStore', {
            name, value
        })
    }
}

export default<T> (app: App<T>) => {
    // 进行全局混入
    // 将vuex方法挂载到$m中
    // 使用方法为:如果要修改vuex的state中的user.name变量为"x" => this.$m.vuex('user.name','x')
    app.config.globalProperties.$m = new Maxer();
    app.mixin({
        computed: {
            // 将vuex的state中的所有变量,解构到全局混入的mixin中
            ...mapState($mStoreKey)
        }
    })
}

建议是在 vuex 中变量前加上 vuex_ 来进行声明变量,让人一目了然。3

之后我们就需要在 main.ts 中进行初始化了。

import { createApp } from 'vue'
import App from './App.vue'
import store from './store'
import installMaxerStore, {Maxer} from './store/maxer.mixin'
...

// 声明全局组件 防止需要this调用时不能识别类型
declare module '@vue/runtime-core' {
    interface ComponentCustomProperties {
        $m: Maxer;  // 声明全局方法
    }
}
...
const app = createApp(App)
installMaxerStore(app) // 全局混入vuex
app.use(store).mount('#app')

最后进行Vuex 数据持久化的处理(防止F5之后数据消失)

在 store 目录下创建store.persistence.ts

export default<T> (store: Store<T>): void=>{
    // 数据存入localStorage
    if (localStorage.getItem('store')){
        store.replaceState(
            // 将刷新前存下的缓存数据同步到store
            Object.assign(
                {},
                store.state,
                JSON.parse(localStorage.getItem('store') as string)
            )
        );
    }
}

需要在入口文件中进行声明

import { createApp } from 'vue'
import App from './App.vue'
import store from './store'
import installMaxerStore, {Maxer} from './store/maxer.mixin'
import initStorePersistence from './store/store.persistence'
...

// 声明全局组件
declare module '@vue/runtime-core' {
    interface ComponentCustomProperties {
        $m: Maxer;  // 声明全局方法
    }
}
...
const app = createApp(App)
installMaxerStore(app) // 全局混入vuex
initStorePersistence(store) // 初始化持久化vuex
app.use(store).mount('#app')

发表评论 取消回复
OwO 图片 链接 代码

分享