computed也就是计算属性,它可以帮助我们将在模板中的一些稍微复杂的逻辑计算放回到js代码中,方便理解与修改维护
官网中给出的例子:这里展示的数据是经过message和number两个属性经过变换合成的
<div id="example"> {{ message.split('').reverse().join('') + number }} </div>
虽然这行js代码很简单,但是如果这样的代码写多了,维护起来会很麻烦,所以类似这样的需求,我们一般将其写入computed计算属性中
官网给出的示例代码如下:
<div id="example"> <p>Original message: "{{ message }}"</p> <p>Computed reversed message: "{{ reversedMessage }}"</p> </div>
var vm = new Vue({ el: '#example', data: { message: 'Hello',
number:123
}, computed: { // 计算属性的 getter reversedMessage: function () { // `this` 指向 vm 实例 return this.message.split('').reverse().join('')+number } } })
computed VS methods
案例如下:
<p>Reversed message: "{{ reversedMessage() }}"</p>
// 在组件中 methods: { reversedMessage: function () { return this.message.split('').reverse().join('') } }
我们可以将同一函数定义为一个方法而不是一个计算属性。两种方式的最终结果确实是完全相同的。然而,不同的是计算属性是基于它们的响应式依赖进行缓存的。只在相关响应式依赖发生改变时它们才会重新求值。这就意味着只要 message
或者number还没有发生改变,多次访问 reversedMessage
计算属性会立即返回之前的计算结果,而不必再次执行函数重新计算。
但是执行函数的话,每执行一次都会重新计算一次。
第一回合:methods猝
computed VS 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 } } })
第二回合:watch猝
computed计算属性的setter
计算属性默认只有 getter,不过在需要时你也可以提供一个 setter:
computed: { fullName: { // getter get: function () { return this.firstName + ' ' + this.lastName }, // setter set: function (newValue) { var names = newValue.split(' ') this.firstName = names[0] this.lastName = names[names.length - 1] } } }
现在再运行 vm.fullName = 'John Doe'
时,setter 会被调用,vm.firstName
和 vm.lastName
也会相应地被更新。
watch是属性监听器,一般用来监听属性的变化(也可以用来监听计算属性函数),并做一些逻辑。
当需要在数据变化时执行异步或开销较大的操作时,这个方式是最有用的。
<template> <div> <p>{{ this.number }}</p> </div> </template> <script> export default { name: 'test1', data () { return { number: 1 } }, created () { setTimeout(() => { this.number = 100 }, 2000) }, watch: { number (newVal, oldVal) { console.log('number has changed: ', newVal) } } } </script>
我们在watch中监听了number属性,并且在实例创建后2s执行对number属性的值的更改。我们可以在控制台中看到2s后打印了
number has changed: 100