Vue3中如何检测数组的变化


Vue 3中,watch和watchEffect函数是用于监听数据变化的功能。

1. watch

  • watch函数是一个选项,可以在组件的选项中使用。
  • 它接收两个参数:要监听的数据表达式或计算属性,以及回调函数。
  • 当监听的数据发生变化时,回调函数会被触发执行。
  • 回调函数接收两个参数:新值(变化后的值)和旧值(变化前的值)。
  • 可以使用watch函数来监听简单的数据变化,以及需要精确控制监听行为的情况。
  • watch函数还支持配置选项,如deep用于深度监听对象或数组的变化,immediate用于在初始化时立即执行回调函数等。
  • 示例代码:
import { watch } from 'vue';

watch(
  () => myArray, // 监听的数组
  (newArray, oldArray) => {
    // 数组发生变化时的回调函数
    console.log('数组变化了', newArray, oldArray);
  }
);

在上面的代码中,我们使用watch函数来监听myArray数组的变化。当数组发生变化时,回调函数将被执行。

2. watchEffect

  • watchEffect函数是一个响应式副作用函数,可以在组件的代码块中使用。
  • 它接收一个函数作为参数,该函数内部可以使用响应式数据。
  • 当响应式数据变化时,函数会被自动触发执行。
  • watchEffect函数会自动追踪函数内部使用的响应式数据,并在其变化时重新执行函数。
  • 这意味着你无需显式指定要监听的数据,而是让Vue自动追踪依赖关系。
  • watchEffect函数适用于需要自动追踪多个响应式数据变化的情况,以及需要处理副作用操作的场景。
  • 示例代码:
import { watchEffect } from 'vue';

watchEffect(() => {
  console.log('数组变化了', myArray);
});

在上面的代码中,我们使用watchEffect函数来监听myArray数组的变化。一旦数组发生变化,回调函数将被执行。

3. 区别

3.1 监听的方式:

  • watch选项:watch选项需要在组件的选项中定义,并接收两个参数:要监听的数据表达式和回调函数。它可以监听指定的数据或计算属性,并在其变化时执行回调函数。
  • watchEffect函数:watchEffect函数可以在组件的代码块中直接使用,并接收一个函数作为参数。它会自动追踪函数内部使用的响应式数据,并在其变化时执行函数。

3.2 追踪依赖:

  • watch选项:watch选项需要明确指定要监听的数据表达式,只有该表达式变化时才会触发回调函数。如果需要监听多个数据,可以使用包含这些数据的计算属性。
  • watchEffect函数:watchEffect函数会自动追踪函数内部使用的响应式数据,并在任何这些数据变化时触发函数。它会自动收集依赖,并在依赖发生变化时重新运行函数。

3.3 调用时机:

  • watch选项:watch选项在初始化时会立即执行一次回调函数,并在监听的数据发生变化时再次执行回调函数。
  • watchEffect函数:watchEffect函数在组件渲染时会立即执行一次函数,并在其内部使用的响应式数据发生变化时再次执行函数。

3.4 返回值:

  • watch选项:watch选项的回调函数可以返回一个清理函数,用于在不需要监听时进行清理操作。
  • watchEffect函数:watchEffect函数没有返回值,且无法手动停止追踪和清理。
Vue.js 中实现数组变化监听主要依赖于其响应式系统的设计。Vue 通过替换数组原型上的方法(如 `push`、`pop`、`shift`、`unshift`、`splice`、`sort` 和 `reverse`)来追踪数组变化,而不是直接为数组的每个元素设置 getter/setter[^2]。 ### 实现方式 #### 1. 使用 `watch` 属性 在 Vue 的选项对象中,可以使用 `watch` 属性来监听特定数据的变化。当需要监听数组时,可以通过深度监听或直接监听数组引用的方式来实现。 ```javascript new Vue({ el: '#app', data: { items: [1, 2, 3] }, watch: { // 监听整个数组变化 items: { handler(newVal, oldVal) { console.log('数组发生变化:', newVal); }, deep: true // 启用深度监听检测数组内部变化 } } }); ``` 如果仅关心数组引用是否改变(例如重新赋值),则可以不启用 `deep` 选项: ```javascript watch: { items(newVal, oldVal) { console.log('数组引用发生变化:', newVal); } } ``` #### 2. 使用 `$watch` 方法 Vue 提供了 `$watch` API 来动态创建监听器。这种方式适用于运行时动态添加监听的情况。 ```javascript const vm = new Vue({ el: '#app', data: { items: [1, 2, 3] } }); vm.$watch('items', function (newVal, oldVal) { console.log('数组发生变化:', newVal); }, { deep: true }); ``` #### 3. 使用 `Vue.set` 或 `this.$set` 当需要向数组中添加新元素并确保该操作是响应式的,可以使用 `Vue.set` 或 `this.$set`。这在修改数组的某些索引位置或长度时特别有用。 ```javascript // 添加一个新元素到数组末尾,并触发更新 this.$set(this.items, this.items.length, 4); ``` #### 4. 替换数组方法 Vue 替换了数组的变异方法,这些方法会修改原数组并触发视图更新。以下是可以被 Vue 检测到的数组方法: - `push()` - `pop()` - `shift()` - `unshift()` - `splice()` - `sort()` - `reverse()` 例如: ```javascript this.items.push(4); // 触发响应式更新 ``` 需要注意的是,像 `this.items[index] = newValue` 这样的操作不会触发响应式更新,因为 JavaScript 不允许为数组索引定义 setter。此时应使用 `this.$set` 来替代: ```javascript this.$set(this.items, index, newValue); ``` #### 5. 深度监听与性能优化 由于数组可能包含大量数据,启用 `deep: true` 可能会对性能产生影响。因此,在实际开发中,建议根据具体需求决定是否需要深度监听。如果只需要监听数组引用的变化,则无需启用 `deep`。 --- ### 总结 Vue 通过重写数组的原型方法来实现对数组变化监听,同时提供了多种方式(如 `watch`、`$watch` 和 `$set`)来处理数组的响应式更新。开发者可以根据具体的业务场景选择合适的监听策略,以平衡功能需求和性能开销。 ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小新-alive

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值