在uni-app项目中如何使用同步或者异步的的方式修改State中定义的属性

本文详细介绍如何在Vue项目中使用Vuex进行状态管理,包括store结构、state、mutations、actions的定义与使用,以及通过不同方式修改state中的属性。同时,提供了五种修改state属性的具体示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

项目结构如下:

store/index.js代码如下:

import Vue from 'vue'
import Vuex from 'vuex'

Vue.use(Vuex)

const store = new Vuex.Store({
	state: {
		/**
		 * 是否需要强制登录
		 */
		forcedLogin: false,
		hasLogin: false,
		userName: ""
	},
	mutations: {
		login(state, userName) {
			state.userName = userName || '新用户';
			state.hasLogin = true;
		},
		logout(state) {
			state.userName = "";
			state.hasLogin = false;
		}
	},
	actions: {
		loginAsync4:async ({commit, state}, payload)=>{
		  return new Promise((resolve) => {
		  	setTimeout(() => {
		  		commit('login', payload)
		  		resolve(payload)
		  	}, 1000)
		  });
		},
		async loginAsync3 ({commit, state}, payload) {
			commit('login',await new Promise((resolve) => {
				setTimeout(() => {
					state.userName = payload
					resolve(state.userName)
				}, 1000)
			}));
		},
		loginAsync2({commit}, {callback,payload}) {
			setTimeout(() => {
				commit('login', payload);
				callback();
			}, 1000);
		},
		loginAsync1({commit}, payload) {
			return new Promise((resolve) => {
				setTimeout(() => {
					commit('login', payload)
					resolve()
				}, 1000)
			});
		}
	}
})

export default store

main.js代码如下:

import Vue from 'vue'
import App from './App'

import store from './store'

Vue.config.productionTip = false

Vue.prototype.$store = store

App.mpType = 'app'

const app = new Vue({
	store,
    ...App
})
app.$mount()

 index/index.vue代码如下:

<template>
	<view class="content">
		<view class="text-area">
			<text class="title">{{userName}}</text>
		</view>
	</view>
</template>

<script>
	import {
		mapState,
		mapMutations,
		mapActions
	} from 'vuex'
	export default {
		computed: {
			userName() {
				return this.$store.state.userName
			}
		},
		data() {
			return {
				title: 'Hello'
			}
		},
		onLoad() {
			this.$store.state.userName = 'jason@hotmail.com';
			console.log('同步方式修改userName: ' + this.userName);
			
			this.$store.commit('login', 'rainly@china.com');
			console.log('同步方式修改userName: ' + this.userName);

			this.login('zhengzizhi@126.com');
			console.log('同步方式修改userName: ' + this.userName);
           
			this.$store.dispatch('loginAsync2',{callback:() => {
				console.log('loginAsync2 userName: ' + this.userName);
			}, payload:'sunny@china.com'});
			
			this.test1();
			this.test2();
			
			var that = this;
			that.$store.dispatch('loginAsync1', 'sunny@china.com').then(() => {
				console.log('loginAsync1 userName: ' + that.userName);
			});


			
		},
		methods: {
			...mapMutations(['login']),
			...mapActions(['login']),
			async test1() {
				console.log('async test1 hello world');
				const userInfo = await this.$store.dispatch('loginAsync3', 'shardingsphere@aliyun.com').then((e) => {
					console.log('loginAsync3 userName: ' + this.userName);
					return e;
				});
				console.log('loginAsync3 userInfo: ' + userInfo);
			},
			async test2() {
				console.log('async test2 hello world');
				const userInfo = await this.$store.dispatch('loginAsync4', 'mycat@aliyun.com').then((e) => {
					console.log('loginAsync4 userName: ' + this.userName);
					return e;
				});
				console.log('loginAsync4 userInfo: ' + userInfo);
			},
		}
	}
</script>

<style>
	.content {
		display: flex;
		flex-direction: column;
		align-items: center;
		justify-content: center;
	}

	.text-area {
		display: flex;
		justify-content: center;
	}

	.title {
		font-size: 36rpx;
		color: #8f8f94;
	}
</style>


 

再列举五种不同的方式修改state中定义的属性userName,
我们还是使用上面范例中的代码文件store/index.js和main.js
(store/index.js文件代码与异步action相关的代码可以去掉),

 

方式一的代码如下:

mapActions与异步调用有关,我们可以去掉它,当然也可以保留它,

这5种不同写法你可以取代上面列举范例中相应位置的代码,照样能用在异步调用中。

<template>
	<view class="content">
		<view class="text-area">
			 <!--修改state中的属性userName 第一种方式-->
			<text class="title">{{$store.state.userName = 'demo@example.com'}}</text>
		</view>
	</view>
</template>

<script>
	export default {
		data() {
			return {
				title: 'Hello'
			}
		},
		onLoad() {
			
		},
		methods: {

		}
	}
</script>

<style>
	.content {
		display: flex;
		flex-direction: column;
		align-items: center;
		justify-content: center;
	}

	.text-area {
		display: flex;
		justify-content: center;
	}

	.title {
		font-size: 36rpx;
		color: #8f8f94;
	}
</style>

方式二的代码如下:

<template>
	<view class="content">
		<view class="text-area">
			 <!--修改state中的属性userName 第二种方式-->
			<text class="title">{{userName}}</text> <!--步骤二-->
		</view>
	</view>
</template>

<script>
	export default {
		computed: {
			userName() {
				return this.$store.state.userName //步骤一,computed定义userName(){}格式是以计算属性的方式
			}
		},
		data() {
			return {
				title: 'Hello'
			}
		},
		onLoad() {
			this.$store.state.userName = 'jason@hotmail.com'; //步骤三 测试修改和输出 
			console.log('同步方式修改userName: ' + this.userName);
		},
		methods: {

		}
	}
</script>

<style>
	.content {
		display: flex;
		flex-direction: column;
		align-items: center;
		justify-content: center;
	}

	.text-area {
		display: flex;
		justify-content: center;
	}

	.title {
		font-size: 36rpx;
		color: #8f8f94;
	}
</style>

方式三的代码如下:

<template>
	<view class="content">
		<view class="text-area">
			 <!--修改state中的属性userName 第三种方式-->
			<text class="title">{{userName}}</text> <!--步骤三-->
		</view>
	</view>
</template>

<script>
	import {
		mapState
		// mapMutations,
		// mapActions 
	} from 'vuex' //步骤一
	export default {
		computed:mapState({
			userName:state => state.userName //步骤二,对象方式
		}),
		data() {
			return {
				title: 'Hello'
			}
		},
		onLoad() {
			this.$store.state.userName = 'jason@hotmail.com'; //步骤四 测试修改和输出 
			console.log('同步方式修改userName: ' + this.userName);
		},
		methods: {

		}
	}
</script>

<style>
	.content {
		display: flex;
		flex-direction: column;
		align-items: center;
		justify-content: center;
	}

	.text-area {
		display: flex;
		justify-content: center;
	}

	.title {
		font-size: 36rpx;
		color: #8f8f94;
	}
</style>

方式四的代码如下:

<template>
	<view class="content">
		<view class="text-area">
			 <!--修改state中的属性userName 第四种方式-->
			<text class="title">{{userName}}</text> <!--步骤三-->
		</view>
	</view>
</template>

<script>
	import {
		mapState
		// mapMutations,
		// mapActions 
	} from 'vuex' //步骤一
	export default {
		computed:mapState([
			'userName' //步骤二,数组方式
		]),
		data() {
			return {
				title: 'Hello'
			}
		},
		onLoad() {
			this.$store.state.userName = 'jason@hotmail.com'; //步骤四 测试修改和输出 
			console.log('同步方式修改userName: ' + this.userName);
		},
		methods: {

		}
	}
</script>

<style>
	.content {
		display: flex;
		flex-direction: column;
		align-items: center;
		justify-content: center;
	}

	.text-area {
		display: flex;
		justify-content: center;
	}

	.title {
		font-size: 36rpx;
		color: #8f8f94;
	}
</style>

方式五的代码如下:

<template>
	<view class="content">
		<view class="text-area">
			 <!--修改state中的属性userName 第五种方式-->
			<text class="title">{{userName}}</text> <!--步骤三-->
		</view>
	</view>
</template>

<script>
	import {
		mapState
		// mapMutations,
		// mapActions 
	} from 'vuex' //步骤一
	export default {
		computed:{
			//步骤二,以对象扩展运算符的方式
		...mapState(['userName'])
		},
		data() {
			return {
				title: 'Hello'
			}
		},
		onLoad() {
			this.$store.state.userName = 'jason@hotmail.com'; //步骤四 测试修改和输出 
			console.log('同步方式修改userName: ' + this.userName);
		},
		methods: {

		}
	}
</script>

<style>
	.content {
		display: flex;
		flex-direction: column;
		align-items: center;
		justify-content: center;
	}

	.text-area {
		display: flex;
		justify-content: center;
	}

	.title {
		font-size: 36rpx;
		color: #8f8f94;
	}
</style>

 

<think>我们正在讨论的是在uni-app使用Vuex进行全局状态管理。根据引用内容,Vuex是一个专为Vue.js应用程序开发的状态管理模式,它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。在uni-app中,由于它是基于Vue.js的,所以同样可以使用Vuex。 根据引用[2]和引用[3],我们可以知道在uni-app中配置Vuex的步骤。下面我将详细说明如何在uni-app中集成和使用Vuex。 步骤1:安装Vuex 在项目根目录下,使用npm安装Vuex(如果项目中没有安装): ```bash npm install vuex --save ``` 步骤2:创建Vuex Store 在项目中创建一个store目录,并在该目录下创建一个index.js文件,用于初始化Vuex Store。 对于Vue2项目uni-app默认使用Vue2): ```javascript // store/index.js import Vue from 'vue' import Vuex from 'vuex' Vue.use(Vuex) const store = new Vuex.Store({ state: { count: 0, // 示例状态 userInfo: null // 用户信息 }, mutations: { // 修改状态的方法 setCount(state, count) { state.count = count }, setUserInfo(state, userInfo) { state.userInfo = userInfo } }, actions: { // 可以定义异步操作 updateCountAsync({ commit }, count) { setTimeout(() => { commit('setCount', count) }, 1000) } }, getters: { // 类似于计算属性 doubleCount(state) { return state.count * 2 } } }) export default store ``` 步骤3:在main.js中引入store并挂载到Vue实例 ```javascript // main.js import Vue from 'vue' import App from './App' import store from './store' // 引入store Vue.config.productionTip = false App.mpType = 'app' const app = new Vue({ store, // 挂载store ...App }) app.$mount() ``` 步骤4:在组件中使用Vuex 在任意组件中,你可以通过this.$store来访问store对象。 获取状态(state): - 在模板中直接使用:`{{$store.state.count}}` - 在脚本中:`this.$store.state.count` 修改状态(mutations): - 通过commit调用mutation:`this.$store.commit('setCount', 10)` 执行异步操作(actions): - 通过dispatch调用action:`this.$store.dispatch('updateCountAsync', 10)` 使用getters: - 在模板中:`{{$store.getters.doubleCount}}` - 在脚本中:`this.$store.getters.doubleCount` 步骤5:使用辅助函数(可选) 为了更便捷地使用Vuex,可以使用mapState, mapGetters, mapMutations, mapActions辅助函数。 例如,在组件中: ```javascript import { mapState, mapMutations, mapActions, mapGetters } from 'vuex' export default { computed: { // 使用对象展开运算符将state混入computed对象中 ...mapState(['count', 'userInfo']), // 将getter混入computed ...mapGetters(['doubleCount']) }, methods: { // 将mutations混入methods ...mapMutations(['setCount']), // 将actions混入methods ...mapActions(['updateCountAsync']) } } ``` 这样,在组件中就可以直接使用this.count, this.userInfo, this.doubleCount,以及调用this.setCount(10)或this.updateCountAsync(10)等方法。 注意事项: 1. Vuex的状态存储是响应式的,所以当状态发生变化时,依赖该状态的组件会自动更新。 2.uni-app中,Vuex的使用与在Vue项目中完全一致。 3. 对于大型项目,建议将store分割成模块(modules),每个模块拥有自己的state、mutations、actions、getters。 模块化示例: ```javascript // store/modules/user.js const user = { state: { name: '', token: '' }, mutations: { setUser(state, payload) { state.name = payload.name state.token = payload.token } } } export default user ``` 然后在store/index.js中引入模块: ```javascript import Vue from 'vue' import Vuex from 'vuex' import user from './modules/user' Vue.use(Vuex) const store = new Vuex.Store({ modules: { user } }) export default store ``` 在组件中使用模块中的状态: ```javascript ...mapState({ userName: state => state.user.name }) ``` 这样,通过Vuex我们就实现了在uni-app中的全局状态管理,可以方便地在各个页面和组件之间共享状态,并且能够跟踪状态的变化。 引用说明: [^1]:Vuex的核心概念和优势,以及为什么需要Vuex。 [^2]:在uni-app中配置Vuex(Vue2)的方法。 [^3]:在main.js中引入store并挂载到Vue实例。 相关问题: 1. Vuex中的mutations和actions有什么区别? 2.uni-app中,如何持久化存储Vuex的状态(例如用户登录信息)? 3. 如何组织大型项目中的Vuex模块结构?</think>在 uni-app使用 Vuex 进行全局状态管理是解决跨组件数据共享的最佳方案。以下是详细实现步骤: ### 一、安装与配置 Vuex 1. **安装依赖**(如未自动安装): ```bash npm install vuex --save ``` 2. **创建 store 文件**: ```javascript // store/index.js import Vue from 'vue' import Vuex from 'vuex' Vue.use(Vuex) export default new Vuex.Store({ state: { count: 0, // 示例状态 userInfo: null, // 用户信息 cartItems: [] // 购物车商品 }, mutations: { // 修改状态的同步方法 setCount(state, value) { state.count = value }, setUserInfo(state, info) { state.userInfo = info }, addCartItem(state, item) { state.cartItems.push(item) } }, actions: { // 异步操作示例 async fetchUser({ commit }) { const res = await uni.request({ url: '/api/user' }) commit('setUserInfo', res.data) } }, getters: { // 计算属性 cartTotal: state => state.cartItems.reduce((total, item) => total + item.price, 0) } }) ``` ### 二、挂载到 Vue 实例 ```javascript // main.js import Vue from 'vue' import App from './App' import store from './store' // 引入store App.mpType = 'app' const app = new Vue({ store, // 关键:挂载store ...App }) app.$mount() ``` ### 三、在组件中使用 #### 1. 获取状态 ```vue <template> <view> <text>计数器:{{ count }}</text> <text>购物车总价:{{ cartTotal }}</text> </view> </template> <script> import { mapState, mapGetters } from 'vuex' export default { computed: { // 映射状态 ...mapState(['count', 'userInfo']), // 映射getters ...mapGetters(['cartTotal']) } } </script> ``` #### 2. 修改状态 ```javascript methods: { // 提交mutation increment() { this.$store.commit('setCount', this.count + 1) }, // 分发action login() { this.$store.dispatch('fetchUser') }, // 使用辅助函数 ...mapMutations(['addCartItem']), addToCart() { this.addCartItem({ id: 1, name: '商品', price: 99 }) } } ``` ### 四、模块化组织(大型项目) ```javascript // store/modules/user.js export default { namespaced: true, state: () => ({ token: '', profile: {} }), mutations: { setToken(state, token) { state.token = token } } } // store/index.js import user from './modules/user' export default new Vuex.Store({ modules: { user } }) // 组件中使用 ...mapState('user', ['token']), this.$store.commit('user/setToken', 'abc123') ``` ### 五、Vuex 核心概念解析 | 概念 | 作用 | 示例 | |------------|----------------------------------------------------------------------|----------------------------------------------------------------------| | **State** | 存储应用状态数据 | `state: { count: 0 }` | | **Mutation** | 同步修改状态(唯一修改途径) | `mutations: { increment(state) { state.count++ } }` | | **Action** | 处理异步操作,提交 mutation | `actions: { asyncFetch({ commit }) { /* 异步操作 */ } }` | | **Getter** | 计算派生状态(类似 computed) | `getters: { doubleCount: state => state.count * 2 }` | | **Module** | 拆分复杂状态树为多个模块 | `modules: { cart, user }` | ### 六、何时使用 Vuex 1. 跨页面共享数据(如用户登录状态) 2. 复杂组件通信(非父子组件) 3. 需要持久化的数据(配合本地存储) 4. 中大型应用状态管理 5. 需要跟踪状态变更历史的场景 > 提示:小型项目使用 `uni.$emit` 和 `uni.$on` 进行简单事件通信,但复杂状态管理仍推荐 Vuex[^1] ### 七、调试工具 启用 Vue Devtools 调试: ```javascript // main.js Vue.config.devtools = true ``` --- ### 常见问题解决 **Q1:页面刷新后状态丢失?** A:使用 `uni.setStorageSync` 持久化关键状态,在 store 初始化时读取 **Q2:如何监听 Vuex 状态变化?** A:使用 `store.subscribe` 监听 mutations: ```javascript store.subscribe((mutation, state) => { if (mutation.type === 'setUser') { console.log('用户信息变更', state.userInfo) } }) ``` **Q3:Vuex 与全局变量区别?** | 特性 | Vuex | 全局变量 | |--------------|-----------------------|-------------------| | **响应式** | ✅ 自动更新视图 | ❌ 需手动更新 | | **调试** | ✅ 完整时间旅行 | ❌ 无 | | **规范** | ✅ 强制单向数据流 | ❌ 任意修改 | | **模块化** | ✅ 命名空间支持 | ❌ 易命名冲突 | ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值