计算不反应?
Computed not reactive?
我把这段代码写到return技能列表中。如果用户已经拥有特定技能,则列表项应更新为 active = false
.
这是我的初始代码:
setup () {
const user = ref ({
id: null,
skills: []
});
const available_skills = ref ([
{value: 'css', label: 'CSS', active: true},
{value: 'html', label: 'HTML', active: true},
{value: 'php', label: 'PHP', active: true},
{value: 'python', label: 'Python', active: true},
{value: 'sql', label: 'SQL', active: true},
]);
const computed_skills = computed (() => {
let result = available_skills.value.map ((skill) => {
if (user.value.skills.map ((sk) => {
return sk.name;
}).includes (skill.label)) {
skill.active = false;
}
return skill;
});
return result;
})
return {
user, computed_skills
}
},
这在初始渲染上运行良好。但是如果我从用户那里删除一项技能
user.skills.splice(index, 1)
computed_skills
未更新。
为什么会这样?
在JavaScript中,用户或对象是对对象的引用,指针本身不会随着底层属性的改变而改变,因此不会触发计算
kid of like computed 属性 for an array and if that array get pushed with new values, array of pointer of the array does not change but the underling reference only changes.
解决方法:
尝试通过隐藏变量重新分配用户
slice
只是 returns 已更改数组的副本,它不会更改原始实例..因此计算 属性 不是反应性的
尝试使用下面的代码
user.skills = user.skills.splice(index, 1);
当您更新 user.skills
时,计算道具实际上正在重新计算,但是 available_skills
的映射产生相同的结果,因此没有明显的变化。
假设 user.skills
包含 available_skills
的完整技能集,第一个计算将所有 skill.active
设置为 false
。当用户点击技能将其移除时,重新计算不会再次设置skill.active
(没有else
子句)。
let result = available_skills.value.map((skill) => {
if (
user.value.skills
.map((sk) => {
return sk.name;
})
.includes(skill.label)
) {
skill.active = false;
}
// ❌ no else to set `skill.active`
return skill;
});
但是,您的计算道具具有改变原始数据的副作用(即在 skill.active = false
中),即 should be avoided。上面的映射应该克隆原始的 skill
项目,并插入一个新的 active
属性:
const skills = user.value.skills.map(sk => sk.name);
let result = available_skills.value.map((skill) => {
return {
...skill,
active: skills.includes(skill.label)
}
});
我把这段代码写到return技能列表中。如果用户已经拥有特定技能,则列表项应更新为 active = false
.
这是我的初始代码:
setup () {
const user = ref ({
id: null,
skills: []
});
const available_skills = ref ([
{value: 'css', label: 'CSS', active: true},
{value: 'html', label: 'HTML', active: true},
{value: 'php', label: 'PHP', active: true},
{value: 'python', label: 'Python', active: true},
{value: 'sql', label: 'SQL', active: true},
]);
const computed_skills = computed (() => {
let result = available_skills.value.map ((skill) => {
if (user.value.skills.map ((sk) => {
return sk.name;
}).includes (skill.label)) {
skill.active = false;
}
return skill;
});
return result;
})
return {
user, computed_skills
}
},
这在初始渲染上运行良好。但是如果我从用户那里删除一项技能
user.skills.splice(index, 1)
computed_skills
未更新。
为什么会这样?
在JavaScript中,用户或对象是对对象的引用,指针本身不会随着底层属性的改变而改变,因此不会触发计算 kid of like computed 属性 for an array and if that array get pushed with new values, array of pointer of the array does not change but the underling reference only changes.
解决方法: 尝试通过隐藏变量重新分配用户
slice
只是 returns 已更改数组的副本,它不会更改原始实例..因此计算 属性 不是反应性的
尝试使用下面的代码
user.skills = user.skills.splice(index, 1);
当您更新 user.skills
时,计算道具实际上正在重新计算,但是 available_skills
的映射产生相同的结果,因此没有明显的变化。
假设 user.skills
包含 available_skills
的完整技能集,第一个计算将所有 skill.active
设置为 false
。当用户点击技能将其移除时,重新计算不会再次设置skill.active
(没有else
子句)。
let result = available_skills.value.map((skill) => {
if (
user.value.skills
.map((sk) => {
return sk.name;
})
.includes(skill.label)
) {
skill.active = false;
}
// ❌ no else to set `skill.active`
return skill;
});
但是,您的计算道具具有改变原始数据的副作用(即在 skill.active = false
中),即 should be avoided。上面的映射应该克隆原始的 skill
项目,并插入一个新的 active
属性:
const skills = user.value.skills.map(sk => sk.name);
let result = available_skills.value.map((skill) => {
return {
...skill,
active: skills.includes(skill.label)
}
});