这里的主要关注点是vue3相比于vue2带来了哪些提升,具体API的使用就不再细述。
下面从vue3的几大新特性来逐个展开。
一、Composition API
Composition API,即组合式API
-
高内聚
聚合业务逻辑,提高代码可读性
-
vue2 通过属性选项(options,如 data、computed、methods 等)书写代码逻辑,代码逻辑点是碎片化、跳跃式的,在大型项目和复杂组件中使得维护变得困难。
-
vue3 的组合式API能够将分散的逻辑代码组合在一起,使代码逻辑更清晰易读。
-
-
低耦合
便于代码拆分,提高复用性
-
Vue2 中的一个常用代码复用方式是 mixins 混入,mixins在一些场景下确实能很大的提升代码复用率,但同时也会带来一些副作用,比如依赖关系不清晰,mixins里定义的data和methods等在组件中使用时没有明确的引入和定义,而且可能与组件里定义的有命名冲突,有很大的维护风险。
-
得益于组合式API,vue3里可以通过自定义hooks来实现类似mixins的复用效果,而且不会有vue2里mixins的缺点。
扫描二维码关注公众号,回复: 13715155 查看本文章https://blog.csdn.net/u010059669/article/details/111688244
-
-
更简化的
<script setup>
语法https://blog.csdn.net/u010059669/article/details/119780334
-
<script setup>
语法是composition api
的一个语法糖,代码编写更加简洁,已经发布正式版本,vue3.2+支持,推荐使用。 -
defineExpose
:使用<script setup>
的组件是默认关闭的,在它的父组件中通过this.$refs
默认是拿不到它所绑定的数据和方法,只有通过defineExpose
暴露出去的才能拿到,这个API设计能显著的解决this.$refs
导致的代码耦合和维护风险问题。// 子组件 <script setup> import { ref } from 'vue' const a = 1 const b = ref(2) const c = ref(3) defineExpose({ a, b }) </script>
-
二、Teleport
Teleport,即传送门。
能在不改变组件内部元素父子关系的情况下,将子元素“传送”到其他指定节点下渲染。
- 应用场景:比如弹窗组件中,多级弹窗嵌套的场景,css的z-indx不方便处理。
<template>
<div class="container">
<teleport to="body">
<div class="dialog">
...
</div>
</teleport>
</div>
</template>
三、Fragment
Fragment,即片段。
- 在 2.x 中,由于不支持多根节点组件,当开发者意外创建多个时会发出警告。
- 在 3.x 中,组件可以包含多个根节点。Vue3 中,组件的 template 被一层不可见的 Fragment 包裹,支持多个根节点。能够减少 dom 层级、提升渲染性能。
<template>
<header>...</header>
<main v-bind="$attrs">...</main>
<footer>...</footer>
</template>
四、Emits
Emits,即组件触发的自定义事件。
-
在vue2中,组件封装时触发自定义事件给父组件,都是通过
this.$emit()
触发,但是触发地点可能会遍布在组件内各个地方,没有统一管理,使用不方便。 -
vue3里,所有自定义事件都要在emits里定义,和定义props类似,而且还能对事件做自定义校验。这样在使用组件时很方便的就能知道有哪些事件可以使用。
import { defineComponent } from 'vue'; export default defineComponent({ props: { isOpen: Boolean, }, emits: { 'closeModal': null, }, setup(props, context) { const clickButton = () => { context.emit('closeModal'); } return { clickButton, } }, })
五、动态css
在 <style>
样式标签可以通过 v-bind
绑定<script>
里定义的变量,来实现动态的css样式。
个人不推荐使用
-
<template> <div class="text">hello</div> </template> <script> export default { data() { return { color1: 'red' } } } </script> <style> .text { color: v-bind(color1); } </style>
六、Tree shaking
Tree shaking,一种按需打包的方式。
由于 es6 的模块化导入导出是静态可分析的,所以在打包的时候通过解析js代码就能明确知道哪部分代码使用了、哪部分代码没有使用,然后只对使用到的代码进行打包,这样就能实现按需打包的效果。
-
vue3 一共开放了113个API,均支持 tree shaking,可通过以下类似的方式引用:
import { ref, reactive, h, onMounted } from "vue"
没有引用的模块不会处理,这样打包速度、打包体积、以及运行速度都会有提升。
-
不仅是vue3,相配套的vue-router4和vuex4都支持了tree-shaking。
七、VDOM
https://blog.csdn.net/summer_zhh/article/details/108080930
VDOM,即vue里的虚拟DOM。
vue3里对VDOM进行了重写,优化了Diff算法:
-
vue2在对比VDOM时,会遍历整个VDOM树,从根节点依次递归遍历到末节点,从而找出所有变化的节点进行局部更新。
-
vue3会区分静态DOM节点和动态DOM节点,对动态DOM节点做一个
PatchFlag
标记,并将动态节点与根节点绑定,这样,在数据更新对比VDOM时,会从根节点里查找PatchFlag
标记,跳到动态节点上直接比较,不用遍历静态节点,提升渲染更新的性能。<template> <div>hello</div> <div>{ {title}}</div> </template> <script> export default { data() { return { title: '标题' } } } </script>
八、Proxy
proxy,是es6新增的一个api,可以对对象进行数据劫持。
-
vue2里是使用
Obejct.definePropery
来实现数据的响应式,存在一些弊端:- 这个api只能传入对象的特定属性进行劫持,所以vue2里是初始化时递归遍历对象所有层级的属性,依次调用Obejct.definePropery方法来实现数据响应式,层级较深时影响性能。
- 对象新增的属性不会劫持,不具有响应式,所以开发过程中也经常会遇到这个问题。解决方式一般是在数据定义时给属性加个默认值,或者通过
this.$set()
手动处理。 - 这个api不能作用于数组,所以vue2是通过重写数组原型的几个方法来实现数据监听。
Object.defineProperty(obj, prop, descriptor)
-
vue3是使用的
proxy
api,这个api传参是一个对象或者数组,api内部会原生实现对象属性或数组元素的数据劫持,包括对象的新增属性和数组元素都具有响应式,所以在开发使用效率和运行效率上都有很大的提升。new Proxy(target, handler)
九、createRenderer
createRenderer,是vue3新增的一个API,用来创建自定义渲染器,实现更好的跨平台应用。
import {
createRenderer } from '@vue/runtime-core'
const {
render, createApp } = createRenderer({
patchProp,
insert,
remove,
createElement,
// ...
})
-
vue默认是用于浏览器端的,所以从虚拟DOM到真实的DOM的映射渲染都是基于浏览器原生BOM API实现的,vue3通过
createRenderer
这个API暴露了自定义渲染方式,跨平台框架就可以基于此实现虚拟DOM到其他平台DOM的映射。 -
常见的前端跨平台方案:
-
一种是解析原代码语法生成AST抽象语法树,然后生成相应平台的代码语法,这种方式更加通用彻底,但由于不同平台的语法功能差异,不能做到完全的转换支持,语法使用上会有很多限制。
-
另一种就是自定义虚拟DOM到真实DOM的映射,这种方式不做语法转换,可以获得原框架全部的开发体验,京东taro的v3版本就是这种实现方式。
- 如果原框架本身没有暴露虚拟DOM到真实DOM的映射API,要打造跨平台框架一般就选择fork一份原框架的源码,改写其中的映射逻辑来实现,老的一些框架如weex、mpvue就是fork的vue2实现的。
- vue3通过
createRenderer
这个API暴露出自定义渲染方式,这样就不用改写原框架源码,能直接使用这个API实现跨平台逻辑,对原框架的版本更新也能更加及时的同步支持。
-
十、TS支持
TypeScript,是js的一个超集,或者说是加了一层包装,对js做了功能拓展和更严谨的代码校验。
- vue2对ts的支持很不友好,强行使用ts需要引入很多库,使用繁琐,而且支持也不全面。
- vue3本身就是用ts编写的,对ts可以说是全方位的支持。
十一、Vite
Vite,基于原生es模块的新型前端构建工具。
- 相对于传统的webpack,vite有着极快的项目启动速度,以及热更新速度。
- 和vue3是同一作者(尤雨溪),所以对vue3的支持比较好。
- 社区插件也在不断的完善中,未来有望取代webpack。
https://blog.csdn.net/u010059669/article/details/121808645?spm=1001.2014.3001.5501
参考文档:https://juejin.cn/post/7036774227583696933