关于如何监控vuex里对象的属性变化

本文探讨如何在Vuex中监控并响应msgList对象的属性变化,特别是当用户发送消息时更新对话记录。通过使用Object.assign()方法来确保对象的更新能够被Vuex检测到,从而实现数据的正确响应。在mutations中,使用Object.assign()创建新对象,然后在组件的computed属性中获取响应式msgList,并在watch中监听其变化以执行相应操作。

我有一个这样的数据结构,在store里有一个msgList的对象,属性是用户的username,要在每次这个用户发出一条消息记录时push一个新元素进去,并响应这个变化,同时更新当前对话记录。
在这里插入图片描述
https://cn.vuejs.org/v2/guide/list.html#
这是官方写的对于数组,对象属性更新检测的注意事项。我自己使用了其中的Object.assign(),来实现响应。

Object.assign() 方法用于将所有可枚举属性的值从一个或多个源对象复制到目标对象。它将返回目标对象。

官方要求我们用这种写法:

vm.userProfile = Object.assign({}, vm.userProfile, {
  age: 27,
  favoriteColor: 'Vue Green'
})

是因为如果使用下列这种写法,只是复制了源目标的值,引用地址并没有变化,本质还是属性的修改,无法检测。而上面写法相当于换了一个对象,自然就能检测到。

Object.assign(vm.userProfile, {
  age: 27,
  favoriteColor: 'Vue Green'
})

预备知识讲完,进入正题。
在mutations里先按照普通写法,将userName作为一个对象的一个属性,并给属性赋值一个被放到数组里的payload对象。

const state={
    msgList:{},//所有消息集合
};
const mutations={
updateMsgList(state,payload){
	console.log(payload)
	if(payload.bySelf===true){//我方发给对方 存储发送消息的To 作为username
		if(!state.msgList[
Vuex修改 `state` 中的对象属性时,需要注意 Vue 的响应式系统限制。如果直接通过属性修改对象属性,例如 `state.obj.key = newValue`,这种方式不会触发响应式更新机制,因此 Vue 无法检测到变化并更新视图或依赖该状态的其他部分。 ### 修改对象属性的方法 1. **使用 `Vue.set` 或 `this.$set`** 为了确保对象属性修改是响应式的,可以使用 `Vue.set` 或其别名 `this.$set`。这种方法会显式地将响应式属性添加到对象上,并触发依赖更新。 ```javascript this.$store.commit('updateObjectProperty', { objKey: 'key', value: newValue }); ``` 在 mutation 中: ```javascript mutations: { updateObjectProperty(state, payload) { Vue.set(state.obj, payload.objKey, payload.value); } } ``` 这种方式适用于需要动态添加或修改对象属性的情况,确保修改是响应式的[^1]。 2. **使用 `Object.assign` 创建新对象** 另一种方法是通过 `Object.assign` 创建一个新对象,并替换原对象。由于 Vuex 的 `state` 是响应式的,替换整个对象可以触发依赖更新。 ```javascript this.$store.commit('updateObjectUsingAssign', { key: 'key', value: newValue }); ``` 在 mutation 中: ```javascript mutations: { updateObjectUsingAssign(state, payload) { state.obj = Object.assign({}, state.obj, { [payload.key]: payload.value }); } } ``` 这种方法通过创建新对象绕过 Vue 的响应式限制,确保组件能够检测到变化并更新[^3]。 3. **使用扩展运算符(Spread Operator)** 如果使用 ES6 的扩展运算符,也可以实现类似效果。通过展开原对象并添加或更新特定属性,生成一个新对象并替换原对象。 ```javascript this.$store.commit('updateObjectUsingSpread', { key: 'key', value: newValue }); ``` 在 mutation 中: ```javascript mutations: { updateObjectUsingSpread(state, payload) { state.obj = { ...state.obj, [payload.key]: payload.value }; } } ``` 这种方法同样利用了响应式系统对对象替换的支持,确保状态变化能够被正确检测到[^1]。 ### 示例代码 以下是一个完整的示例,展示如何通过 `Object.assign` 修改 `state` 中的对象属性: ```javascript // Vuex Store const store = new Vuex.Store({ state: { obj: { key1: 'value1' } }, mutations: { updateObjectProperty(state, payload) { state.obj = Object.assign({}, state.obj, { [payload.key]: payload.value }); } }, actions: { updateObject({ commit }, payload) { commit('updateObjectProperty', payload); } } }); // 在组件中调用 action this.$store.dispatch('updateObject', { key: 'key2', value: 'value2' }); ``` ### 总结 在 Vuex修改对象属性时,需要确保操作是响应式的。直接通过属性修改对象可能不会触发更新,因此推荐使用 `Vue.set`、`Object.assign` 或扩展运算符生成新对象来替代原对象。这些方法能够确保状态变化被正确检测到,并触发依赖更新[^1]。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值