Vue 反应性问题,需要一些解释
Vue reactivity issue, need some explanations
我已经删除了我代码中大部分无用的部分,所以如果这段代码真的没有意义,请不要担心,它只是向您展示哪些部分不起作用。
首先,我从名为 objects
:
的基本数组创建一个数组
objects: [
{
text: "I dont trigger stuff",
},
{
"text": "I dont trigger stuff",
},
{
text:"I trigger stuff",
activated: undefined,
},
],
创建函数
created() {
const newArray = [];
this.objects.forEach(anObj => {
anObj.activated = false;
newArray.push(anObj);
});
this.filteredObjects = newArray;
},
我将属性 activated
初始化为false
。在我的真实代码中,我没有使用 forEach
,而是 find
,但结果是一样的。
然后,我显示几个按钮来触发 "activation"
<button
v-for="(myObj, index) in filteredObjects"
:key="index"
@click="activateObject(myObj, index)">
{{ myObj.text }}
</button>
被触发的函数是这个:
activateObject(anObj, anObjIndex) {
this.$set(this.filteredObjects[anObjIndex], 'activated', !anObj.activated)
},
我的目标是更新 activated
属性.
为了检查反应性是否有效,我有一个观察者:
watch: {
filteredObjects: {
handler() {
alert('called')
},
deep: true,
}
},
我有两个问题:
1/ 由于所有对象的所有 activated
属性都设置为 false
,为什么只有一个工作,属性 最初设置为 undefined
?
2/ 如果我将激活函数更新为:
activateObject(anObj, anObjIndex) {
anObj.activated = !anObj.activated;
this.$set(this.filteredObjects, anObjIndex, anObj);
},
效果很好。谁能解释一下为什么,有什么区别?
在这两种情况下,VueJS Devtools 在单击刷新时都会显示更新后的值。这是一个反应性问题。
您可以在此处找到 fiddle:
来自Docs:
Since Vue performs the getter/setter conversion process during instance initialization, a property must be present in the data object in order for Vue to convert it and make it reactive.
这解释了为什么只有第三个按钮 "trigger stuff"。
因此,您可以在 data()
中添加该属性,或者如文档中所述,使用 this.$set
:
this.objects.forEach(anObj => {
this.$set(anObj, 'activated', false);
newArray.push(anObj);
});
希望对您有所帮助!
我已经删除了我代码中大部分无用的部分,所以如果这段代码真的没有意义,请不要担心,它只是向您展示哪些部分不起作用。
首先,我从名为 objects
:
objects: [
{
text: "I dont trigger stuff",
},
{
"text": "I dont trigger stuff",
},
{
text:"I trigger stuff",
activated: undefined,
},
],
创建函数
created() {
const newArray = [];
this.objects.forEach(anObj => {
anObj.activated = false;
newArray.push(anObj);
});
this.filteredObjects = newArray;
},
我将属性 activated
初始化为false
。在我的真实代码中,我没有使用 forEach
,而是 find
,但结果是一样的。
然后,我显示几个按钮来触发 "activation"
<button
v-for="(myObj, index) in filteredObjects"
:key="index"
@click="activateObject(myObj, index)">
{{ myObj.text }}
</button>
被触发的函数是这个:
activateObject(anObj, anObjIndex) {
this.$set(this.filteredObjects[anObjIndex], 'activated', !anObj.activated)
},
我的目标是更新 activated
属性.
为了检查反应性是否有效,我有一个观察者:
watch: {
filteredObjects: {
handler() {
alert('called')
},
deep: true,
}
},
我有两个问题:
1/ 由于所有对象的所有 activated
属性都设置为 false
,为什么只有一个工作,属性 最初设置为 undefined
?
2/ 如果我将激活函数更新为:
activateObject(anObj, anObjIndex) {
anObj.activated = !anObj.activated;
this.$set(this.filteredObjects, anObjIndex, anObj);
},
效果很好。谁能解释一下为什么,有什么区别?
在这两种情况下,VueJS Devtools 在单击刷新时都会显示更新后的值。这是一个反应性问题。
您可以在此处找到 fiddle:
来自Docs:
Since Vue performs the getter/setter conversion process during instance initialization, a property must be present in the data object in order for Vue to convert it and make it reactive.
这解释了为什么只有第三个按钮 "trigger stuff"。
因此,您可以在 data()
中添加该属性,或者如文档中所述,使用 this.$set
:
this.objects.forEach(anObj => {
this.$set(anObj, 'activated', false);
newArray.push(anObj);
});
希望对您有所帮助!