Vue - computed和watch的区别

computed 计算属性

计算属性 ,用来计算出一个值,这个值在调用的时候会根据依赖的数据显示新的计算结果并自动缓存。 如果依赖不变,computed中的值就不会重新计算。

什么是计算属性,为什么要使用

  • 计算属性含义: 本质还是属性,用来在模板中展示
  • 计算属性其实和data的地位相同,都是vue实例的属性,都可以在模板中使用
  • 出现的原因:一般在模板语法内使用表达式非常方便,模板也只是用于简单的运算,当表达式过于复杂时,在模板中放入太多逻辑会让模板过重且难以维护。为此,Vue提供了计算属性computed。

语法

1
2
3
4
5
6
7
computed:{
属性名:function(){
return
}
}

{{属性名}}
1
2
3
4
5
6
7
8
9
{{ msg.split("").reverse().join("") }}     // 模板过重且难以维护

{{ haha }}

computed:{
haha:function(){
return this.msg.split("").reverse().join("")
}
}

修改计算属性

  • 计算属性默认只有 getter,不可修改
  • 如果需要修改,可以提供一个 setter
1
2
3
4
5
6
7
8
9
10
11
12
13
14
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.firstNamevm.lastName 也会相应地被更新。

watch 侦听器

作用

对data里面的数据进行监听处理。

语法

一个对象,键是需要观察的表达式(data内的数据),值是对应回调函数。值也可以是方法名,或者包含选项的对象。

当数据发生改变时,会执行一个回调,它有两个参数, newVal 和 oldVal

watch 有两个属性:

  • immediate 是否在第一次渲染时执行这个函数,会在监听开始之后就立即本调用。
  • deep 是否要看这个对象里面的属性变化。

浅监听

监听基础数据类型

1
2
3
watch:{
变量名(newval,oldval){}
}

深监听

监听引用数据类型

1
2
3
4
5
6
7
watch:{
变量名:{
deep:true,
handler:function(newval){
}
}
}

computed 和 methods 的区别

  • 计算属性是基于他们的响应式依赖进行缓存的,只在相关响应式依赖发生改变时,才会重新求值(也就是说,计算属性会把数据进行缓存)
  • 而方法不会把数据进行缓存, 每次都会执行,所以用计算属性效率会更高点

所以,对于任何复杂逻辑,都应该使用计算属性

在某些情况,我们可能需要对数据进行一些转化后再显示,或者需要将多个数据结合起来进行显示

  • 比如我们有firstName和lastName两个变量,我们需要显示完整的名称。

  • 但是如果多个地方都需要显示完整的名称,我们就需要写多个

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    <body>
    <div id="app">
    <h2>{{firstName + ' ' + lastName}}</h2>
    <h2>{{firstName}} {{lastName}}</h2>
    <h2>{{getFullName()}}</h2>
    <h2>{{fullName}}</h2>

    </div>
    </body>
    <script src="../js/vue.js"></script>
    <script>
    const app = new Vue({
    el: '#app',
    data: {
    firstName: 'Lron',
    lastName: 'Man'
    },
    // 推荐使用计算属性来操作,因为它会将这些数据进行缓存, 无论打印多少次,它只会调用一次
    computed: {
    // 计算属性 注意 : 计算的是 属性,
    // 所以这里面的属性 看成一个 对象(用名词形式来表达), 调用时候不用加小括号
    fullName: function () {
    return this.firstName + ' ' + this.lastName

    }
    },
    methods: {
    // 不会缓存, 所以有多少次就调用多少次, 没有 computed 划算
    getFullName: function () {
    return this.firstName + ' ' + this.lastName
    }
    }
    })
    </script>

computed 和 watch 的区别

  • computed 是为了简化模板里面的操作,对数据处理后进行展示:由data中的已知值,得到的一个新值;

    watch目的是监听data中已知值的变化,执行响应的逻辑处理。

  • computed擅长处理的场景:一个数据受多个数据影响;

    watch擅长处理的场景:一个数据影响多个数据

如果有一些数据需要随着其它数据变动而变动时, watch就会显得非常冗余,官方文档给出了如下的示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
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
}
}
})
1
2
3
4
5
6
7
8
9
10
11
12
var vm = new Vue({
el: '#demo',
data: {
firstName: 'Foo',
lastName: 'Bar'
},
computed: {
fullName: function () {
return this.firstName + ' ' + this.lastName
}
}
})

总结

  • 如果一个数据需要经过复杂计算就用 computed

  • 如果一个数据需要在发生变化时做一些逻辑就用 watch