【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 返回的函数。
相关推荐
jjw_zyfx1 小时前
成熟的前端vue vite websocket,Django后端实现方案包含主动断开websocket连接的实现
前端·vue.js·websocket
乌夷3 小时前
使用spring boot vue 上传mp4转码为dash并播放
vue.js·spring boot·dash
苹果酱05675 小时前
2020-06-23 暑期学习日更计划(机器学习入门之路(资源汇总)+概率论)
java·vue.js·spring boot·mysql·课程设计
Deepsleep.5 小时前
react和vue的区别之一
javascript·vue.js·react.js
zqlcoding5 小时前
使用el-table表格动态渲染表头数据之后,导致设置fixed的列渲染出现问题
前端·javascript·vue.js
爱吃的强哥5 小时前
vue3 使用 vite 管理多个项目,实现各子项目独立运行,独立打包
前端·javascript·vue.js
涵信6 小时前
第十节:性能优化高频题-虚拟DOM与Diff算法优化
javascript·vue.js·性能优化
拖孩6 小时前
【Nova UI】十一、组件库中 Icon 组件的测试、使用与全局注册全攻略
前端·javascript·vue.js·ui·sass
凉豆菌7 小时前
在html中如何创建vue自定义组件(以自定义文件上传组件为例,vue2+elementUI)
vue.js·elementui·html
广西千灵通网络科技有限公司7 小时前
基于 springboot+vue+elementui 的办公自动化系统设计(
vue.js·spring boot·elementui