【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 返回的函数。
相关推荐
Dread_lxy6 小时前
vue 依赖注入(Provide、Inject )和混入(mixins)
前端·javascript·vue.js
龙猫蓝图8 小时前
vue el-date-picker 日期选择器禁用失效问题
前端·javascript·vue.js
peachSoda78 小时前
随手记:简单实现纯前端文件导出(XLSX)
前端·javascript·vue.js
Tttian6228 小时前
Vue全栈开发旅游网项目(11)-用户管理前端接口联调
前端·vue.js·django
龙猫蓝图10 小时前
vue el-date-picker 日期选择 回显后成功后无法改变的解决办法
前端·javascript·vue.js
刘志辉10 小时前
Pure Adminrelease(水滴框架配置)
vue.js
工业互联网专业11 小时前
Python毕业设计选题:基于Django+uniapp的公司订餐系统小程序
vue.js·python·小程序·django·uni-app·源码·课程设计
黄景圣11 小时前
CURD低代码程序设计
前端·vue.js·后端
lin-lins11 小时前
Vue 模板编译原理
前端·javascript·vue.js
customer0812 小时前
【开源免费】基于SpringBoot+Vue.JS课程答疑系统(JAVA毕业设计)
java·jvm·vue.js·spring boot·spring cloud·kafka·开源