VueJS - Watch 属性
Vue 3 - 侦听器
Section titled “Vue 3 - 侦听器”在 Vue 中,侦听器(watchers)允许您响应响应式(reactive)数据的变化来执行操作。本章节将演示如何在 Vue 3 中使用侦听器,包括经典的选项式 API(Options API)和现代的组合式 API(Composition API)。
当特定的数据发生变化时,侦听器对于执行异步操作或复杂的逻辑非常有用。
概念:侦听数据变化
Section titled “概念:侦听数据变化”想象一下,您有两个输入字段,一个用于输入千米,一个用于输入米。当其中一个字段的值发生变化时,您希望另一个字段根据转换(1千米 = 1000米)自动更新。侦听器非常适合这种场景。
使用组合式 API (watch) 的示例
Section titled “使用组合式 API (watch) 的示例”组合式 API 提供了 watch 函数来创建侦听器。这是推荐用于新的 Vue 3 应用的方法。
<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> <title>Vue 3 Watchers (Composition API)</title> <script src="https://unpkg.com/vue@3"></script></head><body> <div id="app"> <h2>Kilometer / Meter Converter (Composition API)</h2> <label>Kilometers:</label> <input type="number" v-model="kilometers" /> <br/> <label>Meters:</label> <input type="number" v-model="meters" /> </div>
<script> const { createApp, ref, watch } = Vue;
const app = createApp({ setup() { const kilometers = ref(0); const meters = ref(0);
// Watch for changes in kilometers // 侦听 kilometers 的变化 watch(kilometers, (newKilometers) => { // Avoid infinite loops by checking if the value is already correct // 通过检查值是否已经正确来避免无限循环 if (newKilometers * 1000 !== meters.value) { meters.value = newKilometers * 1000; } });
// Watch for changes in meters // 侦听 meters 的变化 watch(meters, (newMeters) => { if (newMeters / 1000 !== kilometers.value) { kilometers.value = newMeters / 1000; } });
return { kilometers, meters }; } });
app.mount('#app'); </script></body></html>在这个组合式 API 示例中:
- 我们从 Vue 中导入了
createApp、ref和watch。 - 我们使用
ref(0)将kilometers和meters定义为响应式引用(reactive references)。 - 我们使用了
watch函数。第一个参数是要侦听的响应式源(例如kilometers)。第二个参数是一个回调函数(callback function),当源发生变化时运行。回调函数接收新值(newKilometers),并且可以选择接收旧值。 - 在侦听器回调函数内部,我们更新了另一个响应式变量(例如,当
kilometers改变时更新meters)。 - 我们在侦听器内部添加了检查 (
if (newKilometers * 1000 !== meters.value)),以防止可能发生的无限更新循环。这种循环可能在设置一个值时立即触发另一个侦听器,而该侦听器又将第一个值设置回去时发生。
使用选项式 API (watch 选项) 的示例
Section titled “使用选项式 API (watch 选项) 的示例”选项式 API 的方法是在组件的 watch 选项中定义侦听器。
<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> <title>Vue 3 Watchers (Options API)</title> <script src="https://unpkg.com/vue@3"></script></head><body> <div id="app-options"> <h2>Kilometer / Meter Converter (Options API)</h2> <label>Kilometers:</label> <input type="number" v-model="kilometers" /> <br/> <label>Meters:</label> <input type="number" v-model="meters" /> </div>
<script> const { createApp } = Vue;
const appOptions = createApp({ data() { return { kilometers: 0, meters: 0 }; }, watch: { // Watcher for the 'kilometers' data property // meters 数据属性的侦听器 kilometers(newValue) { // Avoid infinite loops // 避免无限循环 if (newValue * 1000 !== this.meters) { this.meters = newValue * 1000; } }, // Watcher for the 'meters' data property // meters 数据属性的侦听器 meters(newValue) { if (newValue / 1000 !== this.kilometers) { this.kilometers = newValue / 1000; } } }, // Computed properties are often a better fit for simple dependencies // 对于简单的依赖关系,计算属性通常更适合 // See the chapter on Computed Properties for comparison. // 请参阅计算属性的章节进行比较。 computed: { // Example showing computed equivalent (might be simpler here) // 显示等效计算属性的示例(在此处可能更简单) /* metersFromKm: { get() { return this.kilometers * 1000; }, set(val) { this.kilometers = val / 1000; } } */ } });
appOptions.mount('#app-options'); </script></body></html>在这个选项式 API 示例中:
kilometers和meters在data选项中定义。watch选项包含以其侦听的数据属性命名的函数(例如kilometers(newValue))。- 侦听器方法内部的逻辑与组合式 API 示例类似,使用
this访问其他数据属性。 - 其中包含了一个被注释掉的
computed属性示例。对于像这种单位转换之类的简单同步依赖关系,计算属性通常比侦听器更简洁,性能也更好。
何时使用侦听器
Section titled “何时使用侦听器”- 当某个值(如 ID)改变时异步获取数据。
- 执行不直接映射到计算值的复杂逻辑或副作用。
- 基于数据的快速变化进行节流(throttling)或防抖(debouncing)操作(通常结合 Lodash 等工具库)。
- 响应状态变化与浏览器 API 或第三方库交互。
在实现 watch 之前,请记住考虑 computed 属性是否可能是更简单、更合适的解决方案。
有关更多详细信息,请参阅 Vue 3 官方文档关于侦听器的内容。