1. 前言 本节介绍侦听器 watch 的使用方法。包括什么是侦听器,侦听器的特点,以及如何对不同类型的数据进行监听。其中重点掌握对不同类型的数据如何使用侦听器,了解它之后,才能在之后的日常开发中熟练运用。 2. 木子解释 Vue 提供了一种更通用的方式来观察和响应 Vue 实例上的数据变动:侦听属性。 — 官方定义 侦听器 watch 是 Vue 提供的一种用来观察和响应 Vue 实例上的数据变化的属性。当被侦听的数据发生变化时,会触发对应的侦听函数。 3. 使用侦听器 前面我们介绍了什么是侦听器 watch ,那么如何定义一个侦听器呢? 侦听器 watch 实际是 vue 实例上的一个对象属性。当我们需要对 vue 实例上某个属性进行侦听时,我们以需要被侦听的属性名作为 watch 对象的键,以一个函数 function 作为该键的值。函数 function 接收两个参数:侦听数据变化之后的值 newValue ;侦听数据变化之前的值 oldValue : var vm = new Vue({ el: "#app", data() { return { count: 0 } }, watch: { count: function(newVal, oldVal) { // 具体处理逻辑 }, } }) 代码解释: 第 5 行,我们在 data 中定义了 Number 类型的数据 count 。 第 8-12 行,我们在侦听属性 watch 中定义了侦听器 count 。 在介绍完如何定义一个侦听器之后,让我们用几个实例来学习一下如何在项目中使用侦听器。 3.1 对字符串、布尔值、数字、数组类型的监听 假设当前项目中有以下需求,用户的购买商品页面: 当用户每次修改要购买商品名称的时候,都需要清空购买数量。 用户添加的数量在必须大于 0,并且当首次出现数量大于 10 的时候弹出数量超额提示,下次超过不再提示。 购物车数量发生变化时提示用户。 在我们写具体的代码逻辑之前,让我们先来分析一下如何使用侦听器 watch 来实现需求功能: 对于需求 1, 我们需要对商品名称进行侦听,当它改变的时候将数量清零。 对于需求 2, 我们需要对商品数量进行侦听,当商品数量首次超过 10 的时候,弹出对应提示;当商品数量小于 0 的时候,将数量改为 0。 对于需求 3, 对购物车数据进行侦听,每次操作购物车数据时提示用户。 具体实现如下: 实例演示Document 商品名称: 购买数量{{count}} {{item.name}} x{{item.count}} "运行案例" 可查看在线运行效果 代码解释: 在 html 代码中, 我们给出一个商品名称输入框以及添加数量和减少数量的两个按钮。 代码第 4-9 行,我们定义了四个数据,分别是: name — 商品的名称 count — 商品的数量 isMax — 是否首次超过数量 10 list — 购物车列表 代码第 10-24 行,我们定义了三个方法,分别是: cut — 将数量 count - 1 add — 将数量 count + 1 addCart — 修改购物车数据 代码第 25-49 行,我们定义了四个侦听器,分别是: name — 对数据 name 侦听,触发时将 count 变成 0;并 将 isMax 变成 false count — 对数据 count 侦听, 检测到 count 大于 10 时,将 isMax 变成 true,检测到 count 小于 0 的时候将 count 修改为 0。 isMax — 对数据 isMax 侦听,触发时,判断变化后的值是否为 true,当值为 true 时弹出提示消息 list — 对数据 list 侦听,每次改变时弹出提示消息。 3.2 示例二:侦听对象某个属性的变化 上面在示例一中学习了对字符串、布尔值、数字、数组类型的侦听,那么如何对对象的某个属性进行侦听呢? 我们对上述代码稍作修改: 实例演示Document 商品名称: "运行案例" 可查看在线运行效果 代码解释: 第 11-13 行,我们定义来侦听器 product 。我们的理想效果是:当在输入框中输入商品名称的时候,在控制台中会打印出最新的 product 值。 从效果图中我们可以看出,实际的执行效果和我们想象中并不一致。当在输入框中输入商品名称的时候,侦听器 product 并没有触发。这是为什么呢?我们先带着这个疑问看下下面这段的代码: 实例演示Document 商品名称: "运行案例" 可查看在线运行效果 代码解释: 第 11-13 行,我们定义了侦听器 product ,并在生命周期 mounted 函数中修改 product 的值。运行代码,我们惊奇地发现侦听器会在一开始的时候触发,输入框中输入的时候同样不会触发。 大部分同学看到这里应该已经猜到之前为什么修改 name 不会触发侦听器。因为 product 指向的是一个引用地址,在第一个例子中,我们只修改了 product 的 name 属性,而没有修改 product 的引用地址。而在第二个例子中,我们给 product 重新赋值,因此 product 的引用地址也发生了改变,所以可以成功触发侦听器。 通过这个结论,如果只想监听 product 的 name 属性的变化,可以对代码进行如下修改: 实例演示Document 商品名称: "运行案例" 可查看在线运行效果 代码解释: 第 10-12 行,我们定义了侦听器 product.name ,对 product 的 name 属性进行监听。当 name 值发生变化的时候触发侦听器。 4. 侦听器的高级用法 在之前的例子中,我们都是给侦听器赋值一个函数,实际上它还可以用对象的形式来定义。 4.1 handler方法 我们给 name 绑定了一个 handler 方法,之前我们写的 watch 方法其实默认写的就是这个 handler 。当 name 发生改变时, handler 方法就会执行。 实例演示Document 商品名称: "运行案例" 可查看在线运行效果 代码解释: 第 7-11 行,我们定义了侦听器 name 。它是一个对象,当 name 发生变化的时候,会调用 handler 的方法… 4.2 immediate属性 有时候你可能需要在侦听器最初绑定的时候就触发一次,这个时候我们就需要用到 immediate 属性。 示例: 实例演示Document 商品名称: "运行案例" 可查看在线运行效果 代码解释: 第 13 行,我们给侦听器 name 一个 immediate 属性,它的值为 true。这个时候,当页面第一次渲染的时候就会触发侦听器的 handler 函数。 4.3 deep属性 在之前的 3.2 中我们学习了如何对对象的某个属性做侦听:通过指明对象的某个属性来。假如现在有以下代码: 实例演示Document 商品名称: 商品数量: 商品标题: "运行案例" 可查看在线运行效果 代码解释: 在 watch 属性中,我们写了三个侦听器,都是针对 product 的某个属性进行侦听的。那有没有什么更简单的方法可以实现当 product 里面任何属性发生变化的时候就执行侦听呢? 这里就需要用到 deep 属性。 deep 属性代表是否深度监听,默认值是 false。当设置为 true 时,会对对象里面的每个属性进行侦听。 示例: 实例演示Document 商品名称: 商品数量: 商品标题: "运行案例" 可查看在线运行效果 代码解释: 第 17 行,我们加了一个属性 deep , deep 的意思就是深入观察,监听器会一层层地往下遍历,给对象的所有属性都加上这个监听器,修改对象里面任何一个属性都会触发这个监听器里的 handler。 5. 小结 本节,我们带大家学习了 侦听器 watch 在 vue 项目中的运用。主要知识点有以下几点: 通过侦听器来监听数据的变化,进行相应的逻辑处理。 如何监听对象类型数据的某个属性进行侦听。 侦听器的高级用法,handler 函数、立即触发 immediate 属性、深度监听 deep 属性。