Vue3.5新增的baseWatch让watch函数和Vue组件彻底分手
前言
在Vue 3.5.0-beta.3版本中新增了一个base watch函数,这个函数用法和我们熟知的watch API一模一样。区别就是我们之前用的watch API是和Vue组件以及生命周期是一起实现的,他们是深度绑定的。而Vue3.5新增的base watch函数是一个新的函数,他的实现和Vue组件以及生命周期没有一毛钱关系。
欧阳写了一本开源电子书vue3编译原理揭秘,看完这本书可以让你对vue编译的认知有质的提升。这本书初、中级前端能看懂,完全免费,只求一个star。
@vue/runtime-core
vue3是模块化设计,他将核心功能拆分为多个独立的模块,如下图:

比如reactivity模块中就是响应式的核心代码、runtime-core模块就是运行时相关的核心代码、compiler-core模块就是编译相关的核心代码。
并且这些模块还被单独当作npm包进行发布,命名规则是@vue+模块名。比如reactivity模块对应的npm包就是@vue/reactivity。如下图:

所以如果我们只需要vue的响应式功能,理论上只需要导入@vue/reactivity包即可。比如我之前的文章: 涨见识了!脱离vue项目竟然也可以使用响应式API,在这篇文章中我就介绍了如何脱离Vue项目,在node.js项目中使用vue的响应式API。
但是不知道你有没有注意到,在demo中我是require("vue"),而不是require("@vue/reactivity")。
因为watch不是由@vue/reactivity中导出的,而是由@vue/runtime-core中导出的,如果我只引入@vue/reactivity就会报错了。
const { ref, watch, watchEffect } = require("vue");
const count = ref(0);
// 模拟count变量的值修改
setInterval(() => {
count.value++;
}, 1000);
watch(count, (newVal) => {
console.log("触发watch", newVal);
});
watchEffect(
() => {
console.log("触发watchEffect", count.value);
},
{
flush: "sync",
}
);
watch的实现是和vue组件以及生命周期深度绑定的,而vue组件以及生命周期明显是和响应式无关的。他们的实现是在runtime-core模块中,而非reactivity模块中,这也就是为什么watch的实现是放在runtime-core模块中。

据说性能是 Taro 10 倍的小程序框架 vuemini 底层也是依靠@vue/reactivity实现的,但是由于watch是由@vue/runtime-core中提供的,小程序框架却只引入了@vue/reactivity,所以作者不得不手写了一个watch函数。

重构watch函数
智子在写Vue Vapor时又拆了一个新的模块,叫做runtime-vapor。如果你不了解Vue Vapor,可以看看我之前的文章: 没有虚拟DOM版本的vue(Vue Vapor)。

他们遇到一个问题需要在runtime-vapor模块中使用watch函数,而watch函数是位于runtime-core模块中。但是又不应该在runtime-vapor模块中直接引用runtime-core模块,所以Vue Vapor团队的绚香音就将watch函数重构到了reactivity模块中,这样在runtime-vapor模块中直接使用reactivity模块中的watch函数就行了。
这也就是为什么需要重构watch函数到reactivity模块中。
在欧阳的个人看法中watch函数本来就是属于响应式中的一部分,他在runtime-core模块中反而不合理。在欧阳第一次看vue3源码时就在奇怪为什么没有在reactivity模块中找到watch函数的实现,而是在runtime-core模块中实现的。
当watch函数重构到reactivity模块后,小程序框架 vuemini 的作者也发了一篇帖子。

watch函数重构到reactivity模块后,小程序框架中手写的watch函数都不需要了,因为reactivity模块已经提供了。
看见完了!这下 Vue Mini 真成 @vue/reactivity 套壳了...这个评论后,对不起!杨明山大佬欧阳确实没忍住笑出了声。
总结
vue3.5版本中,Vue Vapor团队在reactivity模块中重构实现了一个watch函数。重构的这个watch函数和我们现在使用的watch函数用法是一样的,区别在于以前的watch函数的实现和Vue组件以及生命周期是深度绑定的,而重构的watch函数和Vue组件以及生命周期一毛钱关系都没有。
这个改动对于普通开发者可能没什么影响,但是对于下游项目,比如Vue mini来说还是很受益的。因为以前他们需要自己去手写watch函数,现在reactivity提供了后就不需要这些手写的watch函数了。
关注公众号:【前端欧阳】,给自己一个进阶vue的机会

另外欧阳写了一本开源电子书vue3编译原理揭秘,看完这本书可以让你对vue编译的认知有质的提升。这本书初、中级前端能看懂,完全免费,只求一个star。
Vue3.5新增的baseWatch让watch函数和Vue组件彻底分手的更多相关文章
- vue第十单元(动态组件 keep-alive(钩子函数) 递归组件(name) 组件命名约定)
第十单元(动态组件 keep-alive(钩子函数) 递归组件(name) 组件命名约定) #课程目标 熟练掌握动态组件的实现 掌握keep-alive缓存组件,以及相应的钩子函数 熟练掌握递归组件, ...
- react_结合 redux - 高阶函数 - 高阶组件 - 前端、后台项目打包运行
Redux 独立的集中式状态管理 js 库 - 参见 My Git 不是 react 库,可以与 angular.vue 配合使用,通常和 react 用 yarn add redux import ...
- vue学习目录 vue初识 this指向问题 vue组件传值 过滤器 钩子函数 路由 全家桶 脚手架 vuecli element-ui axios bus
vue学习目录 vue学习目录 Vue学习一之vue初识 Vue学习二之vue结合项目简单使用.this指向问题 Vue学习三之vue组件 Vue学习四之过滤器.钩子函数.路由.全家桶等 Vue学习之 ...
- 【vue】vue +element 搭建项目,将js函数变成vue的函数
demo:时间转换 1.目录 <1>在src文件夹下新建文件夹prototypefns--------在此文件夹创建util.js, <2>在prototypefns下新建文件 ...
- Vue 组件 data为什么是函数?
在创建或注册模板的时候,传入一个data属性作为用来绑定的数据.但是在组件中,data必须是一个函数,而不能直接把一个对象赋值给它. Vue.component('my-component', { t ...
- Vue组件里面data为什么必须是个函数
在创建或注册模板的时候,传入一个data属性用来绑定数据,但是在组件中,data必须是一个函数,而不能直接把对象赋值给它. export default { name:'app', data(){ r ...
- Vue 组件 data为什么是函数
在创建或注册模板的时候,传入一个data属性作为用来绑定的数据.但是在组件中,data必须是一个函数,而不能直接把一个对象赋值给它. Vue.component('my-component', { t ...
- 基于VueJS的render渲染函数结合自定义组件打造一款非常强大的IView 的Table
基于VueJS的render渲染函数结合自定义组件打造一款非常强大的IView 的Table https://segmentfault.com/a/1190000015970367
- vue组件中—bus总线事件回调函数多次执行的问题
在利用vue组件进行事件监听时发现,如果对N个vue组件实例的bus总线绑定同一事件的回调函数,触发任意组件的对应事件,回调函数至少会被执行N次,这是为什么呢? 为此,调研了普通对象的事件绑定和触发实 ...
- Vue (表单、斗篷、条件、循环指令,分隔符成员、计算属性成员、属性的监听、vue组件、子组件、各个常见的钩子函数)
表单指令 <!DOCTYPE html> <html lang="zh"> <head> <meta charset="UTF- ...
随机推荐
- ARM+DSP!全志T113-i+玄铁HiFi4开发板硬件说明书(1)
前 言 本文档主要介绍开发板硬件接口资源以及设计注意事项等内容,测试板卡为全志T113-i+玄铁HiFi4开发板.由于篇幅问题,本篇文章共分为上下两集,点击账户可查看更多内容详情,开发问题欢迎留言,感 ...
- 嵌入式必读!瑞芯微RK3568J/RK3568B2开发板规格书
评估板简介 创龙科技TL3568-EVM是一款基于瑞芯微RK3568J/RK3568B2处理器设计的四核ARM Cortex-A55国产工业评估板,每核主频高达1.8GHz/2.0GHz,由核心板和评 ...
- 中间件-Nginx
一.nginx反向代理 输入 http://xxx.com/plat/login 跳转: http://localhost:8383/plat/login 将某个指定的域名代理到指定的服务 http: ...
- Log4Net配置详解及输出自定义消息类示例
1.简单使用实例 1.1 添加log4net.dll的引用. 在NuGet程序包中搜索log4net并添加,此次我所用版本为2.0.17.如下图: 1.2 添加配置文件 右键项目,添加新建项, ...
- MyBatis插件:通用mapper(tk.mapper)
简单认识通用mapper 了解mapper 作用:就是为了帮助我们自动的生成sql语句 通用mapper是MyBatis的一个插件,是pageHelper的同一个作者进行开发的 作者gitee地址:h ...
- python爬取网站图片保存到本地文件夹
爬取的网站 https://wallpaperscraft.com/catalog/anime 爬取代码 # 导包 import os import requests import parsel fr ...
- Stopwatch 类来测量时间间隔
使用 Stopwatch 类来测量时间间隔. 以下是一个示例代码,展示如何记录 Excel 导入的用时: ' 创建 Stopwatch 实例 Dim stopwatch As New Stopwatc ...
- 题解:P8144 [JRKSJ R4] BBWWBB
思路 分析题意可得,白方必定不会胜利,只能尽量让游戏无限进行下去.那么我们只考虑黑方能否胜利. 若想让戏能无限进行下去,必须满足以下条件. 白方先手. 若黑方先手必然可以吃掉一个白方,白方仅有一个棋子 ...
- hbuilderx+香蕉云编生成ios证书和上架教程
现在很多公司都使用uniapp作为底层框架来开发app应用,而uniapp的开发工具hbuilderx云打包的时候,需要证书和证书profile文件. 假如是ios应用,则还需要上架到appstore ...
- [rCore学习笔记 019]在main中测试本章实现
写在前面 本随笔是非常菜的菜鸡写的.如有问题请及时提出. 可以联系:1160712160@qq.com GitHhub:https://github.com/WindDevil (目前啥也没有 批处理 ...