湘北有渔 發表於 2026-1-7 08:22:22

如何取消Vue Watch监听的方法示例

<div id="navCategory"><h5 class="catalogue">目录</h5><ul class="first_class_ul"><li><a href="#_label0">1. 为什么要取消 Watch 监听?</a></li><ul class="second_class_ul"><li><a href="#_lab2_0_0">once 和手动取消监听的区别</a></li></ul><li><a href="#_label1">2. Vue 2 中如何取消 Watch 监听</a></li><ul class="second_class_ul"><li><a href="#_lab2_1_1">示例</a></li></ul><li><a href="#_label2">3. Vue 3 中如何取消 Watch 监听</a></li><ul class="second_class_ul"><li><a href="#_lab2_2_2">示例</a></li></ul><li><a href="#_label3">4. 总结</a></li><ul class="second_class_ul"></ul></ul></div><p class="maodian"><a name="_label0"></a></p><h2>1. 为什么要取消 Watch 监听?</h2>
<p>在实际项目中,<code>watch</code> 本质上是一种<strong>长期订阅关系</strong>。<br />如果不加控制,它会在数据变化的整个生命周期内持续触发,这在很多场景下并不是我们想要的。</p>
<p>合理地取消监听,主要有以下几个好处:</p>
<ul><li><strong>避免无意义的重复执行</strong><br />有些监听只在初始化或某个阶段生效,继续监听只会重复跑逻辑。</li><li><strong>减少数据变化带来的逻辑污染</strong><br />后续状态变化可能触发过期逻辑,导致数据被意外修改。</li><li><strong>避免内存泄漏等性能问题</strong><br />尤其是在非组件作用域(如 composable、service)中,未销毁的 watch 可能长期驻留内存。</li></ul>
<p class="maodian"><a name="_lab2_0_0"></a></p><h3>once 和手动取消监听的区别</h3>
<p>Vue 3 提供了 <code>once</code> 选项,用来监听一次后自动销毁:</p>
<p><strong>once</strong></p>
<ul><li>只监听一次</li><li>触发后自动销毁</li><li>适合初始化、首次赋值等简单场景</li><li>相对&ldquo;死板&rdquo;,无法灵活判断是否是期望的数据</li></ul>
<p><strong>手动取消监听(stop)</strong></p>
<ul><li>监听可以持续存在</li><li>由开发者自行决定<strong>何时终止</strong></li><li>更灵活,适合复杂判断条件</li></ul>
<p class="maodian"><a name="_label1"></a></p><h2>2. Vue 2 中如何取消 Watch 监听</h2>
<p>在 Vue 2 中,<strong>只有通过 <code>this.$watch</code> 创建的监听才能被手动取消</strong>。</p>
<p class="maodian"><a name="_lab2_1_1"></a></p><p class="maodian"><a name="_lab2_2_2"></a></p><h3>示例</h3>
<div class="jb51code"><pre class="brush:js;">const stop = this.$watch(
'count',
function (nval) {
    if (nval === 3) {
      stop()
    }
}
)

const handleStopWatch = () =&gt; {
stop()
}
</pre></div>
<p>这里需要注意一个关键点:</p>
<blockquote><p><strong>Vue 2 的选项式写法(watch: {})是没有返回值的,因此无法手动取消监听。</strong></p></blockquote>
<div class="jb51code"><pre class="brush:js;">watch: {
count(val) {
    // ❌ 这种方式无法取消
}
}
</pre></div>
<p>如果你有「阶段性监听」或「一次性逻辑」的需求,就必须使用 <code>this.$watch</code>。</p>
<p class="maodian"><a name="_label2"></a></p><h2>3. Vue 3 中如何取消 Watch 监听</h2>
<p>Vue 3(Composition API)对这点做了明显优化:<br /><strong><code>watch</code> 本身就会返回一个停止监听的函数</strong>。</p>
<h3>示例</h3>
<div class="jb51code"><pre class="brush:js;">const count = ref(1)

const stop = watch(
count,
(nval) =&gt; {
    if (nval === 3) {
      stop()
    }
}
)

const handleStopWatch = () =&gt; {
stop()
}
</pre></div>
<p>可以看到,Vue 3 的写法在语义上更加清晰:</p>
<ul><li><code>watch</code> 创建监听</li><li>返回的 <code>stop</code> 函数用于取消监听</li><li>逻辑更集中,也更安全</li></ul>
<p class="maodian"><a name="_label3"></a></p><h2>4. 总结</h2>
<ul><li><code>watch</code> 本质是<strong>订阅关系</strong>,不是越多越好</li><li><strong>一次性 / 阶段性逻辑</strong>,应及时销毁监听</li><li>Vue 2 中只能通过 <code>this.$watch</code> 取消监听</li><li>Vue 3 中 <code>watch</code> 天然支持 <code>stop</code>,也可以直接使用 <code>once</code></li></ul>
<blockquote><p><strong>监听不是一直盯着,而是完成使命后及时退场。</strong></p></blockquote>
頁: [1]
查看完整版本: 如何取消Vue Watch监听的方法示例