元素码农
基础
UML建模
数据结构
算法
设计模式
网络
TCP/IP协议
HTTPS安全机制
WebSocket实时通信
数据库
sqlite
postgresql
clickhouse
后端
rust
go
java
php
mysql
redis
mongodb
etcd
nats
zincsearch
前端
浏览器
javascript
typescript
vue3
react
游戏
unity
unreal
C++
C#
Lua
App
android
ios
flutter
react-native
安全
Web安全
测试
软件测试
自动化测试 - Playwright
人工智能
Python
langChain
langGraph
运维
linux
docker
工具
git
svn
🌞
🌙
目录
▶
Vue3 基础
▶
环境搭建
安装与配置
项目创建
开发工具
▶
模板语法
插值表达式
指令系统
事件处理
▶
核心概念
▶
响应式系统
ref与reactive
计算属性
侦听器
▶
组合式API
setup函数
生命周期钩子
自定义Hooks
▶
组件开发
▶
组件基础
组件通信
Props详解
插槽机制
▶
高级组件
动态组件
异步组件
递归组件
▶
状态管理
▶
Vuex基础
状态存储
模块化
组合式写法
▶
Pinia
创建Store
状态操作
插件机制
发布时间:
2025-03-22 12:11
↑
☰
# Vue3 侦听器详解 本文将详细介绍Vue3中的侦听器(Watchers)功能,包括其基本用法、高级特性和最佳实践。 ## 侦听器基础 ### 1. watch基础用法 ```vue <template> <div> <input v-model="message" /> <p>Changed Times: {{ changedCount }}</p> </div> </template> <script setup> import { ref, watch } from 'vue' const message = ref('') const changedCount = ref(0) // 基础侦听 watch(message, (newValue, oldValue) => { console.log('Message changed:', newValue, oldValue) changedCount.value++ }) </script> ``` ### 2. watchEffect ```vue <template> <div> <p>Count: {{ count }}</p> <p>Double: {{ double }}</p> <button @click="increment">Increment</button> </div> </template> <script setup> import { ref, watchEffect } from 'vue' const count = ref(0) const double = ref(0) // 自动追踪依赖 watchEffect(() => { double.value = count.value * 2 console.log('Count is:', count.value) }) const increment = () => { count.value++ } </script> ``` ## 高级特性 ### 1. 深度侦听 ```vue <template> <div> <button @click="updateUser">Update User</button> </div> </template> <script setup> import { ref, watch } from 'vue' const user = ref({ name: 'John', profile: { age: 30, city: 'New York' } }) // 深度侦听对象变化 watch(user, (newValue, oldValue) => { console.log('User changed:', newValue, oldValue) }, { deep: true }) const updateUser = () => { user.value.profile.age = 31 } </script> ``` ### 2. 立即执行 ```vue <template> <div> <p>Data: {{ data }}</p> </div> </template> <script setup> import { ref, watch } from 'vue' const data = ref(null) const searchQuery = ref('') // 立即执行的侦听器 watch(searchQuery, async (newQuery) => { try { const response = await fetch(`/api/search?q=${newQuery}`) data.value = await response.json() } catch (error) { console.error('Error:', error) } }, { immediate: true }) </script> ``` ### 3. 多个来源 ```vue <template> <div> <input v-model="firstName" /> <input v-model="lastName" /> <p>Full Name: {{ fullName }}</p> </div> </template> <script setup> import { ref, watch } from 'vue' const firstName = ref('') const lastName = ref('') const fullName = ref('') // 侦听多个来源 watch([firstName, lastName], ([newFirst, newLast], [oldFirst, oldLast]) => { fullName.value = `${newFirst} ${newLast}`.trim() console.log( 'Name changed from:', `${oldFirst} ${oldLast}`, 'to:', `${newFirst} ${newLast}` ) }) </script> ``` ## 性能优化 ### 1. 停止侦听 ```vue <script setup> import { ref, watch } from 'vue' const count = ref(0) // 创建可停止的侦听器 const stopWatch = watch(count, (newValue) => { console.log('Count changed to:', newValue) if (newValue > 10) { stopWatch() // 当count大于10时停止侦听 } }) </script> ``` ### 2. 清理副作用 ```vue <script setup> import { ref, watch } from 'vue' const id = ref(1) const data = ref(null) // 在侦听器中清理副作用 watch(id, async (newId, oldId, onCleanup) => { const controller = new AbortController() const { signal } = controller // 注册清理函数 onCleanup(() => { controller.abort() }) try { const response = await fetch(`/api/data/${newId}`, { signal }) data.value = await response.json() } catch (error) { if (error.name === 'AbortError') { console.log('Request was aborted') } else { console.error('Error:', error) } } }) </script> ``` ## 最佳实践 ### 1. 选择合适的侦听器 ```vue <script setup> import { ref, watch, watchEffect } from 'vue' const userId = ref(1) const userData = ref(null) // 使用watch - 当你需要比较变化前后的值 watch(userId, async (newId, oldId) => { console.log(`User ID changed from ${oldId} to ${newId}`) const response = await fetch(`/api/user/${newId}`) userData.value = await response.json() }) // 使用watchEffect - 当你只关心最新值 watchEffect(async () => { const response = await fetch(`/api/user/${userId.value}`) userData.value = await response.json() }) </script> ``` ### 2. 错误处理 ```vue <script setup> import { ref, watch } from 'vue' const data = ref(null) const error = ref(null) const loading = ref(false) const fetchData = async () => { loading.value = true error.value = null try { const response = await fetch('/api/data') if (!response.ok) throw new Error('Network response was not ok') data.value = await response.json() } catch (e) { error.value = e.message } finally { loading.value = false } } // 使用侦听器处理异步操作 watch(data, () => { if (error.value) { console.error('Data fetch failed:', error.value) } else { console.log('Data updated successfully') } }) </script> ``` ### 3. 避免无限循环 ```vue <script setup> import { ref, watch } from 'vue' const count = ref(0) const double = ref(0) // 错误示例:可能导致无限循环 watch(count, (newValue) => { count.value++ // 不要在侦听器中修改被侦听的值 }) // 正确示例:使用中间值 watch(count, (newValue) => { double.value = newValue * 2 }) </script> ``` ## 总结 本文详细介绍了Vue3中侦听器的使用方法: 1. 基础知识 - watch基础用法 - watchEffect的自动依赖追踪 - 不同类型的侦听器 2. 高级特性 - 深度侦听 - 立即执行 - 多个来源侦听 3. 性能优化 - 停止侦听 - 清理副作用 - 避免无限循环 4. 最佳实践 - 选择合适的侦听器类型 - 错误处理 - 性能考虑 通过合理使用侦听器,可以有效地处理数据变化,实现复杂的响应式逻辑。建议在实际开发中根据具体场景选择合适的侦听器类型,并注意避免常见的陷阱。