vue3 - watchEffect

2023-11-02

watch、watchEffect 不同点

watchEffect并没有要求你声明被监听的变量,而是,你在执行体里写哪个变量,Vue就收集、监听哪个变量,而且可以同时监听多个变量

const count = ref(0)

watchEffect(() => console.log(count.value))
// -> logs 0 组件初始化的时候就会执行一次

setTimeout(() => {
  count.value++
  // -> logs 1 依赖发生变化在执行
}, 100)
  • 第一点我们可以从示例代码中看到 watchEffect 不需要指定监听的属性,他会自动的收集依赖, 只要我们回调中引用到了 响应式的属性, 那么当这些属性变更的时候,这个回调都会执行,而 watch 只能监听指定的属性而做出变更(v3开始可以同时指定多个)。

  • 第二点就是 watch 可以获取到新值与旧值(更新前的值),而 watchEffect 是拿不到的。

  • 第三点是 watchEffect 如果存在的话,在组件初始化的时候就会执行一次用以收集依赖(与computed同理),而后收集到的依赖发生变化,这个回调才会再次执行,而 watch 不需要,因为他一开始就指定了依赖。

  • 在watchEffect里操作响应式数据,不会引起无限循环监听,这虽然很显而易见,但是也在此说一句。

  • 多个watchEffect的执行顺序是watchEffect的书写顺序。

  • watchEffect是立即执行的,所以组件初始化的时候就全部执行了一遍

 watchEffect(() => {
      console.log('b:', s.value.b);
    });
    watchEffect(() => {
      console.log('a - b:', s.value.a + '-' + s.value.b);
    });
    watchEffect(() => {
      console.log('value:', s.value);
    });

停止侦听

自动停止
先说watchEffect生命周期的开始,是从组件的setup()函数或生命周期钩子被调用时开始。自动停止是在组件卸载时自动停止。

手动停止
将watchEffect赋值给变量,执行这个变量即可手动停止。比如:

const xx = watchEffect(() => {
  console.log('a:', s.value.a);
  s.value.a += 10
});
// 后来某个时间执行了:
xx(); // 停止监听
const stop = watchEffect(() => {
  /* ... */
})

// later
stop()

effect 副作用

副作用主要有:DOM更新、watchEffect、watch、computed、、、、

你没看错,既然更新视图层才是主作用,那么视图层更新到DOM上在Vue眼里是副作用,而且,变更响应式数据触发执行computed和触发执行watchEffect当然也是副作用。所以watchEffect本身就是副作用。

onInvalidate(fn)传入的回调会在 watchEffect 重新运行或者 watchEffect 停止的时候执行

watchEffect(() => {
      // 异步api调用,返回一个操作对象
      const apiCall = someAsyncMethod(props.userID)
      onInvalidate(() => {
        // 取消异步api的调用。
        apiCall.cancel()
      })
})


清除副作用是什么意思
例子
比如你有一个页码组件,里面有5个页码,点击就会异步请求数据。于是我就做了一个监听,监听当前页码,只要有变化就ajax一次。

现在问题是,如果我点击的比较快,从1到5全点了一遍,那么会有5个ajax请求,最终页面会显示第几页的内容?你说第5页?那你是假定请求第5页的ajax响应的最晚,事实呢?并不一定。于是这就会导致错乱。还有一个问题,我连续快速点5次页码,等于我并不想看前4页的内容,那么是不是前4次的请求都属于带宽浪费?这也不好。于是官方就给出了一种解决办法:

可用防抖或者节流

或者用watchEffect提供取消副作用的接口,也就是onInvalidate方法。Invalidate中文译义是作废,onInvalidate也就是作废监听器。

import{ 
    watchEffect, 
    ref,
    createApp,
} from "vue"

// 查询数据
function fetchData(pageSize, limit){
    return new Promise(resolve => {
        // 模拟查询数据需要的时间
        setTimeout(() => {
            resolve(`查询第 ${pageSize} 页, 每页数量 ${limit}`)
        }, 3000)
    })
}

let app = createApp({
    setup(){
        let pageSize = ref(1);
        let limit = ref(10);
        let list = ref(null);

        watchEffect(async (onInvalidate) => {
            let cancel = false;
            onInvalidate(() => {
                cancel = true;
            })
            let result = await fetchData(pageSize.value, limit.value)
            // 已经失效就不更新
            if(cancel) return ;
            list.value = result;
        })

        return {
            pageSize,
            limit,
            list,
        }
    },

注意: 如副作用中设计到DOM的操作和ref的获取,watchEffect需要放到mounted周期中执行
onMounted(() => {
watchEffect(() => { // … 操作dom或ref等 })
})

Vue 的响应性系统会缓存副作用函数,并异步地刷新它们,这样可以避免同一个“tick”中多个状态改变导致的不必要的重复调用
同一个“tick”的意思是,Vue的内部机制会以最科学的计算规则将视图刷新请求合并成一个一个的"tick",每个“tick”刷新一次视图,比如a=1;b=2;只会触发一次视图刷新。$nextTick的Tick就是指这个。

watchEffect的执行时机

//如:<h2 ref="x"></h2> 
import {watchEffect,ref} from 'vue'
setup(){
    const x=ref(null) //将这个ref绑定到指定标签或组件上
    watchEffect(()=>{
        console.log(x)
    })
    return {
     x
    }
}
  • 此时会打印两个结果,第一次为null,第二次才为h2元素,这是因为setup函数在执行时就会立即执行传入的副作用函数,这个时候DOM并没有挂载,所以打印为null
  • 而当DOM挂载时,会给x的ref对象赋值新的值,副作用函数会再次执行,打印出来对应的元素
  • 调整watchEffect的执行时机,如果我们希望在第一次的时候就打印出来对应的元素呢?
  • 这个时候我们需要改变副作用函数的执行时机:它的默认值是pre,调整为post
 watchEffect(()=>{
        console.log(x)
    },{
        flush:'post'  //在组件更新完成之后操作
        
    }) 

Vue 2使用this.$nextTick()去获取组件更新完成之后的DOM,和上面是一个意思。

options

{ flush: “pre” | “post” | “sync”}
选项参数可以决定handler执行的时机
pre 在组件更新之前操作
post 在组件更新完成之后操作
sync 同步操作

watchEffect、computed 的不同

computed和watchEffect相同的地方是会自动收集依赖,在值更新时会触发回调,会初始化调用一次。但是在触发初始化的时机是不一样的 ,如果computed的值没有被使用,是不会触发回调的,只有在该值被使用的时候才会触发回调,但watchEffect是在setup的时候就会初始化。

Vue 3 watch

官方说,watch也有停止侦听,清除副作用、副作用刷新时机和侦听器调试行为

Vue 3 computed特点:

Vue 3跟Vue 2的computed的差别在于,Vue 2是所有计算属性都是根对象的属性,Vue 3是计算属性都是独立变量

  • computed默认接收getter函数,也可以接收一个对象,对象里有get和set方法。set方法接收一个val参数。初学者可能会忘记写getter函数,只写计算表达式,要注意这点。
  • computed一定返回ref对象,所以并不需要在计算函数里给返回值添加响应式,这属于画蛇添足。

参考1

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

vue3 - watchEffect 的相关文章

  • 如何让Gmail像加载进度条一样

    我想在页面的中心和顶部创建一个像 Gmail 一样的加载进度条 并适用于所有浏览器 这是基本代码
  • 在随机位置启动 HTML5

    我有一个大约 2 小时长的音轨 我想在我的网站上使用它 我希望它在页面加载时在随机位置开始播放曲目 使用 HTML5 可以吗 我知道您可以使用 element currentTime 函数来获取当前位置 但是如何在完全下载之前获取曲目的总时
  • Mapbox GL 中的 MaxBounds 和自定义非对称填充

    我有一个 Mapbox GL JS 应用程序 在地图上显示一些小部件 为了确保地图上的任何内容都不会被它们隐藏 我使用以下命令添加了一些填充map setPadding 这是一个不对称的 在我的例子中左边比右边大 它按预期工作 例如fitB
  • 设置双指缩放时精确的滚动位置

    我正在创建一个地图应用程序 它将标记图像放置在画布上并滚动到它 我正在使用浏览器的捏缩放和滚动来放大 缩小地图 然而 我注意到有一些奇怪的行为 我想知道如何解决它 这有点难以解释 但我们开始吧 假设您处于网页的标准缩放级别 无法进一步缩小
  • jQuery输入文件点击方法和IE上拒绝访问

    我尝试仅使用一个按钮作为输入文件 它在 Firefox Chrome Safari 中工作正常 但在 IE 中不行 提交表单时我总是收到 访问被拒绝 的消息 代码 input file click 有真正的解决方法吗 我在谷歌上浪费了大约2
  • Nodejs 调试生产中的错误

    我有一个在生产环境中运行的 Nodejs 脚本 我不太可能 千分之一 遇到这样的错误 TypeError value is out of bounds at checkInt buffer js 1009 11 at Buffer writ
  • 如何在 React Native 上显示 SVG 文件?

    我想显示 svg 文件 我有一堆 svg 图像 但我找不到显示的方式 我尝试使用Image and Use的组成部分反应本机 svg https github com magicismight react native svg但他们不这样做
  • C# 和 Javascript SHA256 哈希的代码示例

    我有一个在服务器端运行的 C 算法 它对 Base64 编码的字符串进行哈希处理 byte salt Convert FromBase64String serverSalt Step 1 SHA256Managed sha256 new S
  • Node.js 升级在 Windows 中仍然显示旧版本

    我已使用 msi 安装程序下载并安装了新版本的 nodejs 4 1 2 之后我跑了node v 但它仍然显示旧版本 0 12 2 我尝试重新启动Windows 甚至卸载nodejs并重新安装它 但仍然显示相同的内容 为什么会发生这种情况
  • 全局传递 xhr onload 函数的值

    在我正在创建的应用程序中 我有以下 XMLHttpRequest 并且我正在尝试传递结果data在 的里面xhr onload 到在同一父函数中创建的数组中 var url http api soundcloud com resolve j
  • 如何在 Web 服务器上设置 gzip 压缩?

    我有一个嵌入式网络服务器 总共有 2 兆空间 通常 您使用 gzip 文件对客户端有利 但这会节省我们在服务器上的空间 我读到你可以只 gzip js 文件并将其保存在服务器上 我在 IIS 上测试过 但没有任何运气 为了使这项工作成功 我
  • 如何使用 window.onerror 捕获所有 javascript 错误? (包括道场)

    这个问题是后续问题javascript 如何在弹出警报中显示脚本错误 https stackoverflow com questions 2604976 javascript how to display script errors in
  • 模板中带有 ng-if 的 angularjs 指令

    我正在构建一个在模板内使用 ng if 的指令 奇怪的是 提供给链接函数的元素没有扩展ng if代码 它只是ng if的注释行 经过一番尝试 我发现通过将链接代码包装在 timeout 中似乎可以使其正常工作 但我想知道这是否不是正确的处理
  • webpack中动态加载外部模块失败

    我正在尝试建立以下架构 一个核心 React 应用程序 它具有一些基本功能 并且能够在运行时加载其他 React 组件 这些额外的 React 组件可以按需加载 并且它们在构建核心应用程序时不可用 因此它们不能包含在核心应用程序的捆绑包中
  • 如何使用新的analytics.js跟踪多个帐户?

    我需要使用 Google 的新的analytics js 跟踪一个页面上两个帐户的综合浏览量 有大量教程和示例如何使用较旧的 ga js 进行操作 但我发现的只是这个分析文档页面 https developers google com an
  • javascript 是否有等效的 __repr__ ?

    我最接近Python的东西repr这是 function User name password this name name this password password User prototype toString function r
  • 尝试安装 LESS 时出现“请尝试以 root/管理员身份再次运行此命令”错误

    我正在尝试在我的计算机上安装 LESS 并且已经安装了节点 但是 当我输入 node install g less 时 出现以下错误 并且不知道该怎么办 FPaulMAC bin paul npm install g less npm ER
  • 我可以使用 ASP.NET WebForms 母版页在每个内容页中包含不同的 javascript/css 文件吗?

    我有几个使用相同母版页的内容页 它们并不都需要包含在相同的 javascript 和 css 文件中 tag 是否可以更改内容来自内容页面的标签 确实如此 但我建议采取一些不同的做法 我在关闭正文标签的正上方放置了一个内容占位符 然后我填充
  • Jwt 签名和前端登录身份验证

    我有这个特殊的 jwt sign 函数 Backend const token jwt sign id user id process env TOKEN SECRET expiresIn 1m res header auth token
  • Chrome 扩展:强制 popup.html 关闭

    我想知道是否可以强制 popup html 关闭 在弹出的 javascript 中 window close

随机推荐

  • 计算机系统 实验四(课程实验LAB四)

    实验中需要的几个控制语句 u userid 使用这个语句是要确保不同的人使用不同的 ID 做题 并攻击不同的地址 h 用于打印这几个操作的内容 n 用于 Level4 关卡 s 用于提交你的解决方案到服务器中 1 根据makecookie生
  • mysql ERROR 1045 (28000): Access denied for user ‘ODBC‘@‘localhost‘ (using password: YES)

    遇到这个问题搞了很久 自己记下来 方法是百度的 亲测有效 ERROR 1045 28000 Access denied for user ODBC localhost using password NO ERROR 1045 28000 A
  • 按照lockattribute来划分MESH

    网格模型基础 网格模型 一 定义 二 子集和属性缓存 2 0 子集 2 1 属性 2 2 操作 三 邻接信息 四 属性表 五 优化 六 网格的创建与绘制 6 1 创建 6 2 绘制 一 定义 网格模型是一种将物体的顶点数据 纹理 材质等信息
  • Linux内核scripts/Makefile.build文件结构

    1 默认目标 build 2 初始化obj y obj m等变量 3 include include config auto conf 内含CONFIG RING BUFFER y等变量列表 4 include scripts Kbuild
  • vue+element动态设置el-menu导航,刷新页面保持当前菜单选中项及路由

    今天闲来无事整理了一套后台管理系统的侧边栏菜单 实现了页面刷新路由保持不变和菜单也是当前点击的高亮状态 来一起看看吧 首先 菜单数据是动态的 注意的是 id 和 路由的 name保持一致 页面刷新要用到 一级菜单不用name 因为没用到路由
  • Android开机自启动添加

    1 添加需要自启动的可以执行文件 1 可执行C文件 system core init start needInitStartService c 例如 include
  • 基于大数据的python爬虫的菜谱美食食物推荐系统

    众所周知 现阶段我们正处于一个 大数据 时代 从互联网上大量的数据中找到自己想要的信息变得越来困难 搜索引擎的商业化给市场带来了百度和谷歌这样的商业公司 网络爬虫便是搜索引擎的重要组成部分 本课题是基于Python设计的面向下厨房网站的网络
  • edge浏览器打开多个网页卡顿解决办法

    edge有时候打开了十几个页面就大量占据内存了 卡的不行 上网汇总了解决方法 具体参考以下两篇文章 一个是通过edge浏览器自身的设置修改 一个是关闭gpu相关的图形加速插件 按照以下两篇文章的方法基本就不会卡了 1 解决win10系统ed
  • Redis 与 Lua 脚本

    这篇文章 主要是讲 Redis 和 Lua 是如何协同工作的以及 Redis 如何管理 Lua 脚本 Lua 简介 Lua 以可嵌入 轻量 高效 提升静态语言的灵活性 有了 Lua 方便对程序进行改动或拓展 减少编译的次数 在游戏开发中特别
  • 16行 python代码获取音效素材

    人生苦短 我用python 声音素材资源 源码资料电子书 点击此处跳转文末名片获取 所需环境 开发环境 Python 环境 Pycharm 编辑器 模块 requests re 流程讲解 首先我们打开网址后右键选择检查 选择network
  • Visual Studio 自动补全代码

    自动补全两种方式 1 写完下面代码 双击Tab 自动补全 2 写完下面代码 回车 单击Tab 自动补全 可以在vs中自行查看 ctor 自动补全构造函数 prop 自动实现属性 cw Console WriteLine switch 自动补
  • 【边喝caffee边Caffe 】(三) Check failed: registry.count(t ype) == 1 (0 vs. 1) Unknown layer type

    自己建立一个工程 希望调用libcaffe lib 各种配置好 也能成功编译 但是运行就会遇到报错 F0519 14 54 12 494139 14504 layer factory hpp 77 Check failed registry
  • OCSVM 学习笔记

    OCSVM 学习笔记 前言 OCSVM OneClass SVM 算法是一种经典的异常检测算法 基本原理与 SVM 类似 与 SVM 关注的二分类问题不同的是 就像它的名字 OneClass SVM 那样 OCSVM 只有一个分类 这也正是
  • Excel每页都打印表头

    前言 有时候表格打印时 需要每页都打印表头 但是表格默认是只打印第一页的表头 那该如何设置呢 步骤 切换到 页面布局 打印标题 在 顶端标题行 中右侧可以选择你要打印的标题行 点击确定就欧克了 多行标题就选中多行就行 如 第1行到第3行 所
  • 上岸了,不写代码了

    上岸了 目前不搞这些东西了 不出意外的话应该不会再回来更新和回复了 各位 江湖再见
  • BugKu-Web-矛盾

    BugKu Web 矛盾 题目链接 https ctf bugku com challenges detail id 72 html 考点 PHP弱类型比较漏洞 题目源码分析 num GET num 定义一个num变量用get方法接收 if
  • VUE-鼠标移入到目标区域变成小手模样

    这是测试提的一个需求 当鼠标移入点击更多时 鼠标指针变成小手模样 其实这个东西特别简单 只是用的不多平常 我们只需要给目标区域的style样式中加入 cursor pointer 这个鼠标就好了
  • vue文件无法正常build

    如图所示 run serve后控制台没有报错 但是运行到此处直接结束 解决办法 暴力解决 直接删除node module 再输入cnpm install重新安装依赖 重新安装完成后成功运行
  • CeiT:训练更快的多层特征抽取ViT

    GiantPandaCV导语 来自商汤和南洋理工的工作 也是使用卷积来增强模型提出low level特征的能力 增强模型获取局部性的能力 核心贡献是LCA模块 可以用于捕获多层特征表示 引言 针对先前Transformer架构需要大量额外数
  • vue3 - watchEffect

    watchEffect watch watchEffect 不同点 停止侦听 effect 副作用 watchEffect的执行时机 watchEffect computed 的不同 Vue 3 watch Vue 3 computed特点