美文网首页
Vue核心知识——computed和watch的细节全面分析

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

作者: 为光pig | 来源:发表于2020-12-23 09:42 被阅读0次

    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方法
    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
    */
    

    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,那么如何优化性能呢?请看下面

    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的深度监听

    相关文章

      网友评论

          本文标题:Vue核心知识——computed和watch的细节全面分析

          本文链接:https://www.haomeiwen.com/subject/fhpsnktx.html