指南
基础
- 安装
- 介绍
- Vue 实例
- 模板语法
- 计算属性和侦听器
- 类和样式绑定
- 条件渲染
- 列表渲染
- 事件处理
- 表单输入绑定
- 组件基础
组件深入
- 组件注册
- Props
- 自定义事件
- 插槽
- 动态和异步组件
- 处理边缘情况
过渡和动画
- 进入/离开和列表过渡
- 状态过渡
可重用性和组合
- Mixin
- 自定义指令
- 渲染函数和 JSX
- 插件
- 过滤器
工具
- 单文件组件
- 测试
- TypeScript 支持
- 生产部署
扩展
- 路由
- 状态管理
- 服务器端渲染
- 安全
内部机制
- 深入响应性
迁移
- 从 Vue 1.x 迁移
- 从 Vue Router 0.7.x 迁移
- 从 Vuex 0.6.x 迁移到 1.0
- 迁移到 Vue 2.7
元数据
- 与其他框架的比较
- 加入 Vue.js 社区!
- 认识团队
计算属性和侦听器
计算属性
模板表达式非常方便,但它们只适合简单的操作。在模板中放置太多逻辑会导致模板臃肿且难以维护。例如
|
此时,模板不再简单和声明式。你需要花点时间才能意识到它显示了 message
的反转。当你想要在模板中多次包含反转后的消息时,这个问题会变得更糟。
这就是为什么对于任何复杂的逻辑,你应该使用 **计算属性**。
基本示例
|
|
结果
原始消息: "{{ message }}"
计算后的反转消息: "{{ reversedMessage }}"
这里我们声明了一个计算属性 reversedMessage
。我们提供的函数将用作属性 vm.reversedMessage
的 getter 函数。
|
你可以打开控制台并自己玩这个示例 vm。vm.reversedMessage
的值始终依赖于 vm.message
的值。
你可以在模板中像普通属性一样绑定到计算属性。Vue 知道 vm.reversedMessage
依赖于 vm.message
,因此当 vm.message
发生变化时,它会更新任何依赖于 vm.reversedMessage
的绑定。最棒的是,我们以声明式的方式创建了这种依赖关系:计算 getter 函数没有副作用,这使得它更容易测试和理解。
计算缓存 vs 方法
你可能已经注意到,我们可以通过在表达式中调用方法来实现相同的结果
|
|
我们可以将相同的函数定义为方法,而不是计算属性。对于最终结果,这两种方法确实完全相同。但是,区别在于 **计算属性根据它们的响应式依赖关系进行缓存**。计算属性只有在某些响应式依赖关系发生变化时才会重新计算。这意味着只要 message
没有改变,多次访问 reversedMessage
计算属性将立即返回之前计算的结果,而无需再次运行函数。
这也意味着以下计算属性永远不会更新,因为 Date.now()
不是响应式依赖关系
|
相比之下,方法调用将在 **每次** 重新渲染时 **始终** 运行函数。
为什么我们需要缓存?想象一下,我们有一个昂贵的计算属性 **A**,它需要遍历一个巨大的数组并进行大量计算。然后我们可能还有其他计算属性,它们又依赖于 **A**。如果没有缓存,我们将在必要的情况下执行 **A** 的 getter 多次!在你不想要缓存的情况下,请使用方法代替。
计算属性 vs 侦听属性
Vue 提供了一种更通用的方法来观察和响应 Vue 实例上的数据变化:**侦听属性**。当你有一些数据需要根据其他数据进行改变时,很容易过度使用 watch
- 尤其是如果你来自 AngularJS 背景。但是,通常使用计算属性比使用命令式的 watch
回调更好。考虑以下示例
|
|
上面的代码是命令式的,并且重复。将其与计算属性版本进行比较
|
好多了,不是吗?
计算 setter
计算属性默认情况下是只读的,但你也可以在需要时提供 setter
|
现在当你运行 vm.fullName = 'John Doe'
时,setter 将被调用,vm.firstName
和 vm.lastName
将被相应地更新。
侦听器
虽然计算属性在大多数情况下更合适,但有时需要自定义侦听器。这就是为什么 Vue 提供了一种更通用的方法来通过 watch
选项响应数据变化。这在你想对数据变化执行异步或昂贵的操作时最有用。
例如
|
|
结果
问一个是/否问题:
{{ answer }}
在这种情况下,使用 watch
选项允许我们执行异步操作(访问 API),限制我们执行该操作的频率,并在获得最终答案之前设置中间状态。计算属性无法做到这些。
除了 watch
选项之外,你还可以使用命令式的 vm.$watch API。