Vue3中watchEffect的flush: ‘post‘作用

副作用刷新时机

Vue 的响应性系统会缓存副作用函数,并异步地刷新它们,这样可以避免同一个“tick”中多个状态改变导致的不必要的重复调用。

同一个“tick”的意思是,Vue的内部机制会以最科学的计算规则将视图刷新请求合并成一个一个的"tick",每个“tick”刷新一次视图,比如a=1;b=2;只会触发一次视图刷新。$nextTick的Tick就是指这个。

继续说,比如有个watchEffect监听了2个变量a和b,我的业务写了a=1;b=2;,你觉得监听器会调用2次?当然不会,Vue会合并成1次去执行,代码如下,console.log只会执行一次:

<template>
  <div>
    <button
      @click="
        r++;
        s++;
      "
    >
      {{ r }} - {{ s }}
    </button>
  </div>
</template>
 
<script>
import { ref, watchEffect } from 'vue';
export default {
  setup() {
    let r = ref(2);
    let s = ref(10);
    watchEffect(() => {
      console.log(r.value, s.value);
    });
    return {
      r,
      s,
    };
  },
};
</script>

在核心的具体实现中,组件的update函数也是一个被侦听的副作用。当一个用户定义的副作用函数进入队列时,默认情况下,会在所有的组件update前执行。

所谓组件的update函数是Vue内置的用来更新DOM的函数,它也是副作用。这时候有一个问题,就是默认下,Vue会先执行组件DOM update,还是先执行监听器?测一下:

<template>
  <div>
    <button
      id="aa"
      @click="
        r++;
        s++;
      "
    >
      {{ r }} - {{ s }}
    </button>
  </div>
</template>
 
<script>
import { ref, watchEffect } from 'vue';
export default {
  setup() {
    let r = ref(2);
    let s = ref(10);
    watchEffect(
      () => {
        console.log(r.value, s.value);
        console.log(document.querySelector('#aa') && document.querySelector('#aa').innerText);
      }
    );
    return {
      r,
      s,
    };
  },
};
</script>

点击若干次(比如2次)按钮,得到的结果是:

在这里插入图片描述

为什么点之前按钮的innerText打印null?因为事实就是默认先执行监听器,然后更新DOM,此时DOM还未生成,当然是null。

当我第1和2次点击完,你会发现,document.querySelector(‘#aa’).innerText获取到的总是点击之前DOM的内容。这也说明,默认Vue先执行监听器,所以取到了上一次的内容,然后执行组件update。

Vue 2其实也是这种机制,Vue 2使用this. n e x t T i c k ( ) 去获取组件更新完成之后的 D O M ,在 w a t c h E f f e c t 里就不需要用 t h i s . nextTick()去获取组件更新完成之后的DOM,在watchEffect里就不需要用this. nextTick()去获取组件更新完成之后的DOM,在watchEffect里就不需要用this.nextTick()(也没法用),有一个办法能获取组件更新完成之后的DOM,就是使用:

watchEffect(
  () => {
    /* ... */
  },
  {
    flush: 'post'
  }
)

现在设上flush配置项,重新进入组件,再看看:
在这里插入图片描述
所以结论是,如果要操作“更新之后的DOM”,就要配置flush: ‘post’。
————————————————
版权声明:本文为优快云博主「但加木」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.youkuaiyun.com/weixin_46105875/article/details/119916064

Vue 3中引入了一个新的API,即`watchEffect`,用于监视响应式数据的变化并执行相应的副作用函数。下面是使用`watchEffect`的介绍: 1. `watchEffect`的基本用法: `watchEffect`接收一个函数作为参数,该函数中可以访问响应式数据,并在数据变化时执行相应的副作用操作。当响应式数据发生变化时,`watchEffect`会自动重新运行该函数。 ```javascript import { watchEffect } from &#39;vue&#39;; watchEffect(() => { // 在这里执行副作用操作 }); ``` 2. 监视特定的响应式数据: 如果你只想监视特定的响应式数据,可以在`watchEffect`函数中直接访问它们。当这些数据发生变化时,副作用函数会被重新执行。 ```javascript import { reactive, watchEffect } from &#39;vue&#39;; const state = reactive({ count: 0, message: &#39;Hello&#39;, }); watchEffect(() => { console.log(state.count); console.log(state.message); }); ``` 3. 停止监视: `watchEffect`返回一个停止监视的函数,可以在需要停止监视时调用。 ```javascript import { reactive, watchEffect } from &#39;vue&#39;; const state = reactive({ count: 0, }); const stop = watchEffect(() => { console.log(state.count); }); // 停止监视 stop(); ``` 4. 监视多个响应式数据: 如果你想同时监视多个响应式数据,可以在副作用函数中访问它们,并将它们作为依赖项传递给`watchEffect`。 ```javascript import { reactive, watchEffect } from &#39;vue&#39;; const state = reactive({ count: 0, message: &#39;Hello&#39;, }); watchEffect(() => { console.log(state.count); console.log(state.message); }, { flush: &#39;post&#39;, deep: true, }); ``` 在上面的示例中,`flush`选项设置为`post`,表示在DOM更新之后执行副作用函数。`deep`选项设置为`true`,表示深度监视响应式数据的变化。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值