前一两年一直在研究 Vue 源代码,2和3的源代码变动还是蛮大的,但是 Vue3 在合作开发上需要改变过往习惯的地方真无所谓,即便基础概念是十分相似的,可这回 3 的项目写起来是能让人感觉爽得多,不亲自动手是真感受不到
因此咯,一定要亲自动手!敲标识符!不能学而不用,这是不单单的
这里我归纳了几个 Vue3 的习题,如果你是 Vue2 的北迁者、学习 Vue3 或者准备复试的话,相信看完责任编辑一定会有所斩获
Vue3 有什么样变动
Vue3 是怎么得更快的?
追加了三个组件:Fragment 全力支持多个根结点、Suspense 能在组件图形之前的等候时间显示选定内容、Teleport 能让子组件能够在听觉上跳脱父组件(陈瑚组件overflow:hidden)追加命令 v-memo,能缓存 html 模版,比如 v-for 条目不会变动的就缓存,简单说是用缓存换时间全力支持 Tree-Shaking,会在装箱时除去一些罢了标识符,没有加进的组件,使标识符装箱表面积更小追加 Composition API 能更快的方法论F83E43Se和标识符组织,同一个功能的标识符不致像以前一样太零散,虽然 Vue2 中能用 minxin 来实的不是第一类特性,而是第一类本身,还可截击 apply、has 等13种方式解构了交互式 DOM,在校对时能将事件缓存、将 slot 校对为 lazy 表达式、留存动态结点间接F83E43Se(动态提高)、以及加进动态标记、Diff 演算法采用 最久递减子字符串 强化了对照业务流程,使交互式 DOM 聚合速度提高 200%全力支持在 <style></style> 里采用 v-bind,给 CSS 存取 JS 表达式(color: v-bind(str))删掉了三个开发周期 beforeCreate、created,间接用 setup 替代了追加了合作开发环境的三个钳子表达式,在组件预览时 onRenderTracked 会追踪组件里所有表达式和方式的变动、每天促发图形时 onRenderTriggered 会回到发生变动的旧有值,能让我们进行有前瞻性增容即便 Vue3 是用 TS 写的,因此对 TS 的全力支持度更快Vue3 不兼容 IE11说一下 Composition API
和 Options API 的区别?
Composition API 也叫复合式 API,它主要是为了解决 Vue2 中 Options API 的问题。
一是在 Vue2 中只能固定用 data、computed、methods 等选项组织标识符,在组件越来越复杂的时候,一个功能相关的特性和方式就会在文件上中下到处都有,很零散,变越来越难维护
二是 Vue2 中虽然能用 minxin 来做方法论的提取F83E43Se,但是 minxin 里的特性和方式名会和组件内部的命名冲突,还有当引入多个 minxin 的时候,我们采用的特性或方式是来于哪个 minxin 也不清楚
而 Composition API 刚才就解决了这三个问题,能让我们自由的组织标识符,同一个功能相关的全部放在一起,标识符有更快的可读性更便于维护,单独提取出来也不会造成命名冲突,因此也有更快的可扩展性
说一下 setupsetup() 方式是在 beforeCreate() 开发周期表达式之前执行的表达式;
它接收三个参数 props 和 context。它里面不能采用 this,而是通过 context 第一类来替代当前执行上下文存取的第一类,context 第一类有四个特性:attrs、slots、emit、expose
里面通过 ref 和 rective 替代以前的 data 语法,return 出去的内容,能在模版间接采用,包括表达式和方式
而采用 setup 语法糖时,不用写 export default {},子组件只需要 import 就间接采用,不需要像以前一样在 components 里注册,特性和方式也不用 return。
并且里面不需要用 async 就能间接采用 await,因为这样默认会把组件的 setup 变为 async setup
用语法糖时,p
3.0~3.2版本变成了通过 import 引入的 API:defineProps、defineEmit、useContext(在3.2版本已废弃),useContext 的特性 { emit, attrs, slots, expose }
3.2+版本不需要引入,而间接调用:defineProps、defineEmits、defineExpose、useSlots、useAttrs
watch 和 watchEffect 的区别
watch 作用是对传入的某个或多个值的变动进行监听;促发时能回到新值和老值;也是说第一次不会执行,只有变动时才会重新执行
chEffect是传入一个立即执行表达式,因此默认第一次也会执行一次;不需要传入监听内容,会自动收集表达式内的数据源作为依赖,在依赖变动的时候又会重新执行该表达式,如果没有依赖就不会执行;而且不会回到变动前后的新值和老值
共同点是 watch 和 watchEffect 会共享以下四种行为:
停止监听:组件卸载时都会自动停止监听清除副作用:onInvalidate 会作为回调的第三个参数传入副作用刷新时机:响应式系统会缓存副作用表达式,并异步刷新,避免同一个个 tick 中多个状态改变导致的重复调用监听器增容:合作开发模式下能用 onTrack 和 onTrigger 进行增容Vue3 响应式原理和 Vue2 的区别
众所周知 Vue2 数据响应式是通过 Object.defineProperty() 劫持各个特性 getter 和 setter,在数据变动时发布消息给订阅者,促发相应的监听回调,而这之间存在几个问题
初始化时需要遍历第一类所有 key,如果第一类层次较深,性能不好通知预览过程需要维护大量 dep 实例和 watcher 实例,额外占用缓存较多Object.defineProperty 无法监听到数组元素的变动,只能通过劫持重写数方式动态追加,删掉第一类特性无法截击,只能用特定 set/delete API 替代不全力支持 Map、Set 等数据结构而在 Vue3 中为了解决这些问题,采用原生的 proxy 替代,全力支持监听第一类和数组的变动,并且多达13种截击方式,动态特性增删都能截击,追加数据结构全部全力支持,第一类嵌套特性只代理第一层,运行时递归,加进才代理,也不需要维护特别多的依赖关系,性能取得很大进步
更多细节和源代码剖析能看我另一篇文章 Vue3.2 响应式原理源代码剖析,及与 Vue2响应式的区别defineProperty 和 Proxy 的区别
为什么要用 Proxy 替代 defineProperty ?好在哪里?
Object.defineProperty 是 Es5 的方式,Proxy 是 Es6 的方式defineProperty 不能监听到数组下标变动和第一类追加特性,Proxy 能defineProperty 是劫持第一类特性,Proxy 是代理整个第一类defineProperty 局限性大,只能针对单特性监听,因此在一开始就要全部递归监听。Proxy 第一类嵌套特性运行时递归,加进才代理,也不需要维护特别多的依赖关系,性能提高很大,且首次图形更快defineProperty 会污染原第一类,修改时是修改原第一类,Proxy 是对原第一类进行代理并会回到一个新的代理第一类,修改的是代理第一类defineProperty 不相容 IE8,Proxy 不相容 IE11Vue3 的开发周期
基本上是在 Vue2 开发周期钳子表达式名基础上加了 on;beforeDestory 和 destoryed 更名为 onBeforeUnmount 和 onUnmounted;然后删了三个钳子表达式 beforeCreate 和 created;追加了三个合作开发环境用于增容的钳子
Vue3 的 8 种组件通信
能看我另一文章,就不搬过来了 Vue3的8种和Vue2的12种组件通信,值得收藏Vue3 Diff演算法和 Vue2 的区别
我们知道在数据变更促发页面重新图形,会聚合交互式 DOM 并进行 patch 过程,这一过程在 Vue3 中的强化有如下
校对阶段的强化:
事件缓存:将事件缓存(如: @click),能理解为变成动态的了动态提高:第一次创建动态结点时留存,后续间接F83E43Se加进动态记号:给结点加进动态记号,以强化 Diff 过程由于校对阶段的强化,除了能更快的聚合交互式 DOM 以外,还使 Diff 时能跳过”永远不会变动的结点”,Diff 强化如下
Vue2 是全量 Diff,Vue3 是动态记号 + 非全量 Diff采用最久递减子字符串强化了对照业务流程根据尤大公布的数据是 Vue3 update 性能提高了 1.3~2 倍
源代码剖析能看我另一篇文章 深入浅出交互式 DOM 和 Diff 演算法,及 Vue2 与 Vue3 中的区别我建了一个前端小白交流群,私信我,进入交流群。我会给大家分享我收集整理的各种学习资料,组织大家一起做项目练习,帮助大家匹配一位学习伙伴互相监督学习,欢迎加入
作者:沐华
链接:聊一聊 Vue3 的 9 个习题