金克木藍椶 發表於 2025-12-31 09:29:51

Vue3 watchEffect核心用法与原理解析

<div id="navCategory"><h5 class="catalogue">目录</h5><ul class="first_class_ul"><li><a href="#_label0">一、什么是watchEffect?</a></li><li><a href="#_label1">二、工作原理</a></li><li><a href="#_label2">三、核心特性</a></li><li><a href="#_label3">四、实战用法示例</a></li><ul class="second_class_ul"><li><a href="#_lab2_3_0">4.1 基础用法(修改页面标题)</a></li><li><a href="#_lab2_3_1">4.2 自动清理副作用</a></li><li><a href="#_lab2_3_2">4.3 手动停止侦听</a></li></ul><li><a href="#_label4">五、与watch的核心区别</a></li><ul class="second_class_ul"></ul><li><a href="#_label5">六、常见避坑点</a></li><ul class="second_class_ul"></ul><li><a href="#_label6">七、核心总结</a></li><ul class="second_class_ul"></ul></ul></div><p class="maodian"><a name="_label0"></a></p><h2>一、什么是watchEffect?</h2>
<p>watchEffect是Vue3组合式API提供的响应式侦听器,用于监听响应式数据变化并执行副作用逻辑。核心定义:<strong>立即执行一次副作用函数,自动追踪函数内访问的响应式数据,当依赖变化时重新执行函数</strong>,无需手动指定监听源。</p>
<p>它是watch的&ldquo;简化版&rdquo;,专注于&ldquo;副作用响应&rdquo;,解决了watch需手动指定依赖的繁琐问题。</p>
<p class="maodian"><a name="_label1"></a></p><h2>二、工作原理</h2>
<p>基于Vue3响应式系统的ReactiveEffect实现:</p>
<ul><li>执行watchEffect传入的副作用函数,此时会触发响应式数据的getter</li><li>自动收集函数内访问的所有响应式依赖(依赖追踪)</li><li>当依赖变化时,触发setter,重新执行副作用函数</li><li>组件卸载时,自动停止侦听,避免内存泄漏</li></ul>
<p class="maodian"><a name="_label2"></a></p><h2>三、核心特性</h2>
<ul><li><strong>自动收集依赖</strong>:无需像watch那样手动指定监听源,函数内用到的响应式数据都会被追踪</li><li><strong>立即执行</strong>:默认首次渲染就执行一次,无需配置immediate</li><li><strong>自动清理</strong>:支持通过onInvalidate清理副作用(如移除事件监听、取消请求)</li><li><strong>自动停止</strong>:在</li></ul>
<p class="maodian"><a name="_label3"></a></p><h2>四、实战用法示例</h2>
<p class="maodian"><a name="_lab2_3_0"></a></p><h3>4.1 基础用法(修改页面标题)</h3>
<div class="jb51code"><pre class="brush:js;">&lt;script setup&gt;
import { ref, watchEffect } from 'vue'
const count = ref(0)
// 自动追踪count,count变化时重新执行
watchEffect(() =&gt; {
document.title = `当前计数:${count.value}`
})
&lt;/script&gt;</pre></div>
<p class="maodian"><a name="_lab2_3_1"></a></p><h3>4.2 自动清理副作用</h3>
<div class="jb51code"><pre class="brush:js;">&lt;script setup&gt;
import { watchEffect } from 'vue'
watchEffect((onInvalidate) =&gt; {
// 绑定事件监听
const handleClick = () =&gt; console.log('点击事件')
document.addEventListener('click', handleClick)
// 依赖变化/组件卸载前清理
onInvalidate(() =&gt; {
    document.removeEventListener('click', handleClick)
})
})
&lt;/script&gt;</pre></div>
<p class="maodian"><a name="_lab2_3_2"></a></p><h3>4.3 手动停止侦听</h3>
<div class="jb51code"><pre class="brush:js;">&lt;script setup&gt;
import { ref, watchEffect } from 'vue'
const count = ref(0)
// watchEffect返回停止函数
const stop = watchEffect(() =&gt; {
console.log('count值:', count.value)
})
// 满足条件时停止侦听
if (count.value &gt; 5) {
stop()
}
&lt;/script&gt;</pre></div>
<p class="maodian"><a name="_label4"></a></p><h2>五、与watch的核心区别</h2>
<table><thead><tr><th>对比维度</th><th>watchEffect</th><th>watch</th></tr></thead><tbody><tr><td>依赖收集</td><td>自动收集函数内依赖</td><td>需手动指定监听源</td></tr><tr><td>触发时机</td><td>默认立即执行</td><td>默认惰性执行(需immediate开启)</td></tr><tr><td>旧值获取</td><td>不支持</td><td>支持(newVal, oldVal)</td></tr><tr><td>适用场景</td><td>动态依赖、简单副作用</td><td>旧值对比、节流防抖、异步请求</td></tr></tbody></table>
<p class="maodian"><a name="_label5"></a></p><h2>六、常见避坑点</h2>
<ul><li><strong>副作用堆积</strong>:未清理副作用(如事件监听、定时器),导致多次执行后重复绑定,需用onInvalidate清理</li><li><strong>依赖未追踪</strong>:函数内未直接访问响应式数据(如嵌套过深未触发getter),需确保依赖被直接访问</li><li><strong>异步逻辑问题</strong>:异步操作内的响应式数据不会被追踪,需将依赖写在同步代码中</li></ul>
<p class="maodian"><a name="_label6"></a></p><h2>七、核心总结</h2>
<p>watchEffect核心价值是&ldquo;简化响应式侦听&rdquo;,无需手动指定依赖,适合动态依赖、简单副作用场景(如DOM操作、页面标题修改、临时调试)。记住3个关键点:</p>
<ul><li>自动收集依赖,无需手动配置监听源</li><li>首次立即执行,依赖变化重新执行</li><li>必做:用onInvalidate清理副作用,避免内存泄漏</li></ul>
<p>与watch互补使用,简单副作用用watchEffect,需旧值对比、异步节流用watch,高效驾驭Vue3响应式侦听。</p>
頁: [1]
查看完整版本: Vue3 watchEffect核心用法与原理解析