Vue - 计算属性、监听器
计算属性
file:[计算属性]
<script setup>
let price = ref(1);
let num = ref(1);
const total = computed(() => {
return price.value * num.value;
});
</script>
<template>
<div class="demo2">
Total: {{ total }}
<div>
<span>Price: </span>
<input v-model="price" />
</div>
<div>
<span>Num: </span>
<input v-model="num" />
</div>
</div>
</template>
计算属性中有两个响应式数据:price
和 num
。当其中一个数据发生变化时,计算属性将重新执行一次:
只要依赖的响应式数据没有改变,计算属性就不会重新执行,而是直接返回它存储的缓存。所以,通过计算属性可以节省开销,即官方文档:“因此我们推荐使用计算属性来描述依赖响应式状态的复杂逻辑。”。
比较普通函数
普通的函数也能替代计算属性做的事情,唯一的区别就是,普通函数每在模板里面使用一次就计算一次代码,这可能加大开销,降低性能,它不缓存。
file:[Demo.vue - template]
<div v-html="formatJson(jsonData)"></div>
<div v-html="formatJson(jsonData)"></div>
<div v-html="formatJson(jsonData)"></div>
控制台打印了三次,说明普通函数被调用三次:
总结
在逻辑复杂,页面上多次使用的代码,考虑使用计算属性。计算属性能够保存第一次计算的缓存,除非依赖的响应式数据发生了改变,不管调用多少次都返回上一次的缓存结果。计算属性能够减少我们的开销,提升性能。而普通的函数就完全不具备这些特点。
监听器
file:[监听器]
let price = ref(1);
let num = ref(1);
add:[let total = ref(0);
watch(num, (newVal, oldVal) => {
total.value = price.value + newVal;
});]:add
监听 num
,当其发生变化时,执行监听器回调函数。输入 price
时,该监听器不会执行,即便是监听器内部依赖了其他响应式数据也不会执行,与计算属性不一样。
图2 中,输入 num
时,执行回调函数,界面重新渲染。
适用场景
计算属性
官方文档对于计算属性提到了一个重要的点子——“临时快照”(计算属性的缓存),每响应式数据发生变化时,就会创建一个新的快照。
有时候创建快照是没有意义的,对于间隔时间很短的数据修改,比如输入框输入,每一次都要创建“临时快照”,这样是没有意义的,反而可能增加开销。
界面想要的结果是同一个,即计算逻辑被多次使用,就应该使用计算属性。
监听器
监听器没有“快照机制”,所以更加适用数据修改频繁的场景。而且,监听器只负责一个响应式数据,如果回调函数中涉及到了其他响应式数据,不会因为它们导致整个监听器重新执行。所以,监听器更加适合根据监听的响应式数据去做跟这个数据有关的“副作用”。
tip:[start]
副作用就是例如更改 DOM、根据异步操作的结果去修改另一处的状态,也可以理解为本该停下来的行为却还在执行,总之就是监听器中的回调函数。
tip:[end]