zoukankan      html  css  js  c++  java
  • Vue 侦听器 watch 扩展之立即触发回调、深度监听和注销

    一、立即触发回调

    watch 最初绑定时是不会执行的,需要等监听的内容改变时才执行监听计算

    那我们想要一开始绑定的时候就执行该怎么办呢?

    可以修改一下 watch 写法,如下:

    watch: {
      firstName: {
        handler(newName, oldName) {
          this.fullName = newName + ' ' + this.lastName;
        },
        { immediate: true }
      }
    }

    上述写法用到了 handler 方法和 immediate 属性

    1、handler 方法

    原来我们 watch 中默认写的就是这个 handler,Vue 会去处理这个逻辑,最终编译出来其实就是这个 handler

    2、immediate 属性

    指定 immediate: true 将立即以表达式的当前值触发回调,即在 wacth 中声明了 firstName 之后就会立即执行里面的 handler 方法,如果为 false 就跟原来的效果一样,不会在绑定的时候就执行

    二、深度监听

    受 JavaScript 的限制,Vue 无法检测到对象属性的变化

    例如,在下面的输入框中输入数据改变 obj.a 的值是无效的

    <div>
          <input type="text" v-model="obj.a">
    </div>
     
    new Vue({
      el: '#root',
      data: {
        obj: {
          a: 123
        }
      },
      watch: {
        obj: {
          handler(newVal, oldVal) {
             console.log('obj.a changed');
          },
          { immediate: true }
        }
      } 
    })

    默认情况下 handler 只监听 obj 这个属性的引用的变化,只有给 obj 赋值时它才会被监听到

    如果我们需要监听 obj 的属性 a 该怎么做呢?这时候就需要用到 deep 属性了

    1、deep 属性

    watch 中有一个属性 deep,默认值为 false,表示是否进行深度监听

    watch: {
      obj: {
        handler(newVal, oldVal) {
          console.log('obj.a changed');
        },
        {
          immediate: true,
          deep: true
        }
      }
    } 

    设置 deep 为 true 后,监听器会一层层的往下遍历,给对象的所有属性都加上这个监听器,这样就可以监听到属性 a 了

    但这样性能消耗会非常大,只要修改 obj 中任一属性都会触发这个监听器里的 handler,因此我们可以使用字符串形式监听来进行优化:

    watch: {
      'obj.a': {
        handler(newVal, oldVal) {
          console.log('obj.a changed');
        },
        {
          immediate: true
          // deep: true
        }
      }
    } 

    这样 Vue 会一层层解析下去,直到遇到属性 a,然后才给 a 设置监听函数

    三、注销

    1、unwatch 方法

    const unwatch = app.$watch('text', (newVal, oldVal) => {
      console.log('text changed');
    })
     
    unwatch();  // 手动注销 watch

    注意在带有 immediate 选项时,不能在第一次回调时取消侦听给定的 property

    // 这会导致报错
    var unwatch = vm.$watch(
      'value',
      function () {
        doSomething()
        unwatch()
      },
      { immediate: true }
    )

    如果仍想在回调内部调用一个取消侦听的函数,应该先检查其函数的可用性:

    var unwatch = vm.$watch(
      'value',
      function () {
        doSomething()
        if (unwatch) {
          unwatch()
        }
      },
      { immediate: true }
    )
  • 相关阅读:
    jQuery性能优化
    Google Chrome 浏览器 错误 312 (net::ERR_UNSAFE_PORT):未知错误。
    C#简单数字验证码解析
    折半查找
    平均分配算法之倒序贪婪
    字符串相似度算法(编辑距离算法 Levenshtein Distance)
    c# 冒泡排序算法中三种前后值交换算法效率测试
    二叉树的遍历
    C#使用Tesseract OCR 解析验证码
    页面瘦身之压缩viewState和保存viewState到服务器
  • 原文地址:https://www.cnblogs.com/Leophen/p/13410190.html
Copyright © 2011-2022 走看看