一,概述
watchEffect
,它立即执行传入的一个函数,同时响应式追踪其依赖,并在其依赖变更时重新运行该函数。
也就是说,wactheffect会自动收集函数中的响应式依赖,并且初始化运行一次该函数(相当于watch开启了immediate:true)
二,watcheffect的依赖收集
watcheffect的依赖收集和computed一样,当传入的函数中,有响应式数据时,它会自动把所有的响应式数据收集起来作为依赖。当其中的某个数据发生了变化,则会重新执行传入的函数。
import {
ref, reactive, watch, watchEffect } from 'vue'; const single = reactive({
count: 1, test: {
a: 1, b: 2 } }); const handleClick = function () {
single.test.a++; }; watchEffect(() => {
console.log('-----', single.test.a); });
当初始化的时候,执行了一次。而后其中的响应式数据single.test.a每次变更,都会触发函数执行一次。
值得注意的是,watcheffect只能获取到最新的值(在函数中直接访问),而不像watch那样可以拿到新值和旧值。
三,watcheffect函数执行的时机
<template> <div class="mine-box"> <div ref="countDom">{
{
single.test.a }}</div> <button @click="handleClick">按钮</button> </div> </template> <script setup> import {
ref, reactive, watch, watchEffect } from 'vue'; const single = reactive({
count: 1, test: {
a: 1, b: 2 } }); const countDom = ref(null); const handleClick = function () {
single.test.a++; }; watchEffect(() => {
console.log(countDom.value); console.log('-----', single.test.a); }); </script> <style> .mine-box {
text-align: center; } </style>
可以看到,初始化依赖收集的时候,打印的会是个null,而后续则能拿到更新后的dom。
也就是说:
1,初始化watcheffect收集依赖,是拿的响应式数据的初始值。所以这时候操作dom啊啥的是会报错的。 2,后续依赖项变更,,则是在dom更新完毕之后才执行回调函数,拿到的dom是最新的dom。 3,有多个依赖项同步变更,回调函数只会执行一次。
四,watcheffect的停止监听
通过显示调用返回值停止侦听 组件被卸载时隐式调用了停止侦听
1,通过显示调用返回值停止侦听
import {
reactive, watchEffect } from 'vue'; const single = reactive({
count: 1, test: {
a: 1, b: 2 } }); const handleClick = function () {
single.test.a++; }; const stop = watchEffect(onInvalidate => {
console.log('--监听执行---', single.test.a); if (single.test.a > 5) {
stop(); } });
watcheffect可以返回一个停止监听的函数,在合适的时机执行这个函数,可以显示地停止watcheffect的监听。
2,组件被卸载时隐式调用了停止侦听
watchEffect
所在的组件被卸载时会隐式调用stop
函数停止侦听。
五,watcheffect传入函数的入参: onInvalidate
函数
watchEffect
侦听副作用传入的函数可以接收一个 onInvalidate
函数作为入参,用来注册清理失效时的回调。当以下情况发生时,这个失效回调会被触发:
副作用即将重新执行时(即依赖的值改变) 通过显示调用返回值停止侦听(上文已经有了) 组件被卸载时隐式调用了停止侦听
依赖发生改变,函数即将执行时执行
import {
ref, reactive, watch, watchEffect } from 'vue'; const single = reactive({
count: 1, test: {
a: 1, b: 2 } }); const handleClick = function () {
single.test.a++; }; watchEffect(onInvalidate => {
console.log('-----', single.test.a); onInvalidate(() => {
console.log('执行了onInvalidate'); }); });
点击按钮一次,打印结果如下:
----- 1 执行了onInvalidate ----- 2
可以看到,值变成2之后,是先执行这个onInvalidate的函数参数。
2,通过显示调用返回值停止侦听
import {
reactive, watchEffect } from 'vue'; const single = reactive({
count: 1, test: {
a: 1, b: 2 } }); const handleClick = function () {
single.test.a++; }; const stop = watchEffect(onInvalidate => {
console.log('--监听执行---', single.test.a); if (single.test.a > 5) {
stop(); } onInvalidate(()=>{
console.log("因为停止监听而执行") }) });
可以在控制台看到,当stop()停止监听后,还会执行一次onInvalidate的函数。
3,组件被卸载时
这里可以理解为,是组件卸载时隐式调用stop停止监听,从而触发了这个onInvalidate的调用。
六,watcheffect和computed的区别
同:
都是依赖收集后,依赖变更就会执行回调函数。
不同:
依赖收集 | 返回 | |
---|---|---|
watcheffect | 初始化时就收集,并立即执行回调函数 | 返回停止监听的函数(可以没有返回) |
computed | 初始化时收集,默认当依赖有变更才执行回调函数 | 返回的是计算属性值(必须有返回) |
版权声明:
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若内容造成侵权、违法违规、事实不符,请将相关资料发送至xkadmin@xkablog.com进行投诉反馈,一经查实,立即处理!
转载请注明出处,原文链接:https://www.xkablog.com/qdvuejs/10968.html