• vue实例渲染的底层实现
  • vue实例生命周期

一、vue实例渲染的底层实现

1.1实例挂载

在vue中实例挂载有两种方法:第一种在实例化vue时以el属性实现,第二种是通过vue.$mount()方法实现挂载。不管是哪种挂载都不影响vue实例化组件的执行流程和模式,只是通过vue.$mount()方法实现挂载可以更灵活的实现组件复用和挂载。

 var vm = new Vue({
el:'挂载元素id',//实例化el属性实现挂载
...
})
var vm1 = new Vue({...});
vm1.mount('挂载元素id');//vue.mount()方法实现挂载
//参数模型:# + 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属性值:

 <div id="app">我是一个div</div>
<script>
console.log(app.outerHTML);//"<div id="app">我是一个div</div>"
</script>

通过vue对象实例化属性template构建vue实例:

 <div id="app">我是一个div</div>
<script>
var vm = new Vue({
el:"#app",
template:`<div>我是template模板构建的节点</div>`
})
</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:设定子节点;

 render(createElement){
return createElement("p",{
style:{
color:"red",
fontSize:'18px'
},
class:['classname1','classname2']
},"我是由render构建的p标签");
}

基于data的构建方式:

 <div id="app">我是一个div</div>
<script>
var vm = new Vue({
el:"#app",
template:`<div>我是template模板构建的节点</div>`,
data:{
classname1:true,
classname2:false,
text:'我时由render构建的p标签'
},
render(createElement){
return createElement("p",{
style:{
color:"red",
fontSize:'18px'
},
class:{//基于数据绑定class
classname1:this.classname1,
classname2:this.classname2
}
},this.text);
}
})
</script>

使用createElement工具方法迭代子节点(在前面的子节点都直接使用字符串,就是说明其是文本节点,使用createElement可以创建元素子节点):

 <div id="app">我是一个div</div>
<script>
var vm = new Vue({
el:"#app",
template:`<div>我是template模板构建的节点</div>`,
data:{
classname1:true,
classname2:false,
text:'我时由render构建的p标签'
},
render(createElement){
return createElement("p",{
style:{
color:"red",
fontSize:'18px'
},
class:{//基于数据绑定class
classname1:this.classname1,
classname2:this.classname2
}
},[
'我是一个文本节点',
createElement('h1','我是h1标签'),
createElement('h2',{
style:{
color:'orange'
}
},'我是h2标签')
]);
}
})
</script>

其实本质上render()函数与页面渲染中的抽象语法树构建是异曲同工,一个是基于js对象参数构建,一个是通过html文档构建;一个是在js中完成一个是在浏览器底层渲染模型中完成。

二、vue实例生命周期与钩子函数

更多的钩子函数相关内容可以参考这篇博客: https://www.jianshu.com/p/3e91a1c42397

带后期有深入的理解后再来做详细的解析。

vue入门:(底层渲染实现render函数、实例生命周期)的更多相关文章

  1. vue实例生命周期详解

    每个 Vue 实例在被创建之前都要经过一系列的初始化过程. 例如,实例需要配置数据观测(data observer).编译模版.挂载实例到 DOM ,然后在数据变化时更新 DOM . 在这个过程中,实 ...

  2. 前端(二十)—— vue介绍:引用vue、vue实例、实例生命周期钩子

    vue 一.认识Vue 定义:一个构建数据驱动的 web 界面的渐进式框架 优点: 1.可以完全通过客户端浏览器渲染页面,服务器端只提供数据 2.方便构建单页面应用程序(SPA) 3.数据驱动 =&g ...

  3. vue生命周期图示中英文版Vue实例生命周期钩子

    vue生命周期图示中英文版Vue实例生命周期钩子知乎上近日有人发起了一个 “react 是不是比 vue 牛皮,为什么?” 的问题,Vue.js 作者尤雨溪12月4日正面回应了该问题.以下是尤雨溪回复 ...

  4. Vue实例生命周期+vueRoter

    Vue实例生命周期 vue生命周期之beforeCreate 实例创建之前除标签外,所有的vue需要的数据,事件都不存在 vue生命周期之created 实例创建之后,data和事件已经被解析到,el ...

  5. vue实例生命周期

    实例生命周期 var vm = new Vue({ data: { a: 1 }, created: function () { // `this` 指向 vm 实例 console.log('a i ...

  6. Vue2学习笔记:实例生命周期

    实例生命周期 每个 Vue 实例在被创建之前都要经过一系列的初始化过程.例如,实例需要配置数据观测(data observer).编译模版.挂载实例到 DOM ,然后在数据变化时更新 DOM .在这个 ...

  7. autofac 实例生命周期

    转自逆心博客园 autofac 实例生命周期 实例生命周期决定在同一个服务的每个请求的实例是如何共享的. 当请求一个服务的时候,Autofac会返回一个单例 (single instance作用域), ...

  8. Vue学习笔记进阶篇——Render函数

    基础 Vue 推荐在绝大多数情况下使用 template 来创建你的 HTML.然而在一些场景中,你真的需要 JavaScript 的完全编程的能力,这就是 render 函数,它比 template ...

  9. 【Vue实例生命周期】

    目录 实例创建之前执行--beforeCreate 实例创建之后执行--created 挂载之前执行--beforeMount 挂载之后执行--mounted 数据更新之前执行--beforeUpda ...

随机推荐

  1. LC 738. Monotone Increasing Digits

    Given a non-negative integer N, find the largest number that is less than or equal to N with monoton ...

  2. Hibernate3运行原理

    Hibernate的运行过程如下: 1.应用程序先调用Configuration类,该类读取Hibernate配置文件及映射文件中的信息,2.并用这些信息生成一个SessionFactory对象,3. ...

  3. Nginx知识

    OpenResty最佳实践->location匹配规则传说中图片防盗链的爱恨情仇 ​

  4. scala简单学习---1

    :paste //进入代码块模式 :quit //退出scala编程 安装方面: 版本:scala-2.12.4.msi 环境变量: %SCALA_HOME%\bin;%SCALA_HOME%\jre ...

  5. WebApi实现通讯加密 (转)

    http://www.cnblogs.com/jonneydong/p/WebApi_Encryption.html 一. 场景介绍: 如题如何有效的,最少量的现有代码侵入从而实现客户端与服务器之间的 ...

  6. 一次神奇的JVM调优

    老张接个新项目,项目可是不小,好多模块.使用Intellij import new project, 结果卡在writing class中,而且mac的风扇一直转,像是要变成直升机起飞. 等啊等,in ...

  7. java中使用MappedByteBuffer将 File类转ByteBuffer

    public static WavFile openWavFile(File file) throws IOException, WavFileException { FileChannel chan ...

  8. 基于scrapy框架的爬虫

    Scrapy是一个为了爬取网站数据,提取结构性数据而编写的应用框架. 可以应用在包括数据挖掘,信息处理或存储历史数据等一系列的程序中. scrapy 框架 高性能的网络请求 高性能的数据解析 高性能的 ...

  9. Mac运行React Native安卓项目报错解决

    传送门参考: 下面的这个链接很详细了,一步一步就好.... https://github.com/NARUTOyuyang/React-Native 然而在运行react-native run-and ...

  10. Mac 配置flutter

    1. vim ~/.base_profile 2. 如下 export PATH=/Users/korea/Desktop/development/flutter/bin:$PATH export P ...