Skip to content

计算属性与监听器

在 Vue3 的组合式 API 中,计算属性和监听器是处理响应式数据的重要工具。它们可以帮助我们更高效地处理数据逻辑,提高代码的可维护性。

计算属性 computed

计算属性用于处理复杂的计算逻辑,它会缓存计算结果,只有当依赖的响应式数据变化时才会重新计算。

基本用法

javascript
import { ref, computed } from 'vue'

const count = ref(0)

// 计算属性
const doubleCount = computed(() => {
  return count.value * 2
})

// 使用计算属性
console.log(doubleCount.value) // 0

// 修改依赖数据
count.value = 10
console.log(doubleCount.value) // 20

特点

  • 缓存计算结果,提高性能
  • 依赖响应式数据,自动重新计算
  • 可以像普通响应式数据一样使用

计算属性的 setter

计算属性默认是只读的,但我们也可以为它设置 setter:

javascript
import { ref, computed } from 'vue'

const firstName = ref('张')
const lastName = ref('三')

const fullName = computed({
  // getter
  get() {
    return firstName.value + lastName.value
  },
  // setter
  set(newValue) {
    const parts = newValue.split(' ')
    firstName.value = parts[0]
    lastName.value = parts[1] || ''
  }
})

// 使用 setter
fullName.value = '李四'
console.log(firstName.value) // 李
console.log(lastName.value) // 四

监听器 watch

监听器用于监听响应式数据的变化,当数据变化时执行指定的回调函数。

基本用法

javascript
import { ref, watch } from 'vue'

const count = ref(0)

// 监听单个数据源
watch(count, (newValue, oldValue) => {
  console.log(`count 从 ${oldValue} 变为 ${newValue}`)
})

// 修改数据
count.value++ // 输出:count 从 0 变为 1

监听多个数据源

javascript
import { ref, watch } from 'vue'

const count = ref(0)
const message = ref('Hello')

// 监听多个数据源
watch([count, message], ([newCount, newMessage], [oldCount, oldMessage]) => {
  console.log(`count 从 ${oldCount} 变为 ${newCount}`)
  console.log(`message 从 ${oldMessage} 变为 ${newMessage}`)
})

监听对象

javascript
import { reactive, watch } from 'vue'

const user = reactive({
  name: '张三',
  age: 20
})

// 监听对象的所有属性
watch(
  () => user,
  (newUser, oldUser) => {
    console.log('user 发生变化:', newUser)
  },
  { deep: true } // 深度监听
)

// 只监听对象的某个属性
watch(
  () => user.age,
  (newAge, oldAge) => {
    console.log(`age 从 ${oldAge} 变为 ${newAge}`)
  }
)

watchEffect

watchEffect 是一个更简洁的监听器,它会自动追踪依赖的响应式数据,当依赖变化时重新执行。

基本用法

javascript
import { ref, watchEffect } from 'vue'

const count = ref(0)
const message = ref('Hello')

// 自动追踪依赖
watchEffect(() => {
  console.log(`count: ${count.value}, message: ${message.value}`)
})

// 修改依赖数据
count.value++ // 输出:count: 1, message: Hello
message.value = 'World' // 输出:count: 1, message: World

停止监听

javascript
import { ref, watchEffect } from 'vue'

const count = ref(0)

// 创建监听器
const stop = watchEffect(() => {
  console.log(`count: ${count.value}`)
})

// 修改数据
count.value++ // 输出:count: 1

// 停止监听
stop()

// 再次修改数据,不会触发监听器
count.value++ // 无输出

计算属性与监听器的区别

特性计算属性 (computed)监听器 (watch)
用途处理复杂计算,缓存结果监听数据变化,执行副作用
触发时机依赖变化时自动重新计算数据变化时执行回调
返回值必须有返回值可以没有返回值
缓存有缓存机制无缓存机制

实战示例

javascript
import { ref, computed, watch, watchEffect } from 'vue'

// 数据源
const price = ref(100)
const quantity = ref(10)
const discount = ref(0.9)

// 计算属性:总价
const totalPrice = computed(() => {
  return price.value * quantity.value * discount.value
})

// 监听器:监听总价变化
watch(totalPrice, (newValue) => {
  console.log(`总价变化为: ${newValue}`)
  // 可以在这里执行副作用,如更新 DOM、发送请求等
})

// watchEffect:自动追踪所有依赖
watchEffect(() => {
  const finalPrice = price.value * quantity.value * discount.value
  console.log(`当前总价: ${finalPrice}`)
})

// 修改数据
price.value = 200 // 触发计算属性和监听器
quantity.value = 5 // 触发计算属性和监听器
discount.value = 0.8 // 触发计算属性和监听器

通过计算属性和监听器,我们可以更有效地处理数据逻辑,提高代码的可读性和可维护性。

© 2026 编程马·菜鸟教程 版权所有