method和computed都是我们在vue项目中很常用的两个属性,相信大家对method不是很陌生但对computed却是了解的不多(至少我是这样的),今天刚好和同事聊到这个,所以本篇文章主要来讲讲compued这个属性,小伙伴们可以进行参考学习。
computed定义
计算属性可用于快速计算视图(View)中显示的属性。这些计算将被缓存,并且只在需要时更新。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'
},
computed: {
// 计算属性的 getter
reversedMessage: function () {
// `this` 指向 vm 实例
return this.message.split('').reverse().join('')
}
}
})
在这里相信大家会发现,这个computed和method的功能一样,也是一个函数;对的,我们用method也可以实现这种效果。例如:
<div id="example">
<p>Computed reversed message: "{{ reversedMessage() }}"</p>
/* 直接对函数进行调用*/
</div>
var vm = new Vue({
el: '#example',
data: {
message: 'Hello'
},
methods: {
reversedMessage: function () {
return this.message.split('').reverse().join('')
}
}
})
可以看到二者的效果是一样的,但是其实二者还是有区别的
computed和method的区别
computed具有响应式(双向数据绑定),以属性方式调用,如:this.reversedMessage
methods需以函数方式调用,如:this.reversedMessage()
-
computed具有缓存功能,只要里面的数据不发生改变,就不会重新计算;methods每次调用都重新计算一次,也就是说使用了computed只有它们计算依赖的值发生变化的时候才会进行重新计算,这样大大提高了性能。相比之下,每当触发重新渲染时,method将总会再次执行函数。
这里要注意的一点是,Date.now()将会在执行一次以后失去作用
computed: { now: function () { return Date.now() } }
computed的触发变化条件
- 触发条件是内部计算的数据发生改变
- 内部的数据必须是响应式的数据,普通数据vue无法知道是否有变化
例子1:
<template>
<div @click="change">{{b}}</div>
</template><script>
let a = {value: 1};
export default {
computed: {
b() {
return a.value;
}
},
methods: {
change() {
a.value = 2;
}
},
}
</script>
在点击之后会返回什么值?
答案:点击前是1,点击后也是1
原因很简单,a不是一个响应式的值,没有被vue劫持,所有数据改变时vue并不知道,所已没有触发b的更新
例子2:
<template>
<div @click="change">{{b}}</div>
</template>
<script>
export default {
data() {
return {
a: {value: 1}
}
},
computed: {
b() {
return this.a.value;
}
},
methods: {
change() {
this.a.value = 2;
}
},
}
</script>
答案:点击后,触发了change,把a.value改为2,因为a是在data函数里,data函数里的数据是被vue劫持的,具有响应式,所以会触发计算属性b的更新。
computed的settter
在computed属性中同样为我们提供了setter-getter方法
/*来自官方文档的例子*/
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]
}
}
}
简单理解就是:
setter():用来设置成员变量,可以在方法里面过滤掉一些不合理的值
- 必须是对象方法
- 返回值类型为void
- 方法名以set开头
- 必须提供一个参数,参数类型必须与所对应的成员变量的类型一致
getter():为调用者返回对象内部的成员变量的值
- 必须是对象方法
- 必须有返回值,返回值的类型和成员变量的类型一致
- 方法名必须是成员变量去掉下划线
- 一定是没有参数的
例子:
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]
}
}
}
可以看到getter只是对原本值的处理后返回;而setter则会重新设置值
总结:
- computed用来监控自己定义的变量,该变量不在data里面声明,直接在computed里面定义,然后就可以在页面上进行双向数据绑定展示出结果或者用作其他处理;
- computed比较适合对多个变量或者对象进行处理后返回一个结果值,也就是数多个变量中的某一个值发生了变化则我们监控的这个值也就会发生变化,举例:购物车里面的商品列表和总金额之间的关系,只要商品列表里面的商品数量发生变化,或减少或增多或删除商品,总金额都应该发生变化。这里的这个总金额使用computed属性来进行计算是最好的选择