一、背景
我的项目中偶尔遇到有人在 computed 中这样写代码:
computed: {getName() {return function () {return "张三";};
},
},
这段代码看似没什么故障,实际上它违反了 computed 的设计初衷,computed 设计的起因是为了简化模板中又长又臭的计算逻辑,使模板代码看上去更加简洁,容易保护,并且计算属性会基于响应式依赖进行缓存,从而优化性能。
二、计算属性介绍
对于计算属性官网的形容如下:
文档地址:
https://cn.vuejs.org/v2/guide…
为什么说下面这段代码违反了 computed 的设计初衷呢?
先来看看 computed 和 methods 的区别,而后咱们就能够解释这个问题了,官网形容如下:
文档:https://cn.vuejs.org/v2/guide…
也就是说尽管它们俩的成果雷同,但 computed 会基于响应式依赖进行缓存,methods 不会,咱们来验证一下:
三、实际测验
首先创立 computed 和 methods,打印日志,而后在页面上别离调用几次
<template>
<div>
<p>{{computed_getName}}</p>
<p>{{computed_getName}}</p>
<p>{{computed_getName}}</p>
<p>{{computed_getName}}</p>
<p>{{method_getName() }}</p>
<p>{{method_getName() }}</p>
<p>{{method_getName() }}</p>
<p>{{method_getName() }}</p>
</div>
</template>
<script>
export default {
computed: {computed_getName() {console.log("computed 计算属性被调用了");
return "张三";
},
},
methods: {method_getName() {console.log("methods 办法被调用了");
return "李四";
},
},
};
</script>
页面运行后果如下:
控制台输入后果如下:
后果能够看到尽管计算属性 computed_getName 与办法 method_getName 都在模板中援用了 4 次,然而 computed_getName 只被触发了 1 次,而 method_getName 办法被触发了 4 次,也就验证了 computed 具备缓存性能的个性。
如果将计算属性改一下,换成结尾所说的 return 函数呢?
<template>
<div>
<!-- 相应的调用计算属性也要改成函数的模式 -->
<p>{{computed_getName() }}</p>
<p>{{computed_getName() }}</p>
<p>{{computed_getName() }}</p>
<p>{{computed_getName() }}</p>
<p>{{method_getName() }}</p>
<p>{{method_getName() }}</p>
<p>{{method_getName() }}</p>
<p>{{method_getName() }}</p>
</div>
</template>
<script>
export default {
computed: {computed_getName() {
// 批改成 return 函数的模式
return function () {console.log("computed 计算属性被调用了");
return "张三";
};
},
},
methods: {method_getName() {console.log("methods 办法被调用了");
return "李四";
},
},
};
</script>
页面运行后果如下:
控制台输入后果如下:
后果很显著,return 函数之后,想要拿到计算结果必须要调用这个计算函数(等同于调用办法,只不过定义方法的地位放在了 computed 中),也就失去了缓存的作用,再来品 Vue 官网文档:
咱们为什么须要缓存?假如咱们有一个性能开销比拟大的计算属性 A,它须要遍历一个微小的数组并做大量的计算。而后咱们可能有其余的计算属性依赖于 A。如果没有缓存,咱们将不可避免的屡次执行 A 的 getter!如果你不心愿有缓存,请用办法来代替。
那么,假如本例中的 getName 是一个开销较大的计算属性,当初它又失去了缓存的作用,咱们是不是能够遵循官网约定应用办法来代替呢?
再有另一点起因是,一个计算属性的创立步骤比较复杂,有趣味可参考如下文章进行学习(比拟懒,有现成的就贴这了,轻点喷 …):
https://cloud.tencent.com/dev…
而一个办法的创立就比较简单了,源码如下:
去掉这一大堆的容错判断,实际上就只是遍历所有的 methods 而后挂载到实例 vm 上,如下:
function initMethods (vm, methods) {
var props = vm.$options.props;
for (var key in methods) {
// 省略其余代码
vm[key] = typeof methods[key] !== 'function' ? noop : bind(methods[key], vm);
}
}
有的时候计算须要依赖模板数据中的某个状态,你们想通过计算属性中返回一个函数进行传参,既能借助 computed 缓存的个性来优化内存应用,又能简化模板中大量的计算逻辑,但想法虽好,还需理性认识 computed。
因而,如果你还看到有人在 computed 中 return 函数的骚操作,你晓得该怎么做了吗?
四、总结
- 计算属性适宜简化模板逻辑,具备缓存个性,用得好相对是神器
- 在计算属性中 return 函数的作用与 method 是统一的,然而性能开销远远高于 method
本文由博客一文多发平台 OpenWrite 公布!