如何使用this与多动态括号语法修改Vue数据变量
问题解析与解决方案
我一眼就看出你遇到的问题核心——你在动态赋值时错误地替换了临时变量的指向,而非修改原Vue实例对象的属性,这也是为什么静态直接赋值能生效,而动态路径赋值不行的关键差异。
先拆解你的错误逻辑
你在createObject里的这段代码:
let context = this; location = location.split('.'); location.forEach(item => { context = context[item]; }); context = reply.fields;
执行过程是这样的:
- 初始
context = this(指向Vue实例) - 循环拆分后的路径
['reportText', 'Scope_1_T_1']:- 第一次循环:
context = this['reportText'](现在指向this.reportText对象) - 第二次循环:
context = this.reportText['Scope_1_T_1'](现在指向字符串'Text to change',这是个基本类型值)
- 第一次循环:
- 最后
context = reply.fields:这只是把临时变量context的指向改成了reply.fields,完全没有修改this.reportText.Scope_1_T_1本身——因为基本类型是值传递,你操作的是拷贝出来的临时值,和原对象的属性没关系。
静态赋值为什么能生效
不管是this.reportText.Scope_1_T_1 = 'New String'还是this["reportText"]["Scope_1_T_1"] = 'New String',都是直接修改Vue实例上reportText对象的Scope_1_T_1属性,Vue的响应式系统(基于Object.defineProperty)能捕捉到这个属性的变化,进而触发页面更新。
修正后的createObject方法
你需要做的是保留对父对象的引用,只循环到路径的倒数第二个节点,然后给父对象的对应属性赋值:
methods: { createObject(app, location, type, expression) { if (type === 'String') { app.createGenericOjbect( { fields: { qStringExpression: expression } }, reply => { let context = this; const pathParts = location.split('.'); // 循环到倒数第二个节点,拿到目标属性的父对象 for (let i = 0; i < pathParts.length - 1; i++) { context = context[pathParts[i]]; } // 最后一个节点是要赋值的属性名 const targetKey = pathParts[pathParts.length - 1]; // 直接修改父对象的属性,触发响应式更新 context[targetKey] = reply.fields; } ) } } }
这段代码的逻辑和你静态赋值完全一致:动态定位到this.reportText,然后给它的Scope_1_T_1属性赋值,Vue能正常检测到变化,页面上的p标签内容就会更新了。
额外补充:关于Vue响应式的注意点
如果你的路径可能包含新增的属性(而非已有属性),比如reportText原本没有Scope_1_T_2,那你需要用this.$set(context, targetKey, reply.fields)来赋值,这样Vue才能给新增的属性加上响应式监听。不过你的场景里是已有属性,直接赋值就没问题。
内容的提问来源于stack exchange,提问作者CvP
相关产品推荐
相关产品推荐

