【Uni-App】Vuex在vue3版本中的使用与持久化

news/2024/7/10 1:48:44 标签: uni-app, vue

Vuex是什么

Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。
简而言之就是用来存数据,可以有效减少使用组件传参出现的问题。
基本元素:store(里面存数据),mutation(里面修改数据),action(里面异步调用mutation来修改数据),getter(获取数据)

以下是一个表示“单向数据流”理念的简单示意:
在这里插入图片描述
但是,当我们的应用遇到多个组件共享状态时,单向数据流的简洁性很容易被破坏:

  • 多个视图依赖于同一状态。
  • 来自不同视图的行为需要变更同一状态。
    因此,我们把组件的共享状态抽取出来,以一个全局单例模式管理。在这种模式下,我们的组件树构成了一个巨大的“视图”,不管在树的哪个位置,任何组件都能获取状态或者触发行为!这就是vuex的产生。
    通过定义和隔离状态管理中的各种概念并通过强制规则维持视图和状态间的独立性,我们的代码将会变得更结构化且易维护。这就是 Vuex 背后的基本思想。
    Vuex 是专门为 Vue.js 设计的状态管理库,以利用 Vue.js 的细粒度数据响应机制来进行高效的状态更新。
    在这里插入图片描述
    如果你想交互式地学习 Vuex,可以看这个 Scrimba 上的 Vuex 课程,它将录屏和代码试验场混合在了一起,你可以随时暂停并尝试。

优势与使用场景

  • Vuex的状态存储是响应式的,可跟踪每一个状态变化,一旦它改变,所有关联组件都会自动更新相对应的数据。
  • 共享数据,解决了非父子组件的消息传递(将数据存放在state中)。
  • 统一状态管理,减少了请求次数,有些情景可以直接从内存中的state获取数据。

Vuex与全局变量区别

vuex全局变量
不能直接改变store里面的变量,由统一的方法修改数据可以任意修改
每个组件可以根据自己vuex的变量名引用不受影响全局变量可能操作命名污染
解决了多组件之间通信的问题跨页面数据共享
适用于多模块、业务关系复杂的中大型项目适用于demo或者小型项目

vuex_27">什么时候需要用vuex?

  • 当一个组件需要多次派发事件时。例如购物车数量加减。
  • 跨组件共享数据、跨页面共享数据。例如订单状态更新。
  • 需要持久化的数据。例如登录后用户的信息。
  • 当您需要开发中大型应用,适合复杂的多模块多页面的数据交互,考虑如何更好地在组件外部管理状态时。

核心概念

每一个 Vuex 应用的核心就是 store(仓库),它包含着你的应用中大部分的状态 state
状态管理有5个核心:state(存数据)getter(获取数据)mutation(修改数据)action(异步调用mutation来修改数据)module(模块)

vue3_35">Vuex 在vue3版本中的使用

uniapp已经集成了vuex,所以我们只需要直接引用即可。

1. 引用

main.js文件中添加如下配置:

import store from '@/store';

// vuex   vue3  写法
// #ifdef VUE3
import {
	createSSRApp
} from 'vue'
export function createApp() {
	const app = createSSRApp(App)
	// 引入Vuex
	app.use(store)
	return {
		app,
		// Vuex // 如果 nvue 使用 vuex 的各种map工具方法时,必须 return Vuex
	}
}
// #endif

2. 初始化

在项目根目录创建store文件夹,里面创建index.js,内容如下:

import {
	createStore
} from "vuex";

export default createStore({
	state: {
		isDev: true, // 开发环境true,上线需要改成false
		token: "", //Authorization
		uid:'527',
	},
	mutations: {
		// 定义mutations,用于修改状态(同步)
		updateUid(state, payload) {
			state.uid = payload
		},
		updateToken(state, payload) {
			state.token = payload
		},
	},
	actions: {
		// 定义actions,用于修改状态(异步)
		// 2秒后更新状态
		updateUid(context, payload) {
			setTimeout(() => {
				context.commit('updateUid', payload)
			}, 2000)
		}
		// updateUid(context, payload) {
		// 	context.commit('updateUid', payload)
		// }
	},
	getters: {
		// 定义一个getters
		formatUid(state) {
			return state.uid + ' Tom'
		}
	},
	modules: {}
});

3. 页面中使用

<script>
	import store from '@/store/index.js'; //需要引入store

	export default {
		data() {
			return {
			}
		},
		methods: {
			useStore() {
 			    console.log('updateUid1111', store.state.uid);
				// 异步修改
                store.dispatch('updateUid', 123456)
                // 同步修改
				store.commit('updateUid', 654321)
				console.log('updateUid1222', store.state.uid);
			}
		}
	}
</script>

注意:上述token重新打开应用时,会调用默认值,需要做持久化处理

Vuex的优化

1. 拓展提升(动态存值,持久化处理

通过上述的index.js文件我们可以看到针对不同的状态,需要写对应的mutations,比较繁琐。可以考虑通过以下代码进行优化:

import {
	createStore
} from "vuex";

let lifeData = {}
try {
	lifeData = uni.getStorageSync('lifeData')
} catch (e) {
}

// 需要永久存储,且下次APP启动需要取出的,在state中的变量名
let saveStateKeys = ['vuex_user', 'vuex_token',...]

// 保存变量到本地存储中
const saveLifeData = function(key, value) {
	// 判断变量名是否在需要存储的数组中
	if (saveStateKeys.indexOf(key) != -1) {
		// 获取本地存储的lifeData对象,将变量添加到对象中
		let tmp = uni.getStorageSync('lifeData');
		// 第一次打开APP,不存在lifeData变量,故放一个{}空对象
		tmp = tmp ? tmp : {};
		tmp[key] = value;
		// 执行这一步后,所有需要存储的变量,都挂载在本地的lifeData对象中
		uni.setStorageSync('lifeData', tmp);
	}
}

export default createStore({
	state: {
		isDev: true, // 开发环境true,上线需要改成false
		token: "", //Authorization
		vuex_token: lifeData.vuex_token ? lifeData.vuex_token : '',
	},
	mutations: {
		// 定义mutations,用于修改状态(同步)
		updateUid(state, payload) {
			state.uid = payload
		},
		updateToken(state, payload) {
			state.token = payload
		},

		$uStore(state, payload) {
			let nameArr = payload.name.split('.');
			let saveKey = '';
			let len = nameArr.length;
			if (nameArr.length >= 2) {
				let obj = state[nameArr[0]];
				for (let i = 1; i < len - 1; i++) {
					obj = obj[nameArr[i]];
				}
				obj[nameArr[len - 1]] = payload.value;
				saveKey = nameArr[0];
			} else {
				state[payload.name] = payload.value;
				saveKey = payload.name;
			}
			saveLifeData(saveKey, state[saveKey])
		}
	},
	actions: {
		// 定义actions,用于修改状态(异步)
		// 2秒后更新状态
		updateUid(context, payload) {
			setTimeout(() => {
				context.commit('updateUid', payload)
			}, 2000)
		}
		// updateUid(context, payload) {
		// 	context.commit('updateUid', payload)
		// }
	},
	getters: {
		// 定义一个getters
		formatUid(state) {
			return state.uid + ' Tom'
		}
	},
	modules: {}
});

2. 页面中使用

<script>
	import store from '@/store/index.js'; //需要引入store

	export default {
		data() {
			return {
			}
		},
		methods: {
			useStore() {
 			    console.log('updateUid1111', store.state.uid);
				// 异步修改
                store.dispatch('updateUid', 123456)
                // 同步修改
				store.commit('updateUid', 654321)
				// 动态存储
                store.commit('$uStore', {
					name: 'vuex_token',// vuex_token 可以为任何你需要存储的状态
					value: res.token
				})
				console.log('updateUid1222', store.state.uid);
				console.log('vuex_token1222', store.state.vuex_token);
			}
		}
	}
</script>

参考资料

状态管理Vuex
Uniapp在vue3下使用vuex
uniapp vue3中vuex的使用


http://www.niftyadmin.cn/n/5348246.html

相关文章

Flink生产环境相关问题

1. FlinkKafka保证精确一次消费相关问题&#xff1f; Fink的检查点和恢复机制和可以重置读位置的source连接器结合使用&#xff0c;比如kafka&#xff0c;可以保证应用程序不会丢失数据。尽管如此&#xff0c;应用程序可能会发出两次计算结果&#xff0c;因为从上一次检查点恢…

简单计算与模拟1:鸡兔同笼(POJ 3237)

1 问题描述 图1 问题描述 2 解题思路 鸡有两只脚&#xff0c;兔子有四只脚&#xff0c;且输入数据可能为奇数&#xff0c;使用公式计算即可。 3 设计代码 #include <cstdio> int main() {int nCases, nFeets;while (scanf("%d", &nCases) ! EOF){for (in…

C#使用RabbitMQ-2_详解工作队列模式

简介 &#x1f340;RabbitMQ中的工作队列模式是指将任务分配给多个消费者并行处理。在工作队列模式中&#xff0c;生产者将任务发送到RabbitMQ交换器&#xff0c;然后交换器将任务路由到一个或多个队列。消费者从队列中获取任务并进行处理。处理完成后&#xff0c;消费者可以向…

RUST笔记:candle使用基础

candle介绍 candle是huggingface开源的Rust的极简 ML 框架。 candle-矩阵乘法示例 cargo new myapp cd myapp cargo add --git https://github.com/huggingface/candle.git candle-core cargo build # 测试&#xff0c;或执行 cargo ckeckmain.rs use candle_core::{Device…

解决Tomcat在idea中的控制台中文乱码问题

问题 如图&#xff1a;在我的idea项目中&#xff0c;Tomcat控制台的中文信息提示是乱码。 问题原因 因为IDEA控制台实际上调用的是Windows系统的控制台&#xff0c;而Windows控制台默认是GBK&#xff0c;但是Tomcat默认是UTF-8&#xff0c;但是修改Windows系统的会给其他应用带…

C++中的高精度运算

在有时一个很长的数字C中的数据类型难以表示的时候&#xff0c;就需要我们以数组的方式来存储内个长数字中每位的数字。 一、高精度加法 因为太长的整数无法按照常规使用一个数据类型来表示&#xff0c;使用两个数组分别存储两个数字&#xff0c;然后进行相加。 加法中需要注…

【虚拟机数据恢复】异常断电导致虚拟机无法启动的数据恢复案例

虚拟机数据恢复环境&#xff1a; 某品牌R710服务器MD3200存储&#xff0c;上层是ESXI虚拟机和虚拟机文件&#xff0c;虚拟机中存放有SQL Server数据库。 虚拟机故障&#xff1a; 机房非正常断电导致虚拟机无法启动。服务器管理员检查后发现虚拟机配置文件丢失&#xff0c;所幸…

【自然语言处理的发展】

自然语言处理的发展 自然语言处理&#xff08;NLP&#xff09;作为人工智能领域的一个分支&#xff0c;旨在让计算机理解和生成人类语言。随着深度学习和大数据技术的不断进步&#xff0c;NLP在近年来取得了显著的突破。本文将探讨NLP技术的发展历程、最新技术进展以及未来展望…