computed与watch的区别

一、computed与watch

在之前的练习中本人碰到computed来监听某个数据变化。我们都知道computed与watch都是可以监听数据变化,但具体要怎么区别它们呢?

1.1 watch

1.1.1 watch的简单执行

<template>
  <div class="stylebg">
    <div class="mt22">
      watch的运用
    </div>
    <div>
      姓:<el-input v-model="firstName"></el-input>
    </div>
    <div>
      名:<el-input v-model="secondName"></el-input>
    </div>
    <div>
      {{fullName}}
    </div>
  </div>
</template>

<script>
export default {
  data(){
    return{
      firstName:'1',
      secondName:'2',
      fullName:''
    }
  },
  watch:{
     firstName(fValue){
       console.log('执行了watch')
       this.fullName = fValue + this.secondName
     },
    secondName(sValue){
      this.fullName = this.firstName + sValue
    },
  }
}
</script>

<style scoped>
  .mt22{
    margin:22px 0;
  }
</style>

运行截图
在这里插入图片描述

1.2.1 watch的特点

根据上述代码我们可以总结出watch以下5种特点:

  1. 监听一个数据,一个属性影响多个属性
  2. 不使用return返回
  3. 第一次加载不会监听watch里的属性名
  4. 支持异步操作,既可以监听到异步
  5. 不支持缓存

1.3.1 watch的首次加载

从上述1.2的代码运行中,可以得出我们第一次加载页面的时候,watch是不会监听watch里的属性名,那么有没有一种方法是可以接触这种限制呢?在1.3.1会进一步的说明

1.3.1.1 watch如何实现首次加载

我们把1.2的代码进一步地改进,需要在属性名里面定义immediate:true的相关属性,再把需要所赋的最新值,写入内部属性的方法handler( )中,即可在第一次加载监听watch的某个属性名。

<template>
  <div class="stylebg">
    <div class="mt22">
      watch的运用
    </div>
    <div>
      姓:<el-input v-model="firstName"></el-input>
    </div>
    <div>
      名:<el-input v-model="secondName"></el-input>
    </div>
    <div>
      {{fullName}}
    </div>
  </div>
</template>

<script>
export default {
  data(){
    return{
      firstName:'1',
      secondName:'2',
      fullName:'',
    }
  },
  watch:{
    firstName: {
        // 监听数据
      handler(fValue) {
          console.log('执行了watch')
          this.fullName = fValue + this.secondName
      },
      deep: true, // 深度监听
      immediate:true, //当 watch 一个变量的时候,初始化时并不会执行你需要在created的时候手动调用一次。添加immediate属性,这样初始化的时候也会触发
    },

    secondName(sValue){
      this.fullName = this.firstName + sValue
    }
  }

}
</script>

<style scoped>
  .mt22{
    margin:22px 0;
  }
</style>

运行截图
在这里插入图片描述

从运行截图中我们可以看出首次加载页面的时候会执行firstName属性名中的内部代码(从控制台打印出‘执行了watch’的字符串以及界面显示了fullname的字符串可以看出)

2.1 computed

2.1.1 computed的简单运行

<template>
  <div class="stylebg">
    <div class="mt22">
      computed的运用
    </div>
    <div>
      姓:<el-input v-model="firstName2"></el-input>
    </div>
    <div>
      名:<el-input v-model="secondName2"></el-input>
    </div>
    <div>
      {{fullName2}}
    </div>
  </div>
</template>

<script>
export default {
  data(){
    return{
      firstName2:'1',
      secondName2:'2',
      // fullName2:''
    }
  },
  computed:{
    fullName2(){
      console.log('执行了computed')
      return this.firstName2 + this.secondName2
    }
  },
}
</script>

<style scoped>
  .mt22{
    margin:22px 0;
  }
</style>

运行截图
在这里插入图片描述

2.2.1 computed的特点

根据上述代码我们可以总结出computed以下5种特点:

  1. 监听多个数据,多个属性影响一个属性
  2. 必须使用return返回
  3. 第一次加载会监听computed里的属性名
  4. 无法支持异步操作,既不能监听到异步操作里面的数据变化
  5. 支持缓存,可以避免每次取值时需要重新计算。

2.2.2 computed中设置属性名问题

在编写代码中遇到一个问题,因为computed在运行时是会return把计算的数值直接返回到变量fullName2中,而在data中又同时有fullName2的空字符串,执行代码的时候会发生错误,那么为什么会发生这种错误呢?主要是牵扯到属性名重命名的问题。

2.2.2.1 为什么在data与compted中的属性不能重定义,会报错?

在执行把数据挂在vm实例中会参考下述的vue源码

 	function initState (vm) {
       vm._watchers = [];
       var opts = vm.$options;
       if (opts.props) { initProps(vm, opts.props); }
       if (opts.methods) { initMethods(vm, opts.methods); }
       if (opts.data) {
         initData(vm);
       } else {
         observe(vm._data = {}, true /* asRootData */);
       }
       if (opts.computed) { initComputed(vm, opts.computed); }
       if (opts.watch && opts.watch !== nativeWatch) {
         initWatch(vm, opts.watch);
       }
     }

可以看出上述,代码会把props等通过方法挂载在vm实例上面,执行顺序为props→methods→data→computed→watch。所以若属性名相同的话,后面的值会把前面的值覆盖。在实际运行中会直接抛出属性名重命名的错误。
在书写代码需要避免属性名重复书写。

二、computed与watch的区别

在经过第一章computed与watch的运行介绍,可以列出它们的区别:

watchcomputed
监听一个数据,一个属性影响多个属性监听多个数据,多个属性影响一个属性
不使用return返回必须使用return返回
第一次加载不会监听watch里的属性名(未设置immediate:true情况下)第一次加载会监听computed里的属性名
支持异步操作,既可以监听到异步无法支持异步操作,既不能监听到异步操作里面的数据变化
不支持缓存支持缓存,可以避免每次取值时需要重新计算。

三、computed与watch一般会使用到的场景

watch: 如需要执行异步操作或者开销比较大的场景,搜索框输入一个字符串会调用API去动态获取相应的数据列表。
computed: 如购物车勾选多件商品,此时勾选每件商品的价钱属性影响总价的属性。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值