乐趣区

关于前端:Vue关于computed在计算属性中return函数的问题

一、背景

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

退出移动版