计算属性
在模板表达式中放入太多逻辑时,会让模板重且难以维护。比如:
// 错误示例
<div id="example">
{{ message.split('').reverse().join('') }}
</div>
应该声明一个计算属性,该计算属性不用挂载到Vue实例的data上,而是在Vue实例中的computed上。程序员编写的函数将作用与 property.vm.reversedMessage 的 getter函数
具体看https://cn.vuejs.org/v2/guide/computed.html#%E8%AE%A1%E7%AE%97%E5%B1%9E%E6%80%A7
计算属性缓存 VS 方法
- 相同点:同一个函数定义为方法或计算属性,两种方式的最终结果完全相同。
- 不同点:计算属性是基于它们的响应式依赖进行缓存的。
具体看https://cn.vuejs.org/v2/guide/computed.html#%E8%AE%A1%E7%AE%97%E5%B1%9E%E6%80%A7
计算属性 VS 侦听属性
- 当有些数据需要随着其他数据变动而变动时,可以使用侦听属性。
计算属性的getter、setter
- computed 的属性可以被视为是 data 一样,可以 getter(读取)和 setter(设值),默认情况下 computed 预设只有 getter , 只能读取,不能改变设值。
// VUE.js 计算属性默认只有 getter, 因为是默认值所以我们也常常省略不写,如下代码:
computed: { fullName: function () { return this.firstName + ' ' + this.lastName } }
// computed 里的代码完整的写法应该是:
computed: { fullName: { get(){ return this.firstName + ' ' + this.lastName } } }
getter的触发时间
<template>
<div id="demo">
<p> {{ fullName }} </p>
<input type="text" v-model="firstName">
<input type="text" v-model="lastName">
</div>
</template>
var vm = new Vue({
el: '#demo',
data: {
firstName: 'zhang',
lastName: 'san'
},
computed: {
fullName: function () {
console.log('computed getter...')
return this.firstName + ' ' + this.lastName
}
},
updated () {
console.log('updated')
}
})
如果我们改变上边代码里的2个输入框的值firstName或者lastName,都会触发computed以及updated (),执行: console.log(‘computed getter…’)和console.log(‘updated’)
需要注意的是,不是说我们更改了getter里使用的变量,就会触发computed的更新,前提是computed里的值必须要在模板里使用才行。
如下代码,我们把template里的fullName 注释掉:
<template>
<div id="demo">
<!-- <p> {{ fullName }} </p> -->
<input type="text" v-model="firstName">
<input type="text" v-model="lastName">
</div>
</template>
var vm = new Vue({
el: '#demo',
data: {
firstName: 'zhang',
lastName: 'san'
},
computed: {
fullName: function () {
console.log('computed getter...')
return this.firstName + ' ' + this.lastName
}
},
updated () {
console.log('updated')
}
})
就算我们更改了firstName以及lastName都不会触发computed 中的 getter 中的console.log(‘computed getter…’),而只会触发console.log(‘updated’)
计算属性setter
<template>
<div id="demo">
<p> {{ fullName }} </p>
<input type="text" v-model="fullName">
<input type="text" v-model="firstName">
<input type="text" v-model="lastName">
</div>
</template>
var vm = new Vue({
el: '#demo',
data: {
firstName: 'zhang',
lastName: 'san'
},
computed: {
fullName: {
//getter 方法
get(){
console.log('computed getter...')
return this.firstName + ' ' + this.lastName
},
//setter 方法
set(newValue){
console.log('computed setter...')
var names = newValue.split(' ')
this.firstName = names[0]
this.lastName = names[names.length - 1]
return this.firstName + ' ' + this.lastName
}
}
},
updated () {
console.log('updated')
}
})
在template 中,我们可以看到,input 是直接绑 v-model=“fullName”,如果我们这里直接修改了fullName的值,那么就会触发setter,同时也会触发getter以及updated函数。其执行顺序是setter -> getter -> updated,如下:
console.log('computed setter...')
console.log('computed getter...')
console.log('updated')
这里需要注意的是,并不是触发了setter也就会触发getter,他们两个是相互独立的。我们这里修改了fullName会触发getter是因为setter函数里有改变firstName 和 lastName 值的代码。也就是说我们如果注释掉上边的setter中修改firstName 和lastName的代码后就不会执行getter,如下:
set(newValue){
console.log('computed setter...')
// var names = newValue.split(' ')
// this.firstName = names[0]
// this.lastName = names[names.length - 1]
return this.firstName + ' ' + this.lastName
}
会执行,且顺序如下
console.log('computed setter...')
console.log('updated')