一、背景

我的项目中偶尔遇到有人在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 公布!