前端 · 2021年1月23日 0

Vue中computed和watch的区别

这两个东西在官方文档中叫 计算属性侦听器
官网链接

1. 计算属性 computed

当一个值需要一些复杂的计算或者拼接,用 计算属性 就不需要在页面中处理了,而是直接v-model引用了。

引用官网一句话:对于任何复杂逻辑,你都应当使用计算属性

下面这个案例就是简单的 firstname + lastname,在这里我们理解为是一次对属性fullname的拼接,如果在模板中如此操作,就会较难处理。所以用上计算属性

<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8">
    <title></title>
    <script src="lib/vue.min.js"></script>
    <script src="lib/vue-router-3.0.1.js"></script>
  </head>
  <body>
    <div id="app">
      <input type="text" v-model="firstname" />
      <input type="text" v-model="lastname" />
      <input type="text" v-model="fullname" />
    </div>
    <script type="text/javascript">
      var vm = new Vue({
        el:"#app",
        data:{
          firstname:"",
          lastname:""
        },
        methods:{},
/*       watch:{
          firstname:function(newValue,OldValue){
            console.log(newValue);
            console.log(OldValue);
          }
        }*/
        computed:{
          fullname:function(){
            return this.firstname +"-"+this.lastname
          }
        }
      })
    </script>
  </body>
</html>

2. 监听器 watch

watch属性可以用来监听data属性中数据的变化

官网这样说:Vue 提供了一种更通用的方式来观察和响应 Vue 实例上的数据变动:侦听属性。

案例:在监听的function中使用参数来获取新值与旧值

输入框内的值变化多少次,控制台就会打印多少次

<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8">
    <title></title>
    <script src="lib/vue.min.js"></script>
    <script src="lib/vue-router-3.0.1.js"></script>
  </head>
  <body>
    <div id="app">
      <input type="text" v-model="firstname" />
    </div>
    <script type="text/javascript">
      var vm = new Vue({
        el:"#app",
        data:{
          firstname:"",
          lastname:""
        },
        methods:{},
        watch:{
          firstname:function(){
            console.log(this.firstname)
          }
        }
      })
    </script>
  </body>
</html>

3. 计算属性computed vs 侦听属性watch(勿滥用)

Vue 提供了一种更通用的方式来观察和响应 Vue 实例上的数据变动:侦听属性。
当你有一些数据需要随着其它数据变动而变动时,
很容易滥用 watch。
然而,通常更好的做法是使用计算属性computed而不是命令式的 watch 回调。

这个例子:

<div id="demo">{{ fullName }}</div>
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
    }
  }
})

上面代码是命令式且重复的,因为要重复监听firstName与lastName。
将它调整与计算属性computed的版本进行比较:

var vm = new Vue({
  el: '#demo',
  data: {
    firstName: 'Foo',
    lastName: 'Bar'
  },
  computed: {
    fullName: function () {
      return this.firstName + ' ' + this.lastName
    }
  }
})

简单多了吧~

4. 区别

4.1 调用区别

  • watch中的函数是不需要调用的
  • computed内部的函数调用的时候不需要加()

4.2 监听区别

  • watch 属性监听 监听属性的变化
  • computed:计算属性通过属性计算而得来的属性

4.3 性能区别

  • watch需要在数据变化时执行异步或开销较大的操作时使用

    对于任何复杂逻辑或一个数据属性在它所依赖的属性发生变化时,也要发生变化,这种情况下,我们最好使用计算属性computed。

  • computed 属性的结果会被缓存,除非依赖的响应式属性变化才会重新计算。主要当作属性来使用;

    响应式依赖缓存:只要 Value值 还没有发生改变,多次访问 computed值,都会立即返回之前的计算结果,而不必再次执行函数

4.4 函数区别

  • computed中的函数必须用return返回最终的结果
    > 当computed中的函数所依赖的属性如果没有发生改变的时候,那么调用当前函数的时候结果会从缓存中读取
  • watch 一个对象,键是需要观察的表达式,值是对应回调函数。主要用来监听某些特定数据的变化,从而进行某些具体的业务逻辑操作;

5. 使用场景

  • computed
        当一个属性受多个属性影响的时候就需要用到computed
        最典型的例子: 购物车商品结算的时候
  • watch
        当一条数据影响多条数据的时候就需要用watch
        搜索数据