loading

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>

计算属性中有两个响应式数据:pricenum。当其中一个数据发生变化时,计算属性将重新执行一次:

图1 - 计算属性检测到一个数据发生变化重新计算返回结果

只要依赖的响应式数据没有改变,计算属性就不会重新执行,而是直接返回它存储的缓存。所以,通过计算属性可以节省开销,即官方文档:“因此我们推荐使用计算属性来描述依赖响应式状态的复杂逻辑。”。

比较普通函数

普通的函数也能替代计算属性做的事情,唯一的区别就是,普通函数每在模板里面使用一次就计算一次代码,这可能加大开销,降低性能,它不缓存。

file:[Demo.vue - template]
<div v-html="formatJson(jsonData)"></div>
<div v-html="formatJson(jsonData)"></div>
<div v-html="formatJson(jsonData)"></div>

控制台打印了三次,说明普通函数被调用三次:

图2 - 普通函数调用三次,里面的 log 函数执行了三次

总结

在逻辑复杂,页面上多次使用的代码,考虑使用计算属性。计算属性能够保存第一次计算的缓存,除非依赖的响应式数据发生了改变,不管调用多少次都返回上一次的缓存结果。计算属性能够减少我们的开销,提升性能。而普通的函数就完全不具备这些特点。

监听器

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 时,该监听器不会执行,即便是监听器内部依赖了其他响应式数据也不会执行,与计算属性不一样。

图3 - 数量发生变化时,总价改变;价格发生变化时,总价不变

图2 中,输入 num 时,执行回调函数,界面重新渲染。

适用场景

计算属性

官方文档对于计算属性提到了一个重要的点子——“临时快照”(计算属性的缓存),每响应式数据发生变化时,就会创建一个新的快照。

有时候创建快照是没有意义的,对于间隔时间很短的数据修改,比如输入框输入,每一次都要创建“临时快照”,这样是没有意义的,反而可能增加开销。

界面想要的结果是同一个,即计算逻辑被多次使用,就应该使用计算属性

监听器

监听器没有“快照机制”,所以更加适用数据修改频繁的场景。而且,监听器只负责一个响应式数据,如果回调函数中涉及到了其他响应式数据,不会因为它们导致整个监听器重新执行。所以,监听器更加适合根据监听的响应式数据去做跟这个数据有关的“副作用”

tip:[start]
副作用就是例如更改 DOM、根据异步操作的结果去修改另一处的状态,也可以理解为本该停下来的行为却还在执行,总之就是监听器中的回调函数
tip:[end]

posted @ 2022-08-25 01:36  Himmelbleu  阅读(490)  评论(0编辑  收藏  举报