当前位置: 首页 > news >正文

高效的在Vue3中使用Vuex

前言

我们都知道,vuex 的使用在项目中颇为繁琐,因为它有几大概念使得它不能像普通 ref 或者 data 对象一样直接被我们使用,在我们想要更改 vuex 中的数据时,我们需要通过 mutation 来进行提交,获取 vuex 中存储的变量的时候,我们又需要通过 computed 属性来进行声明,试想,如果项目足够庞大,那么我们使用 vuex 的负担就过于重了,这违背了我们使用状态管理的本意。

问题的提出

首先,我们需要明确,我们想要怎么快捷便利地来使用 vuex ,如果你的想法和我如下所示相同,那么恭喜你,或许本文提出的解决方案适合你。

存储

对于 vuex 的存储我们想要实现的类似如下:

this.$m.vuex(name,value);

我们可以在各个组件或者视图内,通过 this 来直接使用 vuex 进行存储。

读取

对于 vuex 中数据的读取我们想要实现的类似如下:

<template>
<div>{{ vuexUser.name }}</div>
</template><script lang="ts">
import { defineComponent } from 'vue'
export default defineComponent({...methods:{// 业务方法xxxxx(){const flag = this.vuexUser.name? true : false;.....}}
})
</script>

我们能够在模板或者业务逻辑中直接通过 this 直接访问。

解决方案

首先,我们需要在 store 目录下的 index.ts 内加入如下代码

import { createStore } from 'vuex'export default createStore({state: {vuexIsLogin: false,        // 当前的登录状态vuexTestVar: "测试变量",vuexUser:{test: 1,name: "WuYunLong"}},mutations: {$changeStore(state: any, payload: any){// 判断是否为多层级调用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;}}}
})

之后我们在 store 目录下创建一个 ts 脚本文件,在我的项目中我命名为 maxer.mixin.ts ,在这里,我们就需要使用 Vue 中的一个特性 Mixin(混入)「不明白的同学可以去官方文档查一查,Vue3 的官方中文版已经推出了」

/*** @作者: WuYunlong* @时间: 2021/06/22* @版本: V1.0* @说明: maxer Vue 全局混入*/import { App } from 'vue'
import { mapState } from "vuex";
import store from '@/store/index.ts'// 将定义的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中// 使用方法为: this.$m.vuex('user.name', 'x')app.config.globalProperties.$m = new Maxer();app.mixin({computed: {// 将vuex的state中的所有变量,解构到全局混入的mixin中...mapState($mStoreKey)}})
}

在这里我们使用全局混入,将 vuex 的 state 混入到计算属性中,我们就可以通过类似 this.vuexName 来进行调用,还有一点建议就是,由于采用全局混入的模式将 vuex 中的数据进行混入,所以我们应该用特定的字符来进行标识 vuex 中的数据,我的建议是在 vuex 中变量前加上特殊前缀 ,或者类似 vuexVar:'xxx' 来进行声明变量。

之后我们就需要在 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)
app.use(store).mount('#app')

之后我们就可以愉快地使用 vuex 了(在注意变量命名的情况下)。

Vuex 数据持久化

这个时候或许你会发现,当页面进行刷新的时候,vuex 的数据会进行初始化(回到最初的状态),这个是由于 vuex 是运行在内存中的,同样的,它的数据也是存储在内存中,当用户进行刷新页面的操作,所以内存数据会重新进行初始化。

那么我们就可以通过 sessionStorage /localStorage/cookie 来进行数据的持久化存储。

页面加载的时候先读取域中的缓存数据,如果有则覆写。当页面将要刷新前,我们将 vuex 的数据存储到域中。

这里建议使用 sessionStorage ,对于需要长时间持久化的数据再使用 localStorage 或者 cookie。

同样我们在 store 目录下新建一个 ts 脚本。

/*** @作者: WuYunlong* @时间: 2021/6/22* @版本: V1.0* @说明: vuex数据持久化,防止F5之后数据消失*/
import {Store} from "vuex";export default<T> (store: Store<T>): void=>{// 不需要持久化的数据存入sessionStorageif (sessionStorage.getItem('store')){store.replaceState(Object.assign({},store.state,JSON.parse(sessionStorage.getItem('store') as string)));// 移除sessionStorage中的数据sessionStorage.removeItem("store");}// 页面刷新的时候进行持久化window.addEventListener('beforeunload',()=>{sessionStorage.setItem("store", JSON.stringify(store.state));})
}

对于需要长时间持久化的数据建议自行定义规则进行封装。

之后我们需要在入口文件中进行声明

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')

版权说明

本文章转载自网络,如果侵犯了您的权利起联系删除。



喜欢的朋友记得点赞、收藏、关注哦!!!

http://www.dtcms.com/a/266781.html

相关文章:

  • Android-自定义View的实战学习总结
  • python训练day49 CBAM
  • 流程分类框架体系设计应该梳理到L5还是L6?
  • DePIN 普惠结构的缺失拼图,为什么是 UBI Network?
  • js中的捕获阶段和冒泡阶段
  • vue2/3安装依赖报错,终极解决方案
  • Kuberrnetes 服务发布
  • 【MySQL】十六,MySQL窗口函数
  • Mint密室 · 猫猫狐狐的“特征选择”囚室逃脱
  • Ubuntu下的Tomcat服务器部署
  • Linux基础 -- NAND Flash UBIFS基础特性及注意点
  • 【沉浸式解决问题】idea开发中mapper类中突然找不到对应实体类
  • 【Agent】构建专家级SQL Agent交互
  • Qt控件核心属性全解析
  • 【Bluedroid】 BLE 隐私保护机制深度剖析(btm_ble_reset_id)
  • [学习记录]Unity-Shader-曲面细分着色器
  • IDEA-常用的开发组件
  • 用户进程的借壳挂靠之术
  • JAVA-springboot 整合Redis
  • 大数据在UI前端的应用创新研究:基于图神经网络的用户关系网络分析
  • [C++] C++多重继承:深入解析复杂继承关系
  • Blob分析及形态学分析
  • AWS 中如何添加一个内部域名
  • Spring AI Alibaba 来啦!!!
  • 本地区块链服务在物联网中的应用实例
  • M30280F8HP#U5B 瑞萨16位工业MCU微控制器,CAN 2.0B+专用PWM,电机控制专家!
  • 使用mindie:2.0.RC2-800I-A2-py311-openeuler24.03-lts制作一个通用的模型推理性能测试的镜像
  • Flynn分类法知识点梳理
  • 微服务架构的演进:迈向云原生
  • 【Spring Boot】Druid 连接池 YAML 配置详解