计算属性

特点和 Vue2 类似,使用方法不同
使用 computed() 方法期望接收一个 getter 函数,返回值为一个计算属性 ref

<script setup>
import { ref, computed } from 'vue'
 
const price1 = ref(50)
 
const price2 = computed(() => {
  return price1.value + 50
})
 
const priceRMB1 = computed(() => {
  return price2.value / 20.47
})
</script>
 
<template>
  <p>进价{{ price1 }}日元,卖价{{ price2 }}日元(约合人民币{{ priceRMB1 }}元)。</p>
</template>

完全写法

计算属性完全的写法是下面这种,但一般不写 set 方法,让它只读:

<script setup>
import { computed } from 'vue'
 
const price2 = computed({
  get() {},
  set(newValue) {}
})
</script>

获取上一个值

可以通过访问计算属性的 getter 的第一个参数来获取计算属性返回的上一个值 (仅 3.4+ 支持)

侦听器

特点和 Vue2 类似,使用方法不同

语法

watch(source, callback, options)

第一个参数可以是不同形式的“数据源”:

  • 一个 ref (包括计算属性)
  • 一个响应式对象(不能直接侦听响应式对象的属性值)
  • 一个函数,返回一个值
  • 由以上类型的值组成的数组

第三个参数可以添加配置:

  • { deep: true }:深度监听
  • { immediate: true }:在侦听器创建时立即触发回调,第一次调用时旧值是 undefined
  • { flush: 'pre' | 'post' | 'sync' }:调整回调函数的更新时机
  • { once: true }:(3.4+) 回调函数只会运行一次
<script setup>
import { ref, watch } from 'vue'
 
const price3 = ref(0)
const price4 = ref(0)
const priceRMB2 = ref(0)
 
function addPrice(value) {
  price3.value += value
}
 
watch(price3, (newv, oldv) => {
  console.log(newv, oldv)
  price4.value = price3.value + 50
  priceRMB2.value = price4.value / 20.47
})
</script>
 
<template>
  <p>进价{{ price3 }}日元,卖价{{ price4 }}日元(约合人民币{{ priceRMB2 }}元)。</p>
  <button @click="addPrice(100)">加价100</button>
</template>

watchEffect()

不用写第一个参数,会自动跟踪回调中的响应式依赖,且回调会立即执行(不需要指定 immediate: true)

<script setup>
import { ref, watch } from 'vue'
 
const price3 = ref(0)
const price4 = ref(0)
const priceRMB2 = ref(0)
 
function addPrice(value) {
  price3.value += value
}
 
watchEffect(() => {
  price4.value = price3.value + 50
  priceRMB2.value = price4.value / 20.47
})
</script>

优点:

  • 更简洁
  • 自动管理依赖关系

缺点:

  • 不能访问所侦听状态的前一个值和当前值
  • 响应性依赖关系会不那么明显
  • 不是懒执行

停止侦听

要手动停止一个侦听器,调用 watch 或 watchEffect 返回的函数

const unwatch = watchEffect(() => {})
 
// ...当该侦听器不再需要时
unwatch()