vue入门:(底层渲染实现render函数实例生命周期)
Posted zheoneandonly
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了vue入门:(底层渲染实现render函数实例生命周期)相关的知识,希望对你有一定的参考价值。
- vue实例渲染的底层实现
- vue实例生命周期
一、vue实例渲染的底层实现
1.1实例挂载
在vue中实例挂载有两种方法:第一种在实例化vue时以el属性实现,第二种是通过vue.$mount()方法实现挂载。不管是哪种挂载都不影响vue实例化组件的执行流程和模式,只是通过vue.$mount()方法实现挂载可以更灵活的实现组件复用和挂载。
1 var vm = new Vue( 2 el:‘挂载元素id‘,//实例化el属性实现挂载 3 ... 4 ) 5 var vm1 = new Vue(...); 6 vm1.mount(‘挂载元素id‘);//vue.mount()方法实现挂载 7 //参数模型:# + id
1.2构建DOM抽象语法树与template
在vue实例化中有一个非常关键的操作就是构建DOM抽象语法树,基于抽象语法树生成虚拟节点,然后再将数据渲染到虚拟节点上,再将完成数据渲染的节点添加到document中刷新页面,呈现页面效果。构建抽象语法树有三种方式:1.基于绑定的实例化属性el和$mount()方法构建;2.基于实例化属性template添加的模板构建;3.基于ready()的参数构建。
这三种构建方式的优先级:render() > template > el
本质上的el与template与render()函数的参数都是一个原理,通过el就是将el指向的元素的DOM模型的outerhtml属性值拿到,outerHTML属性值与template的形式完全一样就是html文本的字符串形式;然后将这个字符串形式的html文本转换成js对象模型,render()函数中使用的就直接是js对象模型,接着通过js对象模型所表达的html结构转换成AST(抽象语法树)用于构建虚拟节点VNode;render()函数再在这个虚拟节点上渲染数据,完成数据渲染后就添加到html文档中渲染到页面。
通过元素在window上的id指向获取到id匹配的元素节点对象的outerHTML属性值:
1 <div id="app">我是一个div</div> 2 <script> 3 console.log(app.outerHTML);//"<div id="app">我是一个div</div>" 4 </script>
通过vue对象实例化属性template构建vue实例:
1 <div id="app">我是一个div</div> 2 <script> 3 var vm = new Vue( 4 el:"#app", 5 template:`<div>我是template模板构建的节点</div>` 6 ) 7 </script>
通过vue实例化将实例化对象属性template的模板替代app指向的原节点,实质上是在vue实例构建过程中如果发现有template就不会再去获取挂载节点的结构了。接着再来看看render()方法如何实现vue实例构建:
<div id="app">我是一个div</div> <script> var vm = new Vue( el:"#app", template:`<div>我是template模板构建的节点</div>`, render(createElement) return createElement("p"); ) </script>
通过添加render()方法刷新页面会发现页面变成了空白,也就是说el挂载原节点和template模板构建的节点都没生效,查看浏览器控制台可以看到在原app指向的节点的位置被一个空的p标签替代了。这就是说render()函数的优先级大于template和el,但是要注意的是vue实例化必须是在通过el或者vue.mount()挂载才会去执行render()节点渲染方法,不然一个不挂载的vue实例有何必要渲染呢?
1.3基于JS对象模型的AST抽象语法树构建及虚拟节点渲染:
render(createElement)
return createElement(ElementName,ElementProperty,ChildNode);
这里不深入讨论render的设计实现,也不讨论虚拟节点的具体底层实现原理,也不深入探究render的复杂应用,仅仅对render()函数基于js对象模型构建AST抽象语法树做出解析。
createElement:声明工具函数的名称;
ElementName:设定抽象语法树根节点元素名称;
ElementProperty:设定根节点元素的属性;
ChildNode:设定子节点;
1 render(createElement) 2 return createElement("p", 3 style: 4 color:"red", 5 fontSize:‘18px‘ 6 , 7 class:[‘classname1‘,‘classname2‘] 8 ,"我是由render构建的p标签"); 9
基于data的构建方式:
1 <div id="app">我是一个div</div> 2 <script> 3 var vm = new Vue( 4 el:"#app", 5 template:`<div>我是template模板构建的节点</div>`, 6 data: 7 classname1:true, 8 classname2:false, 9 text:‘我时由render构建的p标签‘ 10 , 11 render(createElement) 12 return createElement("p", 13 style: 14 color:"red", 15 fontSize:‘18px‘ 16 , 17 class://基于数据绑定class 18 classname1:this.classname1, 19 classname2:this.classname2 20 21 ,this.text); 22 23 ) 24 </script>
使用createElement工具方法迭代子节点(在前面的子节点都直接使用字符串,就是说明其是文本节点,使用createElement可以创建元素子节点):
1 <div id="app">我是一个div</div> 2 <script> 3 var vm = new Vue( 4 el:"#app", 5 template:`<div>我是template模板构建的节点</div>`, 6 data: 7 classname1:true, 8 classname2:false, 9 text:‘我时由render构建的p标签‘ 10 , 11 render(createElement) 12 return createElement("p", 13 style: 14 color:"red", 15 fontSize:‘18px‘ 16 , 17 class://基于数据绑定class 18 classname1:this.classname1, 19 classname2:this.classname2 20 21 ,[ 22 ‘我是一个文本节点‘, 23 createElement(‘h1‘,‘我是h1标签‘), 24 createElement(‘h2‘, 25 style: 26 color:‘orange‘ 27 28 ,‘我是h2标签‘) 29 ]); 30 31 ) 32 </script>
其实本质上render()函数与页面渲染中的抽象语法树构建是异曲同工,一个是基于js对象参数构建,一个是通过html文档构建;一个是在js中完成一个是在浏览器底层渲染模型中完成。
二、vue实例生命周期与钩子函数
更多的钩子函数相关内容可以参考这篇博客: https://www.jianshu.com/p/3e91a1c42397
带后期有深入的理解后再来做详细的解析。
以上是关于vue入门:(底层渲染实现render函数实例生命周期)的主要内容,如果未能解决你的问题,请参考以下文章