技术文档中心
首页
React
Vue
TypeScript
Kotlin
React Native
Electron
Android
首页
React
Vue
TypeScript
Kotlin
React Native
Electron
Android
  • Vue2 基础

    • Vue 学习指南
    • Vue2 快速入门
    • Vue2 模板语法
    • Vue2 组件基础
    • Vue2 计算属性与侦听器
    • Vue2 生命周期
  • Vue2 进阶

    • Vue2 组件通信
    • Vue2 插槽详解
    • Vue2 混入与自定义指令
    • Vue2 过渡与动画
    • Vuex 状态管理
  • Vue2 高级

    • Vue2 性能优化
    • Vue2 服务端渲染(SSR)
    • Vue2 源码解析
  • Vue3 基础

    • Vue3 快速入门
    • Vue3 Composition API
    • Vue3 响应式系统
    • Vue3 组件基础
    • Vue3 生命周期
  • Vue3 进阶

    • Vue3 组合式函数
    • Vue3 组件通信
    • Vue3 Teleport 与 Suspense
    • Pinia 状态管理
    • Vue Router 4
  • Vue3 高级

    • Vue3 TypeScript
    • Vue3 性能优化
    • Vue3 测试
    • Vue3 SSR
    • Vue3 源码解析
  • 实战项目

    • Vue2 实战项目
    • Vue3 实战项目
    • Vue2 迁移 Vue3

Vue2 计算属性与侦听器

计算属性

基本用法

const vm = new Vue({
  el: '#app',
  data: {
    message: 'Hello'
  },
  computed: {
    reversedMessage() {
      return this.message.split('').reverse().join('')
    }
  }
})

计算属性 vs 方法

// 计算属性
computed: {
  now() {
    return Date.now()
  }
}

// 方法
methods: {
  now() {
    return Date.now()
  }
}

计算属性是基于响应式依赖进行缓存的,只有相关响应式依赖发生改变时才会重新求值。

计算属性的 setter

computed: {
  fullName: {
    get() {
      return this.firstName + ' ' + this.lastName
    },
    set(newValue) {
      const names = newValue.split(' ')
      this.firstName = names[0]
      this.lastName = names[names.length - 1]
    }
  }
}

侦听器

基本用法

const vm = new Vue({
  el: '#app',
  data: {
    question: '',
    answer: 'I cannot give you an answer until you ask a question!'
  },
  watch: {
    question(newQuestion, oldQuestion) {
      this.answer = 'Waiting for you to stop typing...'
      this.debouncedGetAnswer()
    }
  }
})

深度侦听

watch: {
  someObject: {
    handler(newValue, oldValue) {
      console.log('someObject changed')
    },
    deep: true
  }
}

立即执行

watch: {
  someData: {
    handler(newValue, oldValue) {
      console.log('someData changed')
    },
    immediate: true
  }
}

侦听对象属性

watch: {
  'someObject.a': function (val, oldVal) {
    console.log('new: %s, old: %s', val, oldVal)
  }
}

计算属性 vs 侦听器

使用计算属性

computed: {
  fullName() {
    return this.firstName + ' ' + this.lastName
  }
}

使用侦听器(不推荐)

watch: {
  firstName(val) {
    this.fullName = val + ' ' + this.lastName
  },
  lastName(val) {
    this.fullName = this.firstName + ' ' + val
  }
}

实际应用场景

表单验证

data: {
  email: ''
},
computed: {
  isValidEmail() {
    const re = /^[^\s@]+@[^\s@]+\.[^\s@]+$/
    return re.test(this.email)
  }
}

过滤列表

data: {
  searchQuery: '',
  items: [...]
},
computed: {
  filteredItems() {
    return this.items.filter(item => {
      return item.name.toLowerCase().includes(this.searchQuery.toLowerCase())
    })
  }
}

异步操作

watch: {
  searchQuery: {
    handler(newQuery) {
      this.debouncedSearch(newQuery)
    },
    immediate: true
  }
},
methods: {
  debouncedSearch: _.debounce(function (query) {
    this.fetchResults(query)
  }, 500)
}
最近更新: 2026/1/27 15:51
Contributors: hailong
Prev
Vue2 组件基础
Next
Vue2 生命周期