前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Vue专题 01_计算属性vs监听(侦听)属性

Vue专题 01_计算属性vs监听(侦听)属性

作者头像
用户9999906
发布2022-09-26 11:33:12
4730
发布2022-09-26 11:33:12
举报
文章被收录于专栏:学编程的GISer

对于初学者来说,学到计算属性和监听(侦听)属性这里很容易犯晕,搞不懂这两者之前的区别和什么时候该使用哪个,这里Dapan就来尝试梳理一下计算属性(computed)和监视(侦听)属性(watch)的区别,以及该选择使用哪一个:

1. 能用computed实现的尽量用computed实现:

假如现在我们要实现一个自动组成人的全名(fullName)的小案例,如下:

看看用watch和computed分别如何实现该功能:

用watch实现:

代码语言:javascript
复制
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>watch和computed(watch实现)</title>
    <script src="./js/vue.js"></script>
  </head>
  <body>
    <div id="root">
      firstName:<input type="text" v-model="firstName" /><br />
      lastName:<input type="text" v-model="lastName" /><br />
      fullName:
      <h3>{{fullName}}</h3>
    </div>
    <script>
      const vm = new Vue({
        el: '#root',
        data: {
          firstName: '张',
          lastName: '三',
          fullName: '',
        },
        watch: {
          firstName(newValue) {
            this.fullName = newValue + '-' + this.lastName;
          },
          lastName(newValue) {
            this.fullName = this.firstName + '-' + newValue;
          },
        },
      });
    </script>
  </body>
</html>

用watch实现的代码时命令式的,且是重复的。什么是命令式的呢?简单来说就是这里要Vue亲自监视firstName和lastName的变化。

补充:命令式编程:命令“机器”如何去做事情 (how),这样不管你想要的是什么 (what),它都会按照你的命令实现。

用computed实现:

代码语言:javascript
复制
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>watch和computed(computed实现)</title>
    <script src="./js/vue.js"></script>
  </head>
  <body>
    <div id="root">
      firstName:<input type="text" v-model="firstName" /><br />
      lastName:<input type="text" v-model="lastName" /><br />
      fullName:
      <h3>{{fullName}}</h3>
    </div>
    <script>
      const vm = new Vue({
        el: '#root',
        data: {
          firstName: '张',
          lastName: '三',
        },
        computed: {
          fullName() {
            return this.firstName + '-' + this.lastName;
          },
        },
      });
    </script>
  </body>
</html>

显而易见, 用computed实现是声明式的,且比用watch实现会更简单易于理解一点。

补充:声明式编程:告诉“机器”你想要的是什么 (what),让机器想出如何去做 (how)。

2. computed能完成的功能,watch都可以完成。watch能完成的功能,computed不一定能完成,例如:watch可以进行异步操作。

假如现在在实现刚刚那个功能的基础上再加一个功能,在firstName修改两秒钟之后,fullName再修改:

看看watch怎么实现该功能:

代码语言:javascript
复制
watch: {
  firstName(newValue) {
    //  setTimeout:
    setTimeout(() => {
      this.fullName = newValue + '-' + this.lastName;
    }, 2000);
  },
  lastName(newValue) {
    this.fullName = this.firstName + '-' + newValue;
  },
},

用了一个很简单的setTimeout就实现了,再来看看computed能不能实现:

代码语言:javascript
复制
computed: {
  fullName() {
    setTimeout(()=>{
      return this.firstName + '-' + this.lastName;
    },2000)
  },
},

打开live Server发现并没有实现该功能,是因为computed不支持异步操作(这里的返回值交给的是setTimeout,计算属性computed并没有拿到返回值,此时computed的返回值是undefined,计算属性是靠返回值拿数据,而我们办不到让计算属性等一等再有返回值,故计算属性不能开启异步任务去维护数据。),而watch支持异步,因为watch不是靠返回值,而是靠你亲自写的代码去修改。

小结:当需要在数据变化时执行异步或开销较大的操作时使用watch,但计算属性在大多数情况下更合适。

3. computed有缓存,watch没有缓存

computed的缓存机制:

代码语言:javascript
复制
<div id="root">
  姓:<input type="text" v-model="firstName" /><br />
  名:<input type="text" v-model="lastName" /><br />
  姓名:
  <h3>{{fullName}}</h3><br>
  姓名:
  <h3>{{fullName}}</h3><br>
  姓名:
  <h3>{{fullName}}</h3><br>
  姓名:
  <h3>{{fullName}}</h3>
</div>
<script>
  const vm = new Vue({
    el: '#root',
    data: {
      firstName: '张',
      lastName: '三',
    },
    computed: {
      fullName() {
        return this.firstName + '-' + this.lastName;
      },
    },
  });
</script>

这里在页面上显示了四次fullName,但是由于computed的缓存机制,计算属性只被调用了一次,其他三次的fullName是上次缓存下来的值,也就是说计算属性会直接从缓存拿值,只有当计算属性所依赖的数据发生改变时才会重新执行计算属性:

而watch并没有缓存机制。

4. 初次执行时间不同

计算属性是代码刚开始还没有有数据改变的时候就执行一次,而watch是当监视的属性发生变化时才会执行,除非配置immediate:true:

  • watch:
代码语言:javascript
复制
<div id="root">
firstName:<input type="text" v-model="firstName" /><br />
lastName:<input type="text" v-model="lastName" /><br />
fullName:
 <h3>{{fullName}}</h3>
</div>
<script>
 const vm = new Vue({
   el: '#root',
   data: {
     firstName: '张',
     lastName: '三',
     fullName: '',
  },
   watch: {
     firstName(newValue) {
         this.fullName = newValue + '-' + this.lastName;
    },
     lastName(newValue) {
       this.fullName = this.firstName + '-' + newValue;
    },
  },
});
</script>

打开live Server,fullName并没有立即显示在页面上:

代码语言:javascript
复制
<div id="root">
姓:<input type="text" v-model="firstName" /><br />
名:<input type="text" v-model="lastName" /><br />
姓名:<h3>{{fullName}}</h3>
</div>
<script>
 const vm = new Vue({
   el: '#root',
   data: {
     firstName: '张',
     lastName: '三',
  },
   computed: {
     fullName() {
       return this.firstName + '-' + this.lastName;
    },
  },
});
</script>

fullName已经显示在了页面上:

但是当我在watch上加了immediate:true之后:

代码语言:javascript
复制
<div id="root">
  firstName:<input type="text" v-model="firstName" /><br />
  lastName:<input type="text" v-model="lastName" /><br />
  fullName:
  <h3>{{fullName}}</h3>
</div>
<script>
  const vm = new Vue({
    el: '#root',
    data: {
      firstName: '张',
      lastName: '三',
      fullName: '',
    },
    watch: {
      firstName: {
        immediate: true, //watch会立即执行
        handler(newValue) {
          this.fullName = newValue + '-' + this.lastName;
        },
      },
      lastName: {
        immediate: true, //watch会立即执行
        handler(newValue) {
          this.fullName = this.firstName + '-' + newValue;
        },
      },
    },
  });
</script>

watch会立即执行:

5. 是否必须是data中存在的数据

watch监听的必须是data中已经存在的数据,而computed是计算得出来的数据,并且挂载到了vm身上。

6. 是否有return

计算属性必须有return,而监听属性没有return

7. 是否能拿到新旧数据

watch可以拿到新旧数据,而computed拿不到旧数据

代码语言:javascript
复制
watch:{
     监听的属性名(newValue,oldValue){
        console.log(newValue,oldValue)
     }
}

总结

  1. 一般能用computed就用computed,因为它有缓存,会提高运行速度
  2. watch是对data上面的一些数据进行观察和响应,一般的时候使用计算属性替代watch,因为滥用watch的话,会影响性能。但是watch有它自己的使用场景,别人不能替代。当需要在数据变化时执行异步或开销较大的操作时 (js里面学过的异步任务:定时器 + ajax + dom事件)需要使用watch。
  3. 计算属性是将return之后的结果作为一个属性挂载到vm身上,并且命名为计算属性的名字,比如一个计算属性:fullName(){retrun this.filstName + this.lastName}的就是将return的值赋值给fullName,并将这个fullName挂载到vm上,作为vm的一个属性(类似于data中的属性)。而监听属性是监听data中某一属性发生改变时,要进行的一些列操作。

以上知识只是Dapan的个人总结,有什么错误的地方欢迎大家批评指正。转载的话请在后台告知Dapan哦,谢谢!

关注公众号: 学编程的GISer,大家一起学习进步!

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2022-03-01,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 学编程的GISer 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 2. computed能完成的功能,watch都可以完成。watch能完成的功能,computed不一定能完成,例如:watch可以进行异步操作。
  • 3. computed有缓存,watch没有缓存
  • 4. 初次执行时间不同
  • 5. 是否必须是data中存在的数据
  • 6. 是否有return
  • 7. 是否能拿到新旧数据
  • 总结
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档