大概几集下饭剧时间就能懂的VUE3原理
大家好,我是卡颂。
最近中午没胃口,找来VUE源码相关视频来当下饭剧。几顿饭下去,人胖了,VUE也整明白了。
这篇文章为你带来一份VUE3原理速成指南。
如果我们用「VUE的模版语法」定义:
hello
最终VUE会帮我们在浏览器中渲染对应的DOM节点。
这之间对这段节点的描述会经历4次变化,横跨「编译时」与「运行时」:
「模版语法」在编译时会被「编译器」转化为「render函数」,类似:
- render(h) {
- return h('div', 'hello');
- }
在运行时,「render函数」执行后返回的「h函数的执行结果」就是VNode(也就是虚拟DOM),类似:
- {
- tag: "div",
- children: [
- {
- text: "Hello"
- }
- ]
- }
最终,VUE根据VNode的信息,在浏览器渲染对应DOM。
那么,是谁在驱动这一流程?
组件有两种不同的渲染逻辑:「首次渲染」和「更新」。
「首次渲染」意味着从无到有,比如上文的VNode:
- {
- tag: "div",
- children: [
- {
- text: "Hello"
- }
- ]
- }
可能对应如下DOM操作:
- const node = document.createElement(VNode.tag);
- node.textConent = 'Hello';
- contanerDOM.appendChild(node);
「更新」则需要对比更新前后VNode,对变化部分执行DOM操作。
比如,以上VNode如果变为:
- {
- tag: "div",
- children: [
- {
- // text改变
- text: "world"
- }
- ]
- }
则最终执行:
- node.textContent = 'world';
VUE的「首次渲染」对应mount模块,「更新」对应patch模块。
所以,render函数执行后返回VNode,根据情况不同,会走mount或patch的渲染逻辑:
如果想深入虚拟DOM相关知识,推荐阅读snabbdom[1]源码。这是个优秀的虚拟DOM库,VUE2的虚拟DOM部分就是fork这个库改造的。
那么是谁在什么时机调用了render函数呢?
在VUE中,状态变化会实时反映到视图上,比如:
{{count}}
点击div后:
当前我们已经知道第二步是由于触发了如下流程:
所以只需要建立count变化到执行render函数的联系即可。
具体来说,我们希望实现reactive及watchEffect:
- // 定义状态
- const state = reactive({count: 0});
- // 监听状态变化
- watchEffect(() => {
- console.log(state.count);
- })
- // 改变状态
- state.count++;
reactive定义状态。
watchEffect根据回调执行的情况决定监听哪些状态。
比如watchEffect回调执行了console.log(state.count);,他就会监听state的变化。
当执行state.count++;,由于watchEffect监听了state的变化,则其回调会触发,打印state.count。
这就是Reactivity模块。
VUE官方推出了VUE3响应式原理[2]课程讲解Reactivity的实现,这是B站链接。如果经济允许,请支持正版[3]
当实现了Reactivity模块,我们就能将「组件状态」与后续流程串联起来。
刚才讲过,render函数是编译器根据「模版语法」生成的。在面对带状态的模版语法时,比如上文的count:
{{count}}
render函数内的count是响应式的(即:count实际是reactive({count: 0}))。
那么就能用watchEffect监听count的变化。
所以,在应用初始化时,会有类似逻辑:
- let isMounted = false;
- let oldVNode;
- watchEffect(() => {
- if (!isMounted) {
- // mount逻辑
- // 调用render函数
- oldVNode = component.render();
- // mount
- mount(oldVNode);
- } else {
- // patch逻辑
- // 调用render函数
- newVNode = component.render();
- patch(oldVNode, newVNode);
- oldVNode = newVNode;
- }
- })
其中component.render()(render函数的执行)达到上文「监听状态变化」的效果:
- // 监听状态变化
- watchEffect(() => {
- console.log(state.count);
- })
所以,该组件内任何状态变化都会触发watchEffect的执行,watchEffect回调内会触发后续流程。
VUE3按原理大体可以划分为:
VUE官方推出了实现简易VUE3教程[4],感兴趣的朋友可以去看看。如果有能力,记得去支持正版[5]哦。
[1]snabbdom:
https://github.com/snabbdom/snabbdom
[2]VUE3响应式原理:
https://www.bilibili.com/video/BV1SZ4y1x7a9/?spm_id_from=333.788.b_7265636f5f6c697374.6
[3]正版:
https://www.vuemastery.com/free-weekend/?gclid=Cj0KCQjwpreJBhDvARIsAF1_BU16x7gElbhGqGzZZ1geo5RzOqz_PuaJzBM41jHcAAC6CPwPSPvo8G8aAkdhEALw_wcB
[4]实现简易VUE3教程:
https://www.bilibili.com/video/BV1rC4y187Vw?p=10
[5]正版:
https://www.vuemastery.com/free-weekend/?gclid=Cj0KCQjwpreJBhDvARIsAF1_BU16x7gElbhGqGzZZ1geo5RzOqz_PuaJzBM41jHcAAC6CPwPSPvo8G8aAkdhEALw_wcB
新闻名称:大概几集下饭剧时间就能懂的Vue3原理
文章源于:http://www.shufengxianlan.com/qtweb/news47/438047.html
网站建设、网络推广公司-创新互联,是专注品牌与效果的网站制作,网络营销seo公司;服务项目有等
声明:本网站发布的内容(图片、视频和文字)以用户投稿、用户转载内容为主,如果涉及侵权请尽快告知,我们将会在第一时间删除。文章观点不代表本网站立场,如需处理请联系客服。电话:028-86922220;邮箱:631063699@qq.com。内容未经允许不得转载,或转载时需注明来源: 创新互联