Vue3---(5)watch和watchEffect

目录

watch

基本使用

特殊情况 

1.监视ref定义的基本数据数据时

2.监视ref定义的对象数据类型时

3.监视reactive定义的对象数据类型时

4.监视ref或reactive定义的数据类型中的某一个属性时

5.监视上述多个数据

核心实现逻辑

watch源码执行流程

面试重点

watch的depp实现原理

 如何优化大量watch的性能

watchEffect

基本使用

核心机制

 面试重点

为什么 watchEffect 要返回停止函数


watch

基本使用

作用:

监视数据的变化

基本使用:

监视类型只有四种

  1.  通过ref定义的数据
  2. 通过reactive定义的数据
  3. getter函数(函数返回一个值)
  4. 上述三种情况的数组
/* 
    监视【ref】定义的【对象类型】数据,监视的是对象的地址值,若想监视对象内部属性的变化,需要手动开启深度监视
    watch的第一个参数是:被监视的数据
    watch的第二个参数是:监视的回调
    watch的第三个参数是:配置对象(deep、immediate等等.....) 
  */
  watch(test,(newValue,oldValue)=>{
    console.log('test变化了',newValue,oldValue)
  },{deep:true})

    特殊情况 

    1.监视ref定义的基本数据数据时

    监视对象直接写数据名,不用带.value,此时监视的是其value值的变化

    2.监视ref定义的对象数据类型时

    watch监听ref定义的对象数据类型时,监视的是对象的地址值,若想监视对象内部的数据需要手动开启深度监视

    • 若修改的是ref定义的对象的属性,newValue和oldValue都是新值,因为是同一个对象
    • 若修改整个ref定义的对象时,newValue是新值,oldValue是旧值,因为不是同一个对象了
    3.监视reactive定义的对象数据类型时

    监视reactive定义的对象数据类型时,此时默认开启了深度监视 

    4.监视ref或reactive定义的数据类型中的某一个属性时
    • 若该属性不是对象类型,需要写成函数形式

    • 若该属性值依然是对象类型,可以直接写,也可以写成函数 () => object.key

    5.监视上述多个数据

     监视上述多个数据情况下,将多个数据放入数组中进行监视

    核心实现逻辑

    watch源码执行流程

    1. 依赖收集:通过traverse递归遍历监视对象(deep:true深度监视时)
    2. 旧值缓存: 首次执行时缓存初始值
    3. 调度器触发: 数据变化时通过scheduler调度回调

    面试重点

    watch的depp实现原理

    递归遍历对象属性,通过 Object.keys(value).forEach(k => traverse(value[k])) 强制触发所有层级的 getter

     如何优化大量watch的性能

    1. 优先使用 watchEffect 替代多个独立 watch
    2. 合并监听源:watch([src1, src2], handler)
    3. 使用 { flush: 'post' } 延迟到 DOM 更新后执行

    watchEffect

    基本使用

    作用:

    立即运行一个函数,自动收集函数内部的所有依赖,同时响应式地追踪其依赖,并在依赖更改时重新执行该函数

    核心机制

    1. 立即执行:初始化时立即运行副作用函数
    2. 自动依赖追踪:通过 Proxy 的 get 陷阱收集依赖
    3. 清理机制:提供 onInvalidate 处理异步副作用
    // watchEffect 核心逻辑
    function watchEffect(effect, options) {
      const _effect = new ReactiveEffect(effect);
      _effect.onTrack = options?.onTrack; // 调试钩子
      _effect.run(); // 立即执行
      
      return () => _effect.stop();
    }

     面试重点

    为什么 watchEffect 要返回停止函数

    防止组件卸载后副作用继续执行导致内存泄漏,需在 onUnmounted 生命周期调用

    Vue 3 中,`watch` `watchEffect` 都是用来监听数据变动并触发回调函数的特性,但它们有一些关键的区别: **1. watch (旧的观察者API)**: - 它是一个基于深度监听的传统 API,当你需要监视整个对象或数组以及它们内部的嵌套变更时非常有用。 - 监听数据变动是异步的,这意味着它不会立即响应数据的变化,而是等到下一次检测周期(通常是下一次渲染周期)才执行回调。 - `watch` 可以接收两个参数:一个是目标属性(需要监听的对象或路径),另一个是回调函数。如果只需要简单的计算或者副作用处理,可以直接写在回调里。 示例: ```javascript watch(obj, function (newVal, oldVal) { // 回调会在新值旧值改变时执行 }); ``` **2. watchEffect (新的观察者API,Vue 3 引入)**: - `watchEffect` 更加现代化,基于 ES6 的 async/await 并支持副作用管理,提供了一种更清晰的方式来编写副作用逻辑,如订阅事件、网络请求等。 - 它是立即执行的,也就是说它会立即响应数据变化,并且可以在回调中使用 `async` 关键字处理异步操作,这使得代码更容易理解维护。 - 另外,`watchEffect` 还能控制何时开始结束观察,这对于资源管理性能优化很有帮助。 示例: ```javascript watchEffect(() => { async function fetchData() { // 更新数据 } // 数据变化时立即执行fetchData fetchData(); }); ```
    评论
    添加红包

    请填写红包祝福语或标题

    红包个数最小为10个

    红包金额最低5元

    当前余额3.43前往充值 >
    需支付:10.00
    成就一亿技术人!
    领取后你会自动成为博主和红包主的粉丝 规则
    hope_wisdom
    发出的红包
    实付
    使用余额支付
    点击重新获取
    扫码支付
    钱包余额 0

    抵扣说明:

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

    余额充值