先前已经写过Vue3中
watch
和watchEffect
的文章,可以看这里Vue3中的watch和watchEffect,该篇文章主要聊聊computed特性以及这三者之间的区别。
computed
相信大家都不陌生,只是Vue中出现了watch
和watchEffect
等侦听器,这三者大多数情景下相同结果的使用体验,使得我们模糊了这三者之前的作用区别。
computed
computed
又称作计算属性,先给段官方描述 ⬇
接受一个 getter 函数,返回一个只读的响应式 ref 对象。该 ref 通过 .value 暴露 getter 函数的返回值。它也可以接受一个带有 get 和 set 函数的对象来创建一个可写的 ref 对象。
computed
基本用法可以看下面这个链接 ⬇
官方链接 ➡ computed基本了解
computed
特性
- 在 getter 函数中,在追踪的响应式依赖没有发生变化时,返回都会是上次缓存的数据。(计算属性和方法的区别)
- 只有在
computed
中的响应式依赖发生变化时,才会再次进行运算。
computed
的这两个特性都十分重要,我们可以在模板中这样使用setup
函数中定义的方法,编译渲染结果和使用computed
相同 ⬇
<script setup>
import { computed } from 'vue'
const number = ref(1)
const handleMethod = () => {
return number.value++;
}
const result = computed(()=>{
return number.value++;
})
</script>
<template>
<div>{{ handleMethod() }}</div>
<div>{{ result }}</div>
<div>{{ handleMethod() }}</div>
<div>{{ result }}</div>
</template>
// 四个块中的数据都为 2
结果相同,但是产生结果的过程不同,在需要多次调用模板数据且需要进行大量逻辑运算时,性能方面会有明显的差异,computed
中缓存对性能的优化则变得尤为重要。
- 使用方法时,在模板中多次使用,模板渲染时每遇到方法都会执行对应方法一遍,数据结果来源每次返回的结果。
- 使用
computed
时,在模板中多次使用,模板渲染时第一次在computed
中完成逻辑计算,数据结果来源computed
计算结果,当下次遇到相同的数据参数时,且对应的响应式依赖没有发生过变化,数据结果来源则会是computed
的上次计算的缓存数据。
缓存
缓存的性能优化作用还不止上述情况。
官方给出以下例子 ⬇
我们有一个非常耗性能的计算属性 list,需要循环一个巨大的数组并做许多计算逻辑,并且可能也有其他计算属性依赖于 list。没有缓存的话,我们会重复执行非常多次 list 的 getter,然而这实际上没有必要!如果你确定不需要缓存,那么也可以使用方法调用。
还是很好理解的,在计算响应式依赖 list 的过程中,list 里面的可能发生多次改变,而 list 可能作为其它computed
计算属性的响应式依赖,如果没有缓存,依据computed
的特性,每当响应式依赖发生变化时,会执行 getter 函数,徒增很多不必要的算量,对性能的优化是很不利的。
官方链接 ➡ 指南——计算属性
computed
、watch
和watchEffect
的区别
-
参数上,
computed
只接受一个 getter 函数,watch
和watchEffect
可以看开头链接的最后面。 -
返回值,
computed
必须要有个返回值,他会是一个只读的ref对象(最佳实践场景),watch
和watchEffect
的返回会是一个用于停止侦听的函数。 -
computed
、watchEffect
都会自动追踪响应式依赖,watch
则需要主动追踪响应式依赖。 -
使用上,
computed
着重计算,watch
和watchEffect
着重侦听。
从参数上考究,computed
没有像watch
和watchEffect
的配置对象参数去支持调整函数触发时机,官方也说了,在computed
的函数中不能做异步请求或者更改 DOM,而watch
和watchEffect
则相反,十分支持完成类似操作。
文章有问题之处还望评论斧正!