我有一个可以通过编程方式更改的计算属性(我使用get
和set
方法)。
期望:
如果默认参数更改(this.message
),则必须更改计算属性(computedMessage
)(默认行为)。
如果辅助参数发生更改(this.messageProxy
),则只有计算属性必须反映辅助参数。
小提琴A按预期工作,但小提琴B没有。
错误:辅助参数更改后,默认行为(第1点)停止。
fiddles之间的唯一区别是计算属性中的console
语句。
背景:我试图以编程方式设置computed
属性。 computed
属性设置如下:
computedMessage: {
get () {
let messageProxy = this.messageProxy
this.messageProxy = null
console.log(messageProxy, this.messageProxy, this.message)
return messageProxy || this.message
},
set (val) {
this.messageProxy = val
}
}
这允许我设置computedMessage
的值,如:
this.computedMessage = 'some string'
如果这些行:
get () {
let messageProxy = this.messageProxy
this.messageProxy = null
return messageProxy || this.message
}
将替换为:
get () {
return this.messageProxy || this.message
}
然后computedMessage
在设置this.message
时无法再访问this.messageProxy
。
通过将this.messageProxy
设置为null
,我确保
computedMessage = this.messageProxy
仅在进行作业时才会进行。
答案 0 :(得分:2)
返回语句中对this.message
的引用不会触发computedMessage
更新。这是因为它在逻辑||
语句中的位置使其无法访问。它是Vue.js Computed Properties Documentation中记录的问题。
来自文档:
status: function () {
return this.validated
? this.okMsg
: this.errMsg // errMsg isn't accessible; won't trigger updates to status
}
解决方法是显式访问依赖项:
status: function () {
// access dependencies explicitly
this.okMsg
this.errMsg
return this.validated
? this.okMsg
: this.errMsg
}
因此,在您的示例中添加对this.message
的引用:
get() {
this.message
let messageProxy = this.messageProxy
this.messageProxy = null
return messageProxy || this.message
}
您的第一个小提琴按预期工作的原因是因为console.log
调用this.message
作为参数。
答案 1 :(得分:1)
您的代码的实际问题是您正在更改get
函数中的数据值,它们是触发重新计算get
函数的数据值。不要这样做。 get
应该只根据其他值计算一个值。在这种情况下,它应该是
get () {
console.log(this.messageProxy, this.message);
return this.messageProxy || this.message;
},
无论有没有console
消息,它都会按预期执行。
重新检查了您的期望后,我发现只要默认消息发生更改,您就希望清除覆盖。您可以使用其他watch
:
var demo = new Vue({
el: '#demo',
data() {
return {
message: 'I am a great guy',
messageProxy: null,
someText: ''
}
},
computed: {
computedMessage: {
get() {
return this.messageProxy || this.message
},
set(val) {
this.messageProxy = val
}
}
},
methods: {
overrideComputed() {
this.computedMessage = this.someText
}
},
watch: {
message: function() {
this.messageProxy = null;
}
}
})

div {
margin: 5px;
}

<script src="//cdnjs.cloudflare.com/ajax/libs/vue/2.2.4/vue.min.js"></script>
<div id="demo">
<p>This message must reflect value of input1</p>
<div>
{{ computedMessage }}
</div>
input1: <input type="text" v-model='message'>
<div>
<p>This will cause computed message to reflect input2</p>
input2: <input type="text" v-model='someText'>
<button @click='overrideComputed'>Override</button>
</div>
</div>
&#13;
PS:你真的不需要这里计算的可设置表。您可以overrideComputed
直接设置messageProxy
。