预期效果
通过 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') 🎨 原创不易,支持请点赞、转载请注明本文作者为子成君