预期效果
通过 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' import router from "@renderer/router"; const userData = [ // 示例数据 与用户登录态和权限相关的数据 {name:'vuex_user',value:{}}, {name:'vuex_token',value:''}, ] export default createStore({ state: { // 示例数据 vuex_user: {}, vuex_token: '', vuex_version: '', }, mutations: { $clearUserData(state: any){ // 示例方法 不需要请删除 清除用户登录态 let data = JSON.parse(localStorage.getItem('store')) userData.forEach(saveKey =>{ state[saveKey.name] = saveKey.value data[saveKey.name] = saveKey.value }) setTimeout(()=>{ console.log('跳转登录') localStorage.setItem("store", JSON.stringify(data)); router.push('/login')// 跳转至你的登录页 },300) }, $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 目录下创建 maxVuex.mixin.ts
,使用Vue中的一个特性 Mixin(混入), 使用的详细方法已在下面写出
/** * @创建: zhaozc * @时间: 2021/5/27 * @说明: Vue 全局混入 */ import {mapState} from "vuex"; import store from "./index" import {App, getCurrentInstance} from 'vue' // 将定义的state变量key全部加载到全局变量中 const $mStoreKey = store.state ? Object.keys(store.state) : []; export class MaxVuex{ vuex = (name: string, value: any): void=>{ store.commit('$changeStore', { name, value }) } } // 大型项目不推荐这种方式 QAQ export default<T> (app: App<T>) => { // 进行全局混入 // 将vuex方法挂载到$m中 /* 使用方法为: 1.如果要修改vuex的state中的"vuex_xxx"变量为"x" => this.$m.vuex('vuex_xxx','x') 2.在composition-api中使用: 写: import { getCurrentInstance } from 'vue' const { proxy }: any = getCurrentInstance() const { $m } = getCurrentInstance().appContext.config.globalProperties $m.vuex('vuex_xxx','x') 读: 页面上无需任务引入直接{{ vuex_xxx }}即可 js中引入useStore读取 import { useStore } from 'vuex' const store = useStore() store.state.vuex_xxx */ app.config.globalProperties.$m = new MaxVuex(); app.mixin({ computed: { // 将vuex的state中的所有变量,解构到全局混入的mixin中 ...mapState($mStoreKey) } }) }
建议是在 vuex 中变量前加上 vuex_
来进行声明变量,让人一目了然。
之后我们就需要在 main.ts 中进行初始化了。
import { createApp } from 'vue' import App from './App.vue' import store from './store' import installMaxVueStore, {MaxVuex} from './store/maxVuex.mixin' ... // 声明全局组件 防止需要this调用时不能识别类型 这一步建议单独创建个ts文件去声明 declare module '@vue/runtime-core' { interface ComponentCustomProperties { $m: MaxVuex; // 声明全局方法 } } ... const app = createApp(App) installMaxVueStore(app) // 全局混入vuex app.use(store).mount('#app')
最后进行Vuex 数据持久化的处理(防止F5之后数据消失)
在 store 目录下创建store.persistence.ts
/** * @创建: zhaozc * @时间: 2021/5/27 * @说明: vuex数据持久化 */ import {Store} from "vuex"; 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) ) ); } }
需要在入口文件main.ts中追加:
... import initStorePersistence from './store/store.persistence' ... initStorePersistence(store) // 初始化持久化vuex .... app.use(store).mount('#app')
🎨 原创不易,支持请点赞、转载请注明本文作者为子成君