当前位置:网站首页>watch VS watchEffect
watch VS watchEffect
2022-07-27 13:09:00 【Lyrelion】
目录
使用 onInvalidate() 清除 watchEffect 副作用
使用 watchEffect 返回的 stop 方法,停止 watchEffect 监听
如何使用 watch ?
Vue Options API 提供了一个 watch 选项
export default {
data () {
return {
title: 'Vue2'
}
},
watch: {
// Watcher
}
}
watch: {
title: {
handler: (newTitle, oldTitle) => {
console.log("Title changed from " + oldTitle + " to " + newTitle);
},
immediate: true,
},
},适用场景:
- 需要控制哪些依赖项会触发该方法
- 需要访问之前的值
如何在首次监听后,自动取消 watch 监听?
调用 watch 自身,可以实现此需求
/**
* 监听 vuex 里开发者配置改变
*/
const watchInitData = watch(
() => store.state[VuexModule.ApplicationLibDevelopment],
async (newVal) => {
// 页面初始化
initPage();
// 调用 watch 本身,可以实现取消监听
watchInitData();
},
{ deep: true },
);如果需要跟踪多个响应式变量,有什么好的解决方案吗?
在 Vue Options API(Vue2)中,可以创建多个 watch 观察者
在 Composition API(Vue3)中,可以创建多个 watchEffect 观察者;也可以只创建一个 watchEffect,但在他的回调函数中,写上所有要监听的值
watchEffect VS watch
是否需要指手动传入依赖
watch —— 既要指明监视的属性,也要指明监视的回调【需要手动传入依赖】
watchEffect —— 不用指明监视哪个属性,监视的回调中用到哪个属性,那就监视哪个属性【不需要手动传入依赖,会从回调函数中自动获取】
是否为惰性的
watch 是惰性的 —— 仅当依赖项更改时,才会触发;可以为 watch 传递一个 immediate 属性,使其在初始化时运行
watchEffect 是非惰性的 —— 在创建组件后立即运行,同时,在方法的任何依赖项发生更改时运行
每次监听依赖项时 返回的值
wach —— 每次监听,都会返回新旧值
watchEffect —— 每次监听,只会返回最新的值;只有在页面初始化时,才能拿到一次旧值
watchEffect VS computed
watchEffect 和 watch 一样,都有点像 computed
- computed 注重的计算出来的值(回调函数的返回值),所以必须要写返回值
- watchEffect 注重的是过程(回调函数的函数体),所以不用写返回值
如何使用 watchEffect ?
- 在初始化组件时立即运行(组件初始化时,watchEffect 将运行并记录起始值)
- 在依赖项发生变化时运行(当 监听对象的值 改变时,就会触发 watchEffect)
由第二点可得:在挂载 DOM 之前,尽量不要尝试访问 DOM,防止产生不必要的监听
import { ref, watchEffect } from 'vue'
export default {
setup () {
const userID = ref(233)
watchEffect(() => console.log('userID: ' + userID.value))
setTimeout(() => {
userID.value = 666
}, 500)
return {
userID
}
}
}
// 打印结果
userID: 233
userID: 666也可以在组件中,使用 watchEffect 结合 props 进行使用
export default {
props: {
movieID: String,
},
setup(props) {
watchEffect(() => console.log(props.movieID))
},
}使用 onInvalidate() 清除 watchEffect 副作用
每当 watchEffect 监听到了依赖项变化时,就执行一个异步请求;
但是在异步请求完成之前,依赖项又发生了变化……
如何避免再一次发请求?
export default {
setup() {
watchEffect(onInvalidate => {
// 异步请求
const apiCall = someAsyncMethod(props.songID)
onInvalidate(() => {
// 取消异步请求
apiCall.cancel()
})
})
}
}使用 watchEffect 返回的 stop 方法,停止 watchEffect 监听
可以手动停止 watchEffect 监听
试想一下,如果你想观察一个依赖项,直到他变成某个值,就不希望继续监听了
继续监听属于浪费资源了,如何实现手动停止 watchEffect 监听?
watchEffect 返回了 stop 方法,调用它,可以手动停止 watchEffect 监听
export default {
setup (props) {
let stopWatcher = watchEffect(() => console.log(props.movieID))
stopWatcher()
}
}使用 flush 修改 watchEffect 监听的时机
watchEffect 默认在组件加载好之前,就会调用一次监听,举个栗子:
const state = reactive({
test: {
myName: '',
}
});
state.test.myName = 'Lyrelion'
watchEffect(() => {
console.log('名字被修改了', state.test.myName );
})
/**
* 打印结果(在组件更新前,watchEffect 就执行了一次监听,所以会打印两次)
* 名字被修改了
* 名字被修改了 Lyrelion
*/
如果在组件加载好之前,我不想执行监听呢?也就是说,修改 watchEffect 监听时机
可以通过修改 watchEffect 中的 flush 属性,指定监听时机
flush 有以下三种可设置项:
- pre (默认)
- post (在组件渲染完成后触发,访问加载后的 DOM,这就可以防止初始值还没附上,就开始监听了的问题)
- sync (与 watch 一样,每个更改都强制触发侦听器,这是低效的,应该很少需要)
综上所述,为了在组件加载好之前,不执行监听,可以这么写
const state = reactive({
test: {
myName: '',
}
});
state.test.myName = 'Lyrelion'
watchEffect(() => {
console.log('名字被修改了', state.test.myName );
}, {
flush: 'post'
})
/**
* 打印结果(在组件更新前,watchEffect 就执行了一次监听,所以会打印两次)
* 名字被修改了 Lyrelion
*/
补充一篇写的不错的文章
边栏推荐
- 面向不平衡数据的电子病历自动分类研究
- NFT 的 10 种实际用途
- Crop the large size image of target detection into a fixed size image
- Unity2d -- camera follow
- 基于RoBERTa-wwm动态融合模型的中文电子病历命名实体识别
- 达科为生物IPO过会:年营收8.37亿 吴庆军父女为实控人
- Weice biological IPO meeting: annual revenue of 1.26 billion Ruihong investment and Yaohe medicine are shareholders
- This points to problems, closures, and recursion
- 利用C语言实现URL解析的基本方法之优秀
- Wechat campus laundry applet graduation design finished product of applet completion work (8) graduation design thesis template
猜你喜欢

在灯塔工厂点亮5G,宁德时代抢先探路中国智造

Excellent basic methods of URL parsing using C language

West test Shenzhen Stock Exchange listing: annual revenue of 240million, fund-raising of 900million, market value of 4.7 billion

Interview secrets are widely distributed, and the exclusive secrets of editing, testing and learning are leaked?!

Keras deep learning practice - recommend system data coding

Recursive method to realize the greatest common divisor

Interview eight part essay · TCP protocol
![[training day4] card game [greed]](/img/02/88af03ca5e137eba6cdd778f827f2b.png)
[training day4] card game [greed]

基于C语言的LR1编译器设计

How to make computers have public IP
随机推荐
What are the benefits of taking NPDP
Positive mask, negative mask, wildcard
【图论】负环
How to test and decrypt the encryption interface
基于招聘广告的岗位人才需求分析框架构建与实证研究
Travel notes from July 11 to August 1, 2022
How to make computers have public IP
PCL common operations
Redis implements the browsing history module
[training day4] card game [greed]
CARLA 笔记(04)— Client 和 World (创建 Client、连接 World 、批处理对象、设置 Weather、设置 Lights、World snapshots)
[training day3] delete [simulation]
Unity2d -- camera follow
阿里最新股权曝光:软银持股23.9% 蔡崇信持股1.4%
LeetCode·每日一题·592.分数加减运算·模拟
Wechat campus laundry applet graduation design finished product of applet completion work (3) background function
redis集群搭建-使用docker快速搭建一个测试redis集群
基于STM32的自由度云台运动姿态控制系统
阻塞队列BlockingQueue
There is no need for semantic segmentation of annotation data! Eth & Leuven University proposed maskdistill, using transformer for unsupervised semantic segmentation, SOTA