欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

Vue核心知识——computed和watch的细节全面分析

程序员文章站 2022-03-23 13:39:37
computed和watch的区别 computed特性 1.是计算值,2.应用:就是简化tempalte里面{{}}计算和处理props或$emit的传值,computed(数据联动)。3.具有缓存性,页面重新渲染值不变化,计算属性会立即返回之前的计算结果,而不必再次执行函数 watch特性 1. ......

computed和watch的区别

computed特性

1.是计算值,
2.应用:就是简化tempalte里面{{}}计算和处理props或$emit的传值,computed(数据联动)。
3.具有缓存性,页面重新渲染值不变化,计算属性会立即返回之前的计算结果,而不必再次执行函数

watch特性

1.是观察的动作,
2.应用:监听props,$emit或本组件的值执行异步操作,watch(异步场景)。
3.无缓存性,页面重新渲染时值不变化也会执行

注:watch:一般监听单个变量或者一个数组或对象,computed: 监听在同一个实例里的很多个变量。

watch 并不适用于显示某一个数据以及数据的拼装等。watch 用在监听数据变化,做某些指令操作(给后台发数据请求)

一、computed

定义:是一个计算属性,类似于过滤器,对绑定到view的数据进行处理

实现进行简单的字符串拼接

1.不适用computed的用法

new vue({
  el: '#app',
  template:"<p>{{firstname +' '+ lastname}}</p>",
  data: {
    firstname: 'lucas',
    lastname: 'root'
  },
})
/*lucas root*/

2.使用computed

new vue({
  el: '#app',
  template:"<p>{{fullname}}</p>",
  data: {
    firstname: 'lucas',
    lastname: 'root'
  },
  computed:{
    fullname(){
        return `${this.firstname} ${this.lastname}`;
    }
  }
})

3.使用methods方法

methods方法实现和computed相同拼接

let vm = new vue({
  el: '#app',
  template:`
    <div>
        <p>computed:{{fullname}}</p>
        <p>methods:{{names()}}</p>
    </div>
  `,
  data: {
    firstname: 'lucas',
    lastname: 'root'
  },
  computed:{
    fullname(){
        return `${this.firstname} ${this.lastname}`;
    }
  },
  methods:{
    names() {
        return `${this.firstname} ${this.lastname}`;
    }
  }
})
/*
computed:lucas root

methods:lucas root
*/

computed属性fullname不可在data里定义,否则会报错。

4.使用computed的好处

当我们改变data变量值时,整个应用会重新渲染,vue 会被数据重新渲染到 dom 中。这时,如果我们使用 names方法,随着渲染,方法也会被调用,而 computed 不会重新进行计算,从而性能开销比较小。当新的值需要大量计算才能得到,缓存的意义就非常大。
如果 computed 所依赖的数据发生改变时,计算属性才会重新计算,并进行缓存;当改变其他数据时,computed 属性 并不会重新计算,从而提升性能。
当我们拿到的值需要进行一定处理使用时,就可以使用 computed。

5.computed的get与set用法

let vm = new vue({
  el: '#app',
  template:`
    <div>
        <p>computed:{{fullname}}</p>
    </div>
  `,
  data: {
    firstname: 'lucas',
    lastname: 'root'
  },
  computed:{
    fullname:{      /*若使用方法写法fullname()会报错,需使用属性写法*/
        get() {  //回调函数 当需要读取当前属性值是执行,根据相关数据计算并返回当前属性的值
           return `${this.firstname} ${this.lastname}`;
        },
        set(val) {  //监视当前属性值的变化,当属性值发生变化时执行,更新相关的属性数据,val就是fullname的最新属性值
        const names = val.split(' ');
        console.log(names);
        this.firstname = names[0];
        this.lastname = names[1];
        }
    }
  },
})
vm.fullname="hello world"; //也可以在浏览器控制台修改输出
/*
    computed:hello world
*/

 

二、watch

定义:watch是一个观察的动作,例如,监听 firstname 数据,并根据改变得到的新值,进行某些操作。

2.1示例

let vm = new vue({
  el: '#app',
  template:`
    <div>
        <p>computed:{{fullname}}</p>
    </div>
  `,
  data: {
    firstname: 'lucas',
    lastname: 'root',
    fullname:'names',
  },
  watch:{
    firstname (newname1,oldname1){
        console.log('this firstname newname '+newname1);
        console.log('this firstname oldname '+oldname1);
       this.fullname = newname1 + ' ' + this.lastname;
    },
  },
})

// vm.firstname="hello";
/*
   this firstname newname hello
   this firstname oldname lucas
*/


上面是监听firstname和lastname的变化,但是仅限简单数据类型

:watch:一般监听单个变量或者一个数组,computed: 监听在同一个实例里的很多个变量。

2.2监听简单数据类型

data(){
      return{
        'first':2
      }
    },
    watch:{
      first(){
        console.log(this.first)
      }
    },

2.3 监听复杂数据类型

1.深度监听deep

不使用 deep 时,当我们改变 obj.a 的值时,watch不能监听到数据变化,默认情况下,handler 只监听属性引用的变化,也就是只监听了一层,但改对象内部的属性是监听不到的。

let vm = new vue({
  el:'#app',
  template: `
    <div>
      <p>obj.a: <input type="text" v-model="obj.a"/></p>
    </div>
  `,
  data: {
    obj: {
      a: '123'
    }
  },
  watch: {
    obj: {
      handler () {
        console.log('obj.a changed')
      },
      // immediate: true
      deep: true
    }
  }
})

immerdiate 属性:通过声明 immediate 选项为 true,可以立即执行一次 handler。

通过使用 deep: true 进行深入观察,这时,我们监听 obj,会把 obj 下面的属性层层遍历,都加上监听事件,这样做,性能开销也会变大,只要修改 obj 中任意属性值,都会触发 handler,那么如何优化性能呢?请看下面2.4监听对象单个属性

watch: {
    'obj.a': {  //监听对象单个属性a
      handler () {
        console.log('obj.a changed')
      },
      immediate: true    //该属性会先执行一次handler
      // deep: true
    }
  }

 

2.4监听对象单个属性

方法一:可以直接对用对象.属性的方法拿到属性

 let vm=new vue({
        el:'#app',
        template: `
        <div>
          <p>obj.number: <input type="text" v-model="first.number"/></p>
        </div>
        `,
        data(){
          return{
            first:{
              number:5,
            }
          }
        },
        watch:{
          'first.number':function(newval,oldval){  //监听单个属性number
            console.log(newval,oldval);
          }
        },
    })

vm.$watch的深度监听