- ubuntu12.04环境下使用kvm ioctl接口实现最简单的虚拟机
- Ubuntu 通过无线网络安装Ubuntu Server启动系统后连接无线网络的方法
- 在Ubuntu上搭建网桥的方法
- ubuntu 虚拟机上网方式及相关配置详解
CFSDN坚持开源创造价值,我们致力于搭建一个资源共享平台,让每一个IT人在这里找到属于你的精彩世界.
这篇CFSDN的博客文章升级 Vue3 大幅提升开发运行效率由作者收集整理,如果你对这篇文章有兴趣,记得点赞哟.
。
原计划 2019 年发布的 Vue3,又经过一年的再次打磨,终于于去年 9 月正式发布。随后,不少 UI 组件库都积极参与适配,去年 12 月,Element-plus(Element-ui 官方升级版)也发布了 beta 版.
由于项目中用到了 Element-ui 组件,组件库未适配的情况下,不敢贸然升级 Vue3。Element-plus 发布后,又经过 1 个月的观察、测试和调研,发现 Element-plus 相对成熟(还有少量 bug,后续会讲),便开始尝试升级 Vue3.
。
有两种方案可以快速升级 Vue3:
之所以会有方案一,主要还是担心 Element-plus 不够稳定,如果有天坑,又无法绕过去,除了向饿了么团队提交 PR,微前端兜个底也是不错的应急措施.
就这样微前端方案又运行了 1 个月,部分页面已完成升级,运行良好,实践证明 Element-plus 比想象中稳定,这增加了我对于方案二的信心。考虑到还有少量业务复杂的页面,在微前端模式下,子项目的各种数据多经过一层 qiankun 的 proxy 代理,性能有损耗,影响了页面更新,于是一次性将剩余的页面全部迁移到 Vue3 项目中.
实践证明,除非比较复杂的项目,或者依赖组件库没升级等原因不适合升级外,常规情况下,升级 Vue3 都是一个不错的选择.
。
为什么要升级 Vue3,这是一个几乎不需要回答的问题。升级 Vue3 后,代码结构更加清晰内聚,响应式数据流更加可控,节省了很多心智成本,从而使得开发效率大幅提升。Vue3 还带来了很多新特性,框架层面运行性能更高(性能提升了 1.3 至 2 倍,SSR 性能提升了 2 至 3 倍),Composition API 使得代码拆分,函数封装更容易,复杂项目也随之更容易管理.
Vue2 中,相关的逻辑经常分散在 option 的 data、watch、computed、created、mounted 等钩子中,阅读一段代码,经常需要上下反复横跳,带来了部分阅读障碍。钩子又依赖 Vue 实例,代码封装基于天生携带钩子的 Mixin 去做,更加容易和相对方便.
但正因为如此,Mixin 的钩子容易不自觉的越界,插手到页面或组件的内部变量和方法管理过程中;甚至,多个不同的 Mixin,相互之间就很容易冲突,项目开发者,在引入 Mixin 和避免冲突之间需要保持微妙的平衡,不但增加心智负担,还带来了副产品:本身扑朔迷离的 this 变得更加不确定。因此,大型项目 Mixin 几乎都是一种反模式.
现在这些框架问题,都由 Vue3 的 Composition API 解决了.
。
我们先看一些立马能感受到变化的特性.
Proxy 代理 。
这是一个一上手 Vue3 就能感知的变化。即使你在 Vue3 中编写 Vue2 风格的基于 option 的代码,Proxy 也是默默提供着数据响应式.
如上所示,Vue2 的数据响应式是通过 Object.defineProperty 实现,这是一个深度遍历的过程,无论 data 中包含多少层数据,都需要全部遍历一遍。深度遍历,给对象的每个自身属性添加 defineProperty,需要不小的性能开销,同时后面新增到 this 中的属性不提供响应式监听,因此我们需要使用诸如this.$set这种方式去添加新属性.
Proxy 就没有这个问题,如下所示.
Proxy 不但使得 data 获得了新属性的响应性,整个响应式处理过程的效率还提升了数倍,由此带来了 Vue3 的大部分性能提升.
Composition API 。
为了保持对 Vue2 的向下兼容,Vue3 中仍然支持纯 Option 配置的书写方式,这为升级提供了便利,平移 Vue2 的代码,只需少量改动,便可正常运行.
同时考虑到上手难度,Vue3 的顶层代码风格与 Vue2 保持一致,依然是 export 一个对象,对象包含了一系列的配置,其中便有 setup 入口函数。我们先来看一段代码,然后逐个解读.
setup 作为入口函数,包含两个参数,分别是响应式的 props 外部参数,以及 context 对象,context 包含 attrs、emit、expose、props、slots 五个参数,如下所示:
在 Vue3 的设计里,setup,以及从 vue 对象中解构出来的各种生命周期函数,执行优先级高于 Vue2 中的各种生命周期钩子,因此 。
这段代码的输出依次是 setup、beforeCreate、created.
ref、reactive 。
setup 中,第一句const selectRef = ref(null);,这里定义的是一个响应式的数据,可传递给 template 或 render,用于下拉框组件或下拉框 dom 绑定引用。为什么使用 ref,不使用 reactive 呢?ref 和 reactive 都可以给数据添加响应性,ref 一般用于给 js 基本数据类型添加响应性(当然也支持非基本类型的 object),reactive 只能用于代理非基本数据类型。null 是基本数据类型,只能使用 ref,那既然如此,为什么不在所有情况都使用 ref 呢?我们来看一段代码:
我们注意到,使用 ref api 时,数据变成了对象,值就是 value 属性的值,如果数据本身就是对象,依然会多一层 value 结构,而 reactive 没有这些副作用。同时,还有一个有意思的现象是,所有的源数据,都需要经过响应式 api 包裹,然后才能使用,这跟前面提到的 Proxy 原理有关,Proxy 代理数据时,需要基于返回的代理进行数据更新.
toRefs 。
除了 ref、reactive 外,还有一个常用的响应式 api——toRefs。为什么需要它,这是因为响应式对象,经过解构出来的属性不再具有响应性,toRefs 就是为了快速获得响应性的属性,因此这段代码const { init } = toRefs(props);,就是为了获得响应式属性 init,想要保留 props 参数的响应性,建议这么做.
watch、watchEffect 。
如上,watch api,它需要接受一个具有返回值的 getter 函数或者 ref(如() => state.num,ref).
如果需要监听多个值,如下所示:
可见多个数据的每次更新都会触发 watch。想要监听一个嵌套的对象,跟 Vue2 一样,依旧需要使用 deep 选项,如下所示:
看到差别了吗?监听响应式对象时,返回的是对象的引用,因此 currState,prevState 指向是同一个最新的 state,如果需要获取变化前的值,建议返回监听的属性,如watch(() => state.attr.id),刚好 state.attr.id 是一个基本类型的值,那么 deep 也不需要.
watchEffect 是 Vue3 新增的 api,watchEffect 会自动运行一次,用于自动收集依赖,但不支持获取变化前的值,除此之外,与 watch 用法一致。那么 watchEffect 适用什么场景呢?这也是我刚上手 Vue3 的困惑之一。我们来看一段代码:
以上代码中,watch 中的逻辑只能在 userInfo 变化后执行,因此 state.rights 不会提供初始值,相反,watchEffect 中 state.rights 由于自动依赖收集,获得了一次赋值的机会.
这样做的好处是什么呢?在实际项目中,userInfo.role 可能是一个全局 store 中的数据,用户登录进来后,就会通过接口获取初始值,我们并不能确认,用户进到其中一个页面时,userInfo.role 的值是否已经被接口更新,且 userInfo 变化前的值我们也不关心,watchEffect 就非常适合这种场景,它会自动进行一次初始化,并且在变化后,及时更新值.
watch 和 watchEffect 的监听会在组件销毁时自动取消,除此之外,可以通过它们返回的函数手动取消监听,如下所示:
watchEffect 更多的用法,请参考官方文档.
computed 。
computed 的使用如下:
num2 是一个不可变的 ref 对象,不能直接对它的 value 属性赋值.
computed 还可以接收一个带有 get 和 set 函数的对象,来创建一个可读写的 ref 对象,如下所示:
自定义 Hooks 。
Vue3 的 Composition 之所以这样实现,主要原因就是为了便于代码拆分,降低耦合,我们不妨来实现一个自定义的 hooks.
useCount.js 就是一个自定义的 hooks,得益于 Vue3 的全局 API,我们可以轻松做到代码拆分。Vue3 的 setup 聚合了所有的逻辑,容易产生面条代码,合理使用自定义 hooks,可以有效的减少面条代码,提升代码可维护性。并且 Vue3 的 hooks 比 react 更加简单高效,不会多次执行,不受调用顺序影响,不存在闭包陷阱等等,几乎可以没有任何心智负担的使用.
。
看到这里,相信你对 Vue3 的生命周期已经有一些了解了,我们不妨来做个梳理.
Vue3 几乎内置了所有的 Vue2 生命周期钩子,也就是说,刚开始升级项目至 Vue3 时,可以直接使用 Vue2 的钩子,方便平滑升级,如上图左下角所示,有两个钩子发生了替换,beforeDestory 被替换成了 beforeUnmount,destoryed 被替换成了 unmounted。完整的钩子对比如下:
除了 setup 外,Vue3 的其他生命周期钩子都添加了 on 前缀,更加规范统一。新的钩子需要在 setup 中使用,如下所示:
Tree-Shaking 。
Vue3 一共开放了 113 个 API,我们可以通过如下方式引用:
通过 ES6 modules 的引入方式,能够被 AST 静态语法分析感知,从而可以只提取用到的代码片段,最终达到 Tree-Shaking 的效果,这样就使得 Vue3 最终打包出来的包更小,加载更快。据尤大去年 4 月在 B 站的直播:基本的 hello world 项目大小为 13.5kb,Composition API 仅有 11.75kb,包含所有的运行态仅 22.5kb.
Fragment 。
Vue3 中,Fragment 的引入,解决了组件需要被一个唯一根节点包裹的难题,带来的是 dom 层级的减少,以及渲染性能的提升,某些时候,如下所示:
在 Vue2 中,这意味着我们没办法在 child.vue 的 template 中加入多个 td 节点,多个 td 可以被 tr 包裹,如果 child.vue 根节点替换为 tr,那么就会跟 parent.vue 的 tr 冲突.
同样的代码,在 Vue3 中就能正确编译通过,这是因为 Vue3 中,组件的 template 被一层不可见的 Fragment 包裹,组件天生支持多个根节点的布局.
Teleport 。
Teleport 是 Vue3 新增的组件,即传送门,Teleport 能够在不改变组件内部元素父子关系的情况下,将子元素”传送“到其他节点下加载,如下所示:
dialog 直接挂载在 container 下,超出部分将不可见。加一层 Teleport,我们可以轻松将 dialog 展示出来.
dialog 依然处于 container 内部,仅仅只是被挂载到 body 上,逻辑关系不变,展示也不会遮挡.
Suspense 。
Vue2 中,我们经常写这样的 loading 效果,如下所示:
Vue3 中,我们可以通过 Suspense 的两个插槽实现以上功能,如下所示:
。
Vue3 还包括了一些其他常用更新,限于篇幅,这里先列出来,下篇再讲.
实际上,Vue3 带来的更新,远不止这些,为此我梳理了一个 Vue3 的知识图谱,尽可能囊括一些本文未提到的特性.
如上图,Vue 不但重写了 diff 算法,还在编译阶段做了很多优化,编译时优化可以通过这个网站看出来:https://vue-next-template-explorer.netlify.app/.
。
根据 Monterail 2 月份发布的第三版 Vue 生态报告,Vue 的流行度逐年上升,很多非 web 的可视化领域也可以基于 Vue 开发,特别是 Vue3 的渲染 API 的开放,使得基于 Vue 构建 Canvas、WebGL、小程序等应用更加方便,如下图所示,60 行代码实现一个简单的 Canvas 柱状图:
运行结果如下图所示:
原文地址:https://zhuanlan.51cto.com/art/202104/659798.htm 。
最后此篇关于升级 Vue3 大幅提升开发运行效率的文章就讲到这里了,如果你想了解更多关于升级 Vue3 大幅提升开发运行效率的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。
好的,所以我想从批处理文件运行我的整个工作环境... 我想要实现什么...... 打开新的 powershell,打开我的 API 文件夹并从该文件夹运行 VS Code 编辑器(cd c:\xy;
我正在查看 Cocoa Controls 上的示例并下载了一些演示。我遇到的问题是一些例子,比如 BCTabBarController ,不会在我的设备上构建或启动。当我打开项目时,它看起来很正常,没
我刚刚开始学习 C 语言(擅长 Java 和 Python)。 当编写 C 程序(例如 hello world)时,我在 ubuntu cmd 行上使用 gcc hello.c -o hello 编译
我在 php 脚本从 cron 开始运行到超时后注意到了这个问题,但是当它从命令行手动运行时这不是问题。 (对于 CLI,PHP 默认的 max_execution_time 是 0) 所以我尝试运行
我可以使用命令行运行测试 > ./node_modules/.bin/wdio wdio.conf.js 但是如果我尝试从 IntelliJ 的运行/调试配置运行它,我会遇到各种不同的错误。 Fea
Error occurred during initialization of VM. Could not reserve enough space for object heap. Error: C
将 Anaconda 安装到 C:\ 后,我无法打开 jupyter 笔记本。无论是在带有 jupyter notebook 的 Anaconda Prompt 中还是在导航器中。我就是无法让它工作。
我遇到一个问题,如果我双击我的脚本 (.py),或者使用 IDLE 打开它,它将正确编译并运行。但是,如果我尝试在 Windows 命令行中运行脚本,请使用 C:\> "C:\Software_Dev
情况 我正在使用 mysql 数据库。查询从 phpmyadmin 和 postman 运行 但是当我从 android 发送请求时(它返回零行) 我已经记录了从 android 发送的电子邮件是正确
所以这个有点奇怪 - 为什么从 Java 运行 .exe 文件会给出不同的输出而不是直接运行 .exe。 当 java 在下面的行执行时,它会调用我构建的可与 3CX 电话系统配合使用的 .exe 文
这行代码 Environment.Is64BitProcess 当我的应用单独运行时评估为真。 但是当它在我的 Visual Studio 单元测试中运行时,相同的表达式的计算结果为 false。 我
关闭。这个问题是opinion-based .它目前不接受答案。 想要改进这个问题? 更新问题,以便 editing this post 可以用事实和引用来回答它. 关闭 8 年前。 Improve
我写了一个使用 libpq 连接到 PostgreSQL 数据库的演示。 我尝试通过包含将 C 文件连接到 PostgreSQL #include 在我将路径添加到系统变量 I:\Program F
如何从 Jenkins 运行 Android 模拟器来运行我的测试?当我在 Execiute Windows bath 命令中写入时,运行模拟器的命令: emulator -avd Tester 然后
我已经配置好东西,这样我就可以使用 ssl 登录和访问在 nginx 上运行的 errbit 我的问题是我不知道如何设置我的 Rails 应用程序的 errbit.rb 以便我可以运行测试 nginx
我编写了 flutter 应用程序,我通过 xcode 打开了 ios 部分并且应用程序正在运行,但是当我通过 flutter build ios 通过 vscode 运行应用程序时,我得到了这个错误
我有一个简短的 python 脚本,它使用日志记录模块和 configparser 模块。我在Win7下使用PyCharm 2.7.1和Python 3.3。 当我使用 PyCharm 运行我的脚本时
我在这里遇到了一些难题。 我的开发箱是 64 位的,windows 7。我所有的项目都编译为“任何 CPU”。该项目引用了 64 位版本的第 3 方软件 当我运行不使用任何 Web 引用的单元测试时,
当我注意到以下问题时,我正在做一些 C++ 练习。给定的代码将不会在 Visual Studio 2013 或 Qt Creator 5.4.1 中运行/编译 报错: invalid types 'd
假设我有一个 easteregg.py 文件: from airflow import DAG from dateutil import parser from datetime import tim
我是一名优秀的程序员,十分优秀!