计算属性和观察者

计算属性

模板内的表达式非常便利,但是设计它们的初衷是用于简单运算的。在模板中放入太多的逻辑会让模板过重且难以维护。例如:

<div id="example">{{ message.split('').reverse().join('') }}
</div>
复制代码

在这个地方,模板不再是简单的声明式逻辑。你必须看一段时间才能意识到,这里是想要显示变量 message 的翻转字符串。当你想要在模板中多次引用此处的翻转字符串时,就会更加难以处理。

所以,对于任何复杂逻辑,你都应当使用计算属性

基础例子

<div id="example"><p>Original message: "{{ message }}"</p><p>Computed reversed message: "{{ reversedMessage }}"</p>
</div>
复制代码
var vm = new Vue({el: '#example',data: {message: 'Hello'},computed: {// 计算属性的 getterreversedMessage: function () {// `this` 指向 vm 实例return this.message.split('').reverse().join('')}}
})
复制代码
结果:Original message: "Hello"Computed reversed message: "olleH"
复制代码

这里我们声明了一个计算属性 reversedMessage。我们提供的函数将用作属性 vm.reversedMessage 的 getter 函数:

console.log(vm.reversedMessage) // => 'olleH'
vm.message = 'Goodbye'
console.log(vm.reversedMessage) // => 'eybdooG'
复制代码

你可以打开浏览器的控制台,自行修改例子中的 vm。vm.reversedMessage 的值始终取决于 vm.message 的值。

你可以像绑定普通属性一样在模板中绑定计算属性。Vue 知道 vm.reversedMessage 依赖于 vm.message,因此当 vm.message 发生改变时,所有依赖 vm.reversedMessage 的绑定也会更新。而且最妙的是我们已经以声明的方式创建了这种依赖关系:计算属性的 getter 函数是没有副作用 (side effect) 的,这使它更易于测试和理解。

计算属性缓存 vs 方法

你可能已经注意到我们可以通过在表达式中调用方法来达到同样的效果:

<p>Reversed message: "{{ reversedMessage() }}"</p>
复制代码
// 在组件中
methods: {reversedMessage: function () {return this.message.split('').reverse().join('')}
}
复制代码

我们可以将同一函数定义为一个方法而不是一个计算属性。两种方式的最终结果确实是完全相同的。然而,不同的是计算属性是基于它们的依赖进行缓存的。计算属性只有在它的相关依赖发生改变时才会重新求值。这就意味着只要 message 还没有发生改变,多次访问 reversedMessage 计算属性会立即返回之前的计算结果,而不必再次执行函数。

这也同样意味着下面的计算属性将不再更新,因为 Date.now() 不是响应式依赖:

computed: {now: function () {return Date.now()}
}
复制代码

相比之下,每当触发重新渲染时,调用方法将总会再次执行函数。

我们为什么需要缓存?假设我们有一个性能开销比较大的的计算属性 A,它需要遍历一个巨大的数组并做大量的计算。然后我们可能有其他的计算属性依赖于 A 。如果没有缓存,我们将不可避免的多次执行 A 的 getter!如果你不希望有缓存,请用方法来替代。

计算属性 vs 侦听属性

Vue 提供了一种更通用的方式来观察和响应 Vue 实例上的数据变动:侦听属性。当你有一些数据需要随着其它数据变动而变动时,你很容易滥用 watch——特别是如果你之前使用过 AngularJS。然而,通常更好的做法是使用计算属性而不是命令式的 watch 回调。细想一下这个例子:

<div id="demo">{{ fullName }}</div>
复制代码
var vm = new Vue({el: '#demo',data: {firstName: 'Foo',lastName: 'Bar',fullName: 'Foo Bar'},watch: {firstName: function (val) {this.fullName = val + ' ' + this.lastName},lastName: function (val) {this.fullName = this.firstName + ' ' + val}}
})
复制代码

上面代码是命令式且重复的。将它与计算属性的版本进行比较:

var vm = new Vue({el: '#demo',data: {firstName: 'Foo',lastName: 'Bar'},computed: {fullName: function () {return this.firstName + ' ' + this.lastName}}
})
复制代码

计算属性的 setter

计算属性默认只有 getter ,不过在需要时你也可以提供一个 setter :

// ...
computed: {fullName: {// getterget: function () {return this.firstName + ' ' + this.lastName},// setterset: function (newValue) {var names = newValue.split(' ')this.firstName = names[0]this.lastName = names[names.length - 1]}}
}
// ...
复制代码

现在再运行 vm.fullName = 'John Doe' 时,setter 会被调用,vm.firstNamevm.lastName 也会相应地被更新。

侦听器

虽然计算属性在大多数情况下更合适,但有时也需要一个自定义的侦听器。这就是为什么 Vue 通过watch 选项提供了一个更通用的方法,来响应数据的变化。当需要在数据变化时执行异步或开销较大的操作时,这个方式是最有用的。

例如:

<div id="watch-example"><p>Ask a yes/no question:<input v-model="question"></p><p>{{ answer }}</p>
</div>
复制代码
<!-- 因为 AJAX 库和通用工具的生态已经相当丰富,Vue 核心代码没有重复 -->
<!-- 提供这些功能以保持精简。这也可以让你自由选择自己更熟悉的工具。 -->
<script src="https://cdn.jsdelivr.net/npm/axios@0.12.0/dist/axios.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/lodash@4.13.1/lodash.min.js"></script>
<script>
var watchExampleVM = new Vue({el: '#watch-example',data: {question: '',answer: 'I cannot give you an answer until you ask a question!'},watch: {// 如果 `question` 发生改变,这个函数就会运行question: function (newQuestion, oldQuestion) {this.answer = 'Waiting for you to stop typing...'this.getAnswer()}},methods: {// `_.debounce` 是一个通过 Lodash 限制操作频率的函数。// 在这个例子中,我们希望限制访问 yesno.wtf/api 的频率// AJAX 请求直到用户输入完毕才会发出。想要了解更多关于// `_.debounce` 函数 (及其近亲 `_.throttle`) 的知识,// 请参考:https://lodash.com/docs#debouncegetAnswer: _.debounce(function () {if (this.question.indexOf('?') === -1) {this.answer = 'Questions usually contain a question mark. ;-)'return}this.answer = 'Thinking...'var vm = thisaxios.get('https://yesno.wtf/api').then(function (response) {vm.answer = _.capitalize(response.data.answer)}).catch(function (error) {vm.answer = 'Error! Could not reach the API. ' + error})},// 这是我们为判定用户停止输入等待的毫秒数500)}
})
</script>
复制代码

在这个示例中,使用 watch 选项允许我们执行异步操作 (访问一个 API),限制我们执行该操作的频率,并在我们得到最终结果前,设置中间状态。这些都是计算属性无法做到的。

除了 watch 选项之外,您还可以使用命令式的 vm.$watch API

Vue 第一天: 计算属性和观察者相关推荐

  1. 003-读书笔记-Vue官网 计算属性与监听器

    1.计算属性 1-1 计算属性概述 计算属性也是 Vue 实例的属性,和 data 方法中返回的对象中的属性是等同的存在.通常来说,计算属性可以简单理解: 计算属性其实就是 Vue 实例的一个属性 计 ...

  2. [vue] watch和计算属性有什么区别?

    [vue] watch和计算属性有什么区别? 一个是侦听属性,一个是计算属性 2.一个是为了应对复杂的逻辑计算,一个是对数据的变化作出反应 3.一个是只有当缓存改变时才执行,一个是只要从新渲染就会执行 ...

  3. [vue] 在使用计算属性的时,函数名和data数据源中的数据可以同名吗?

    [vue] 在使用计算属性的时,函数名和data数据源中的数据可以同名吗? 莫名其妙的问题.可以同名,但data会覆盖methods.并且本就不该同名,同名说明你命名不规范.然后解释为什么会覆盖,因为 ...

  4. Vue基础之计算属性

    Vue基础之计算属性 定义: 原理: get函数执行时机: 优势: 备注: Demo: 定义: 要用的属性不存在,要通过已有属性计算得来. 原理: 底层借助了Objcet.defineproperty ...

  5. Vue中computed计算属性和data数据获取的问题

    获取到数据(对象.数组),截取一部分显示到页面中,用computed计算属性来实现截取数据然后直接输出到页面. <div class="detailBox"><h ...

  6. 面试题!vue中的计算属性、方法、侦听属性

    1.计算属性 详细的内容可跳转至vue 计算属性 可以使用计算属性来代替在表达式中进行的复杂运算,以便于能够更方便的维护与复用逻辑. 计算属性是在选项对象中使用 computed 字段来定义. 特点: ...

  7. Vue.js系列之四计算属性和观察者

    一.计算属性 1.模版内的表达式非常便利,但是设计它们的初衷是用于简单计算的.在模版中放入太多的逻辑运算会让模版过重且难以维护,例如如下代码: <div id="example&quo ...

  8. Vue 过滤器、计算属性、侦听器 图解版 一目了然

    文章目录 本篇学习目标 1. vue基础 1.0_vue基础 v-for更新监测 1.1_vue基础_v-for就地更新 1.2_vue基础_虚拟dom 1.3_vue基础_diff算法 情况1: 根 ...

  9. 五十八、Vue中的计算属性,方法和侦听器

    @Author:Runsen @Date:2020/10/15 本篇是水篇,记录前端的学习,争取早日拿到前端offer 计算属性,方法和侦听器 所以,对于任何复杂逻辑,你都应当使用计算属性.(官方原话 ...

最新文章

  1. json字段顺序读取 python_如何利用Python批量读取视频文件的时间长度?
  2. CMake一次失败应用
  3. Ubuntu开机后一直循环登录,却进不去桌面
  4. 一个简单的登录页面,效果不错哦!
  5. 猫猫学IOS(二十一)UIApplication设置程序图标右上⾓红⾊数字_联⺴指⽰器等
  6. 5 压缩上传图片_推荐一个干净纯粹的网站,专注图片压缩、pdf相关操作
  7. redis java序列化_java处理redis的几种序列化策略
  8. zzulioj 1065:统计数字字符个数
  9. 根据函数名称调用函数
  10. 如何在 vue 项目中引入 html 文件
  11. 用数据说话,基金经理一年到底能挣多少钱?
  12. python多线程异步爬虫-Python异步爬虫试验[Celery,gevent,requests]
  13. linepipe——又一个自然语言开源程序
  14. 统计处理包Statsmodels: statistics in python
  15. 关于js对象添加属性
  16. 《数学之美》一 文字、数字及语言的历史
  17. PLSQL 升级到最新版本 以及 破解注册细则
  18. 单点登录(java)
  19. 最小二乘法原理-线性回归
  20. 现在世界上到底有多少飞机?

热门文章

  1. ActiveMQ持久化消息的三种方式
  2. JavaScript中函数四种调用模式
  3. 可以多次使用同一个hbitmap吗_一个部位可以多次吸脂吗?
  4. Python爬无止境,获得王者荣耀全部高清皮肤
  5. java中的循环语句类型_java 循环 基本类型
  6. lg-1 x 怎么算_阿迪达斯crazy byw x实战测评 crazy byw x脚感怎么样
  7. 如果你是C开发人员请看这三个显式编程技巧
  8. ASP.NET Web Pages – Chart 帮助器简介
  9. elementary OS 6 评测!
  10. ldap客户端工具_什么是性能测试?性能测试主流工具有哪些?