computed 2
computed通过this.message调用vue里data中的message值后乘以2(this 指向 app 实例), getMessage方法renturn的结果,在模版引擎中通过{{getMessage}}调用显示
在这里,getMessage函数被声明成app的一个getMessage属性,在控制台输出
app.getMessage
得到的结果是2,在控制台中我们输入
app.message = 2
consoe.log(app.getMessage) //4
computed里的getMessage的值受app.message影响
computed和methods对比
以上计算属性,在methods中同样可以实现;
<div id="app">
{{message}}
<div>methods {{getMessage()}}</div>
</div>
var app = new Vue({
el: '#app',
data: {
message: 1,
methods: {
getMessage: function(){
return this.message * 2;
同样浏览器显示结果为
methods 2
既然得到的结果都一样,那么这两个到底有什么区别呢,为什么要使用 computed
?
带着这个疑惑,我们去详细分析。
计算属性是基于它们的响应式依赖进行缓存的
也就是说在computed中,getMessage的值是根据data中的message去相应变化的,如果在getMessage没有去调用data中的message,那么getMessage将不会再计算,官方🌰
computed: {
now: function () {
return Date.now()
无论我们调用now多少次,始终都是第一次计算的时间,因为Date.now()是不基于响应式的,我们将官网的例子改一下
computed: {
now: function () {
console.log(this.message);
return Date.now()
不加任何返回只是打印了message,我们在浏览器控制台对 app.message做更改,
app.message = 2
这时,发现了now的值也进行的更新,这说明只要在computed中添加message的内容,就和computed建立了响应式关系,当app.message更新时,now也会进行更新,对应的缓存方法now也进行了更新。为了进行减少性能的开销,避免重复调用getter方法,我们尽量使用computed缓存,如果不需要缓存,直接在methods使用方法就好了。
computed和watch
vue中提供watch来监听vue实例的属性变化,那么它和computed有什么不同呢?
首先我们先看一个例子
var app = new Vue({
el: '#app',
data: {
firstName: {
a: 'Foo'
lastName: 'Bar',
fullName: 'Foo Bar'
computed: {
first(){
return this.firstName;
full(){
return this.firstName.a +' '+this.lastName
watch: {
firstName: function (val) {
this.fullName = val.a + ' ' + this.lastName
lastName: function (val) {
this.fullName = this.firstName.a + ' ' + val
分别定义了watch和computed,data里定义了firstName
lastName
fullName
,注意,这里的firstName是一个对象,包含子属性a
,
<div id="app">
<div>data.firestName - firstName {{firstName.a}}</div>
<div>watch - fullName {{fullName}}</div>
<div>computed - {{first.a}}</div>
<div>computed - {{full}}</div>
</div>
默认浏览器显示
data.firestName - firstName Foo
watch - fullName Foo Bar
computed - Foo
computed - Foo Bar
此时,我们在浏览器控制台输入app.firstName.a ='hello'
,得到结果如下:
data.firestName - firstName hello
watch - fullName Foo Bar
computed - hello
computed - hello Bar
我们发现watch中监控的firstNam并没有起到作用,fullname值并没有更新,难道watch不能使用?这时我又尝试在浏览器输入app.lastName = 'word'
,得到结果却更新了:
data.firestName - firstName hello
watch - fullName hello word
computed - hello
computed - hello word
computed和watch对比结论
1. watch不能对对象属性深层次的监听,watch如果需要实现深度监听,需要添加选项deep:true(默认是false)
2. watch可以不return,可以直接设置data值,computed需要return去调用值
3. computed默认只有getter方法,如果需要对computed进行赋值,需要我们自己去定义setter方法,否则浏览器会报错
4. watch还可以根据某个属性变化去执行异步操作,调用其他库的方法,这种在computed中是无法实现
computed setter定义的方式(这里直接抄官网的例子了)
computed: {
fullName: {
get: function () {
return this.firstName + ' ' + this.lastName
set: function (newValue) {
var names = newValue.split(' ')
this.firstName = names[0]
this.lastName = names[names.length - 1]
复制代码