【Vue.js】侦听器 watch

1. 概述:

watch(侦听器)是 Vue 提供的一个添加依赖变化时副作用扩展的 API。

我们可以给依赖 (data, computed, props ...) 添加侦听器,当这些依赖变化的时候可以实时执行一些副作用操作(e.g 表单提交,Ajax 请求)

2. watch 和 computed 的对比

2.1. 复习 computed 计算属性

  • 关注点:模板
  • 主要用来:抽离复用模板中复杂的逻辑和运算
  • 特点: 当函数内部的依赖发生变化时, 重新计算结果调用

2.2. watch侦听器:

  • 关注点:数据更新
  • 主要用来:给数据添加更新监测 - 当数据更新时, 侦听器函数执行
  • 特点: 在数据更新时, 需要完成什么逻辑
API 名称 关注点 主要用途 特点
watch 数据更新 给数据添加更新监测 - 当数据更新时, 侦听器函数执行 在数据更新时, 需要完成什么逻辑
computed 模板 抽离复用模板中复杂的逻辑和运算,并渲染 当函数内部的依赖发生变化时, 重新计算结果调用

注意

  • watch 侦听器默认首次是不会触发的(懒执行)
  • watch 侦听器内设置的名字需要和数据的名字一致 (data, computed)
  • 使用 watch 时,应该考虑的是给一个数据发生变化添加逻辑运算/回调函数添加副作用

3. 侦听器的语法

3.1. 基本使用

js 复制代码
export default {
  data() {
    a: 1,
  },

  watch: {
    a(newValue, oldValue) {
      // ...
    }
  }
};

3.2. 用 . 分隔的路径注册侦听器

js 复制代码
export default {
	data() {
    return {
      some: {
        nested: {
          key: ''
        }
      },
    };
  },
  
  watch: {
    // 注意:只能是简单的路径,不支持表达式。
    'some.nested.key'(newValue) {
      // ...
    }
  }
};

3.3. 深层侦听器(deep)

watch 默认是浅层的:被侦听的属性,仅在被赋新值时,才会触发回调函数---而嵌套属性的变化不会触发。如果想侦听所有嵌套的变更,你需要深层侦听器:

深度侦听需要遍历被侦听对象中的所有嵌套的属性,当用于大型数据结构时,开销很大。因此请只在必要时才使用它,并且要留意性能。

js 复制代码
export default {
  watch: {
    someObject: {
      handler(newValue, oldValue) {
        // 注意:在嵌套的变更中,
        // 只要没有替换对象本身,
        // 那么这里的 `newValue` 和 `oldValue` 相同
      },
      deep: true
    }
  }
}

3.4. 及时响应回调的侦听器(immediate)

  • watch 默认是懒执行的:仅当数据源变化时,才会执行回调。但在某些场景中,我们希望在创建侦听器时,立即执行一遍回调。举例来说,我们想请求一些初始数据,然后在相关状态更改时重新请求数据。
  • 我们可以用一个对象来声明侦听器,这个对象有 handler 方法和 immediate: true 选项,这样便能强制回调函数立即执行:
js 复制代码
export default {
  // ...
  watch: {
    question: {
      handler(newQuestion) {
        // 在组件实例创建时会立即调用
      },
      // 强制立即执行回调
      immediate: true
    }
  }
  // ...
}

4. 关于 watch 的一些补充点

4.1. watch 回调的触发时机

  1. 当你更改了响应式状态,它可能会同时触发 Vue 组件更新和侦听器回调。
  2. 默认情况下,用户创建的侦听器回调,都会在 Vue 组件更新之前被调用。这意味着你在侦听器回调中访问的 DOM 将是被 Vue 更新之前的状态。
  3. 如果想在侦听器回调中能访问被 Vue 更新之后的DOM,你需要指明 flush: 'post' 选项:
js 复制代码
export default {
  // ...
  watch: {
    key: {
      handler() {},
      flush: 'post'
    }
  }
}

4.2. this.$watch()

  • 我们也可以使用组件实例的 $watch()方法来命令式地创建一个侦听器:
  • 如果要在特定条件下设置一个侦听器,或者只侦听响应用户交互的内容,这方法很有用。它还允许你提前停止该侦听器。
js 复制代码
export default {
  created() {
    this.$watch('question', (newQuestion) => {
      // ...
    })
  }
}

4.3. unwatch - 侦听器停止

  • 用 watch 选项或者 $watch() 实例方法声明的侦听器,会在宿主组件卸载时自动停止。因此,在大多数场景下,你无需关心怎么停止它。
  • 在少数情况下,你的确需要在组件卸载之前就停止一个侦听器,这时可以调用 $watch() API 返回的函数。
相关推荐
Front思33 分钟前
vue使用高德地图
javascript·vue.js·ecmascript
花花鱼3 小时前
@antv/x6 导出图片下载,或者导出图片为base64由后端去处理。
vue.js
流烟默4 小时前
Vue中watch监听属性的一些应用总结
前端·javascript·vue.js·watch
蒲公英10015 小时前
vue3学习:axios输入城市名称查询该城市天气
前端·vue.js·学习
杨荧7 小时前
【JAVA开源】基于Vue和SpringBoot的旅游管理系统
java·vue.js·spring boot·spring cloud·开源·旅游
一 乐12 小时前
学籍管理平台|在线学籍管理平台系统|基于Springboot+VUE的在线学籍管理平台系统设计与实现(源码+数据库+文档)
java·数据库·vue.js·spring boot·后端·学习
小御姐@stella13 小时前
Vue 之组件插槽Slot用法(组件间通信一种方式)
前端·javascript·vue.js
万叶学编程16 小时前
Day02-JavaScript-Vue
前端·javascript·vue.js
积水成江19 小时前
关于Generator,async 和 await的介绍
前端·javascript·vue.js
计算机学姐19 小时前
基于SpringBoot+Vue的高校运动会管理系统
java·vue.js·spring boot·后端·mysql·intellij-idea·mybatis