目录
一、什么是计算属性
在 Vue 应用中,在模板中双向绑定一些数据或者表达式,但是表达式如果过长,或者逻辑更
为复杂时,就会变得臃肿甚至难以维护和阅读,比如:
<div>
{{text.split(',').reverse().join(',')}}
</div>
这里表达式包含三个操作,并不是很清晰,所以在遇到复杂的逻辑时应该使用计算属性。 上
例可以用计算属性进行改写:
<div id="CalculationProperties">
{{ReversedText}}
</div>
<script>
var CalculationProperties = new Vue({
el: "#CalculationProperties",
data: {
text:"123,456",
},
computed: {
ReversedText: function ()
{
//所有计算属性都以函数的形式写在 Vue 实例内的 computed 选项内,最终返回计算后的结果
return this.text.split(',').reverse().join(',')
}
}
})
</script>
注意:所有计算属性都以函数的形式写在 Vue 实例内的 computed 选项内,最终返回计算后的结果
二、计算属性用法
在一个计算属性里可以完成各种复杂的逻辑,包括逻辑运算、函数调用等,只要最终返回一
个结果就可以。除了上面的简单的用法,计算属性还可以依赖多个 vue 实例的数据,只要其中任
意一个数据变化,计算属性就会重新执行,视图也会更新。
例如:计算购物车内两个包裹的物品总价
<div id="prices">
总价: {{prices}}
</div>
<script>
// <!--购物车总价-->
var prices = new Vue({
el: "#prices",
data: {
package1: [
{
name: "华为 mate20pro",
price: 4566,
count: 2
},
{
name: "华为 p30",
price: 4166,
count: 2
}
],
package2: [
{
name: "苹果",
price: 30,
count: 2
},
{
name: "香蕉",
price: 2,
count: 20
}
]
},
computed: {
prices: function () {
var prices = 0;
debugger
for (var i = 0; i < this.package1.length; i++) {
prices += this.package1[i].price * this.package1[i].count;
}
for (var i = 0; i < this.package2.length; i++) {
prices += this.package2[i].price * this.package2[i].count;
}
return prices;
}
}
})
</script>
当 package1 或 package2 中的商品发生变化,比如购买数量变化或者增删商品时,计算属性 prices就会自动更新,视图中的总价也会自动变化。
每个计算属性都包含一个 getter 和 setter,上面的例子都是计算属性默认用法,只是利用
了 getter 来读取。在你需要时,也可以提供一个 setter 函数,当手动修改计算属性的值就像修
改一个普通数据那样,就会触发 setter 函数,执行一些自定义的操作。
<!--setter-->
<div id="setter">
FirstName:
<input type="text" v-model = "firstName">
<br><br>
lastName:
<input type="text" v-model = "lastName">
<br><br>
姓名: {{fullName}}
</div>
<script>
var setter = new Vue({
el: "#setter",
data: {
firstName: 'Jack',
lastName:'Green'
},
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[1];
}
}
}
})
</script>
三、计算属性的使用技巧
计算属性不仅可以依赖当前 Vue 实例的数据,还可以依赖其他 Vue 实例的数据
<div id="app1">
{{ text }}
</div>
<div id="app2">
{{reversedText}}
</div>
<script>
var app1 = new Vue({
el: "#app1",
data: {
text: "123,456"
}
});
var app2 = new Vue({
el: "#app2",
computed: {
reversedText: function () {
//这里是依赖 app1 实例中的数据 text
return app1.text.split(',').reverse().join(',')
}
}
})
</script>
这里我们创建了两个 vue 实例 app1 和 app2,在 app2 的计算属性 reversedText 中,依赖
的是 app1 的数据 text,所以当 text 变化时,实例 app2 的计算属性也会变化。
四、计算属性缓存
其实细心的话就会发现,调用 methods 里的方法也能实现和计算属性一样的效果,甚至有的方法还能接收参数,使用起来更加的灵活,既然使用 methods 就可以实现,那为什么还需要计算属性呢?原因就是计算属性是基于他的依赖缓存的。一个计算属性所依赖的数据发生变化时,他才会重新取值,所以依赖的 text 只要不改变。计算属性也就不更新。
computed:{
now:function()
{
return Date.now()
}
}
这里的 Date.now()不是响应式依赖,所以计算属性 now 不会更新,但是 methods 则不同,只要重新渲染他就会被调用,因此函数也会被执行。 使用计算属性还是 methods 取决于是否需要缓存,当遍历大数组和做大量计算时,应当使用计算属性,除非不希望得到缓存。
五、Vue 侦听器
虽然计算属性在大多数情况下更合适,但有时也需要一个自定义的侦听器。
所谓 侦听器(watch),就是 当数据发生变化时,及时做出响应处理。
注意:当需要在数据变化时执行异步或开销较大的操作时,这个方式是最有用的!
1、基本使用
创建一个侦听器非常简单,只需要在 Vue 对象上挂载 watch 属性,然后监听 data 中的数据即可。
<div id="app">
<input type="text" v-model="message">
<h2>状态:{{ state }}</h2>
</div>
<script>
let vm = new Vue({
el: '#app',
data: {
message: 'Hello',
state: '【未修改】'
},
watch: {//监听属性
// 绑定监听数据
message: function (e){
// 当数据修改时做出响应(处理函数)
this.state = '【已修改】'
}
}
})
</script>
2、侦听是否 “及时” ?
假如在侦听器里更改监听数据的话,那么显示 更改前的数据,还是显示更改后的数据呢?
<div id="app">
<input type="text" v-model="message">
<h2>状态:{{ state }}</h2>
</div>
<script>
let vm = new Vue({
el: '#app',
data: {
message: 'Hello',
state: '【未修改】'
},
watch: {//监听属性
// 绑定监听数据
message: function (e){
// 当数据修改时做出响应(处理函数)
this.state = '【已修改】'
console.log(e)
}
}
})
</script>
答案是:及时
3、小结
- 同样的,监听器还可以监听数组 / 对象。
- 监听器使用不宜过多,因为会造成性能下降。
- 允许异步操作 (访问一个 API),限制我们执行该操作的频率,并在我们得到最终结果前,设置中间状态。这些都是计算属性无法做到的。