【高级前端】为什么computed不起作用?有哪些使用computed 的禁忌?
🍄 先来看实际应用时的代码
下面的方法modifyListChanged事件 不会执行,使得computed看起来‘无用’:
const modifyList = computed(() => {
emits('modifyListChanged', [0]);
return goodsList.value.map((item) => {
if (item.OriginTitle !== item.Title || item.OriginCategoryName !== item.CategoryName) {
return {
GoodsID: item.GoodsID,
Title: item.Title,
CategoryID: item.CategoryID,
CategoryName: item.CategoryName,
};
}
});
});
而下面的方法却能顺利执行:
const modifyList = computed(() => {
return goodsList.value.map((item) => {
if (item.OriginTitle !== item.Title || item.OriginCategoryName !== item.CategoryName) {
return {
GoodsID: item.GoodsID,
Title: item.Title,
CategoryID: item.CategoryID,
CategoryName: item.CategoryName,
};
}
});
});
//监听 modifyList 的变化
watch(modifyList, (newVal) => {
emits('modifyListChanged', newVal);
});
🍄原因是什么?
该modifylist变量未被使用(如模版和其他逻辑)。Vue就会优化掉它的计算,导致它看起来无用。
🍄使用computed 的禁忌
1、纯计算:computed 是个纯函数【保证了代码的可预测性和可维护性】,它的返回值只依赖于其内部的响应式数据,当这些数据变化时,computed会自动重新计算并返回新的值。
2、无副作用:computed不应该(但是会执行)包含副作用(如触发事件、修改外部状态等)。它的设计初衷是用于计算和返回数据,而不是执行额外的逻辑。(?)
🍄什么是纯函数?
1、相同的输入,总是得到相同的输出。
2、没有副作用
纯函数不建议修改外部的状态,包括但不限于:
🔨修改全局变量或传入的参数。
🔨 触发事件(如 emit)。
🔨执行 I/O 操作(如读写文件、网络请求)。
🔨调用非纯函数。
非纯函数的例子
let counter = 0;
// 非纯函数
function increment() {
counter++;
return counter;
}
- 每次调用 increment(),返回值可能不同(依赖于外部变量 counter)。
- 它修改了外部状态(counter),因此是非纯函数。
🍄为什么emits在computed 中实际情况下依旧会被执行?
只是不建议这么使用。它不会影响 computed 的返回值。因此,Vue 不会阻止这种行为。
🍄为什么不建议在computed中使用emit操作
⛓️💥、多次调用
⛓️💥、难以调试,隐藏在computed中,代码难以理解和调试
⛓️💥、emits触发的逻辑又比较复杂,可能会影响性能。