涨见识了!脱离vue项目竟然也可以使用响应式API
前言
vue3的响应式API大家应该都特别熟悉,比如ref
、watch
、watchEffect
等。平时大家都是在vue-cli
或者vite
创建的vue项目里面使用的这些响应式API,今天欧阳给大家带来一些不一样的。脱离vue项目,在node.js
项目中使用vue的响应式API。
关注公众号:【前端欧阳】,给自己一个进阶vue的机会
直接上代码
话不多说,直接上代码。这个是我在本地新建的一个最简单的node.js
项目,如下图:
从上图可以看到我们的node.js
项目依赖只有一个:vue
。并且提供了一个名为dev的脚本命令,这个脚本命令实际是在node环境内执行index.js
文件。
我们来看index.js
文件,代码如下:
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",
}
);
为了标明index.js
文件是在node.js
环境中运行的,所以这里我特地使用require
去导入vue导出的ref
、watch
、watchEffect
这三个响应式API。
并且我们还模拟了修改count
响应式变量值的操作,使用setInterval
每隔一秒让count
的值+1
。
在vue项目中一样使用watch
和watchEffect
去监听count
变量的值。
在终端执行yarn dev
,也就是执行node index.js
,如下图:
从上图中可以看到在node.js
中的执行结果和预期是一模一样的。
为什么可以这样写呢?
前面的那个例子是一个node.js
项目,项目中我们并没有像vue项目那样去创建一个vue组件,然后在组件里面去使用响应式API。而是直接在一个普通的node.js
文件中使用vue暴露出来的响应式API,并且watch
和watchEffect
在监听的值改变后同样触发了对应的watch回调,那么这个又是怎么做到的呢?
这得益于vue3优秀的模块化设计,他将核心功能拆分为多个独立的模块,如下图:
比如reactivity
模块中就是响应式的核心代码、compiler-core
模块就是编译相关的核心代码。
并且这些模块还被单独当作npm包进行发布,命名规则是@vue+模块名
。比如reactivity
模块对应的npm包就是@vue/reactivity
。如下图:
得益于模块化的设计,响应式相关的API和vue组件并没有强关联的关系,所以我们可以在node.js
应用中去直接使用响应式API。
这里使用到了三个响应式API,分别是:ref
、watch
和watchEffect
。在vue组件中的响应式的实现原理大家多多少少都有所听闻,其实在node.js
项目中实现原理也是一样的,接下来我们讲讲是如何实现响应式的。
在我们这个demo中count
是一个ref的响应式变量,当我们对count
变量进行读操作时会触发get
拦截。当我们对count
变量进行写操作时会触发set
拦截。
在我们这里使用watch
和watchEffect
的代码是下面这样的:
watch(count, (newVal) => {
console.log("触发watch", newVal);
});
watchEffect(
() => {
console.log("触发watchEffect", count.value);
},
{
flush: "sync",
}
);
当代码首次执行到watch
和watchEffect
时都会对count
变量进行读操作,并且watch
和watchEffect
都传入了一个回调函数。
由于对count
变量进行读操作了,所以就会触发get
拦截。在get
拦截中会将当前watch的回调函数作为依赖收集到count
变量中。收集的方式也很简单,因为count
变量是一个对象,所以使用对象的dep
属性进行依赖收集。因为dep
属性是一个集合,所以可以收集多个依赖。
在我们这里watch
和watchEffect
都触发了count
变量的get拦截,所以watch
和watchEffect
的回调函数都被count
变量进行了依赖收集。
当修改count
变量的值时会触发set
拦截,在set
拦截中做的事情也很简单。将count
变量收集到的依赖全部取出来,然后执行一遍。这里收集的依赖是watch
和watchEffect
的回调函数,所以当count
变量的值改变时会导致watch
和watchEffect
的回调函数重新执行。
这个是整个流程图:
从流程图可以看到响应式的实现原来完全不依赖vue组件,所以我们可以在node.js
项目中使用vue的响应式API,这也是vue的设计奇妙之处。
总结
这篇文章讲了我们可以脱离vue项目,直接在node.js
项目中使用vue的响应式API。接着讲了响应式的实现原理其实就是依靠get
拦截进行依赖收集,set
拦截进行依赖触发。
搞清楚响应式原理后,我们发现响应式完全不依赖vue组件,所以我们可以在node.js
项目中使用vue的响应式API,这也是vue的设计奇妙之处。
关注公众号:【前端欧阳】,给自己一个进阶vue的机会
涨见识了!脱离vue项目竟然也可以使用响应式API的更多相关文章
- 【Vue高级知识】细谈Vue 中三要素(响应式+模板+render函数)
[Vue高级知识]细谈Vue 中三要素(响应式+模板+render函数):https://blog.csdn.net/m0_37981569/article/details/93304809
- vue项目使用vue-amap调用高德地图api详细步骤
想要的效果如下 : 高德地图 && 信息窗体 步骤一: 申请高德key 高德开放平台 | 高德地图API (amap.com) (可参考博客: [996]如何申请高德地图用户Key ...
- 【Vue源码学习】响应式原理探秘
最近准备开启Vue的源码学习,并且每一个Vue的重要知识点都会记录下来.我们知道Vue的核心理念是数据驱动视图,所有操作都只需要在数据层做处理,不必关心视图层的操作.这里先来学习Vue的响应式原理,V ...
- Vue.2.0.5-深入响应式原理
大部分的基础内容我们已经讲到了,现在讲点底层内容.Vue 最显著的一个功能是响应系统 -- 模型只是普通对象,修改它则更新视图.这会让状态管理变得非常简单且直观,不过理解它的原理以避免一些常见的陷阱也 ...
- Vue.js学习 Item12 – 内部响应式原理探究
深入响应式原理 大部分的基础内容我们已经讲到了,现在讲点底层内容.Vue.js 最显著的一个功能是响应系统 —— 模型只是普通对象,修改它则更新视图.这让状态管理非常简单且直观,不过理解它的原理也很重 ...
- 读Vue源码二 (响应式对象)
vue在init的时候会执行observer方法,如果value是对象就直接返回,如果对象上没有定义过_ob_这个属性,就 new Observer实例 export function observe ...
- 深入浅出Vue基于“依赖收集”的响应式原理(转)
add by zhj: 文章写的很通俗易懂,明白了Object.defineProperty的用法 原文:https://zhuanlan.zhihu.com/p/29318017 每当问到VueJS ...
- vue新增属性是否会响应式更新?
原文地址 在开发过程中,我们时常会遇到这样一种情况:当vue的data里边声明或者已经赋值过的对象或者数组(数组里边的值是对象)时,向对象中添加新的属性,如果更新此属性的值,是不会更新视图的. 根据官 ...
- 项目总结一:响应式之CSS3 媒体查询
1.<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scala ...
- vue源码解析之响应式原理
关于defineReactive等使用细节需要自行了解 一些关键知识点 $mount时 会 new Watcher 把组件的 updateComponent 方法传给watcher 作为getter ...
随机推荐
- 为WPF框架Prism注册Nlog日志服务
这篇文章介绍了为WPF框架Prism注册Nlog日志服务的方法,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧 无论是Nlog还是Serilog, 它们都提供 ...
- request to https://registry.npm.taobao.org/cnpm failed, reason: certificate has expired
换华为的,否则会出问题:cnpm confg set registry https://mirrors.huaweicloud.com/repository/npm/ npm ERR! code CE ...
- 系统镜像烧写及U-Boot编译
1 系统镜像烧写 1.1 工具介绍 烧写软件:使用NXP的MfgTool2工具烧写,工具路径:[正点原子]阿尔法Linux开发板(A盘)-基础资料\05.开发工具\04.正点原子MFG_TOOL出厂固 ...
- Qt下载、安装及环境搭建
1 下载 刚开始去的官网下载,需要注册账号,而且还比较麻烦,后来找到了一个安装包的链接,直接下载就好了:http://mirrors.ustc.edu.cn/qtproject/archive/qt ...
- ASP.NET MVC 出现: Uncaught ReferenceError: $ is not defined
ASP.NET MVC 出现: Uncaught ReferenceError: $ is not defined 错误 将 _Layout.cshtml 中的三行代码,移动到 <head> ...
- 编程语言界的丐帮 C#.NET 国密数字信封 民生银行
民生银行的库DLL只有C版本和JAVA版本.按着JAVA版本做的C# 实现. 重点内容. 1.数字信封就是 CmsEnvelopedData Der编码后转BASE64 2.重点类:ContentIn ...
- windows 通过cmd命令(netsh wlan命令)连接wifi
引用:https://www.cnblogs.com/moonbaby/p/11188135.html 1)显示本机保存的profiles,配置文件是以wifi的ssid命名的. netsh wlan ...
- 使用 eBPF 在云中实现网络可观测性
可观测性是一种了解和解释应用当前状态的能力,也是一种知道何时出现问题的方法.随着在 Kubernetes 和 OpenShift 上以微服务形式进行云部署的应用程序越来越多,可观察性受到了广泛关注.许 ...
- Go版RuoYi
RuoYi-Go https://github.com/Kun-GitHub/RuoYi-Go 1. 关于我 个人介绍 2. 介绍 后端用Go写的RuoYi权限管理系统 (功能正在持续实现)后端 G ...
- redshift DATE_TRUNC函数 查询日期上个月的26号到当前月的26号
redshift DATE_TRUNC函数 查询日期上个月的26号到当前月的26号 # redshift脚本 # 2023-08-01 00:00:00.000 select DATE_TRUNC(' ...