1. 渲染函数
渲染函数(render函数)
- 通过 createElement 函数来创建虚拟DoM(VirtualDom),这个虚拟DOM包含的信息会告诉Vue页面上需要渲染出什么元素。
- 可以解决有些场景中用 template 实现起来代码冗长繁琐,而且有大量重复的问题。
渲染函数解析
- render函数的返回值 VNode (即:虛拟节点),也就是我们要渲染的节点。
- render函数的参数 createElement 是 render 函数的参数,它本身也是个函数,并且有三个参数。 createElement 函数的返回值也是 VNode虚拟节点。
demo<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> <script src="https://cdn.bootcss.com/vue/2.6.10/vue.min.js"></script> </head> <body> <div id="app"></div> </body> <script> Vue.component('heading-line', { render: function(createElement) { return createElement( 'h' + this.level,// 第一个参数是必选参数,可以是一个HTML标签,也可以是一个组件或函数。这里是标签名称 // 第二个参数是可选参数,数据对象,在template中使用,这里省略 this.$slots.default// 第三个是子节点,也是可选参数,需要渲染的子节点数组,它会将slot里面的内容分发到相应的节点上去 ) }, props: { level: {// 做校验,因为不做验证可能出一些bug type: Number, required: true } } }) new Vue({ el: '#app', template: "<div><heading-line :level='1'>我是标题</heading-line></div>" }) </script> </html>
2.认识节点、树及虚拟DOM
概念
- 当浏览器读到一些DOM结构时,会建立一个“DOM节点”树来保持追踪所有内容,如同你会画一张家谱树来追踪家庭成员的发展一样。
- 虚拟DOM(VirtualDom)就是通过一种 VNode(节点)类表达的,每个DOM元素或组件都对应一个 VNode对象。
- 使用 javascript对象模拟了DOM结构的树形结构,这个树结构包含整个DOM结构的信息。
VNode对象源码
每个DOM元素或组件都对应一个VNode对象,具体含义见代码所示
路径:src/core/vdom/vnode.js
this.tag = tag // 当前节点标签名
this.data = data // 当前节点数据(VNodeData类型)
this.children = children // 当前节点子节点
this.text = text // 当前节点文本
this.elm = elm // 当前节点对应的真实DOM节点
this.ns = undefined // 当前节点命名空间
this.context = context // 当前节点上下文
this.fnContext = undefined // 函数化组件上下文
this.fnOptions = undefined // 函数化组件配置项
this.fnScopeId = undefined // 函数化组件ScopeId
this.key = data && data.key // 子节点key属性
this.componentOptions = componentOptions // 组件配置项
this.componentInstance = undefined // 组件实例
this.parent = undefined // 当前节点父节点
this.raw = false // 是否为原生HTML或只是普通文本
this.isStatic = false // 静态节点标志 keep-alive
this.isRootInsert = true // 是否作为根节点插入
this.isComment = false // 是否为注释节点
this.isCloned = false // 是否为克隆节点
this.isOnce = false // 是否为v-once节点
this.asyncFactory = asyncFactory // 异步工厂方法
this.asyncMeta = undefined // 异步Meta
this.isAsyncPlaceholder = false // 是否为异步占位
节点、树及虚拟DOM
虚拟DOM不是真正意义上的DOM,而是一个轻量级的js对象,在状态改变的时候,虚拟DOM会进行diff算法计算,来更新只需要被更新的DOM,而不是全部的重绘重构。与DOM操作相比,虚拟DOM是基于js计算的,而且是在内存中的,所以开销会很小。
流程图:
3.JSX语法及函数式组件
这里只做简单介绍
JSX语法
- Javascript和XML结合的一种格式。最早 React 发明了JSX,利用HTML语法来创建虚拟DOM。JSX执行更快,因为它在编译为 JavaScript 代码后进行了优化。它是类型安全的,在编译过程中就能发现错误。使用JSX编写模板更加简单快速。
- JSX语法需要babel插件转译为普通的HTML。
函数式组件
- 可以把函数式组件想像成组件里的一个函数,入参是渲染上下文(render context),返回值是渲染好的HTML。
- 函数式组件没有this,参数就是靠context来传递的,context完整属性可参照官方文档查询。
- 特性:
1.Stateless(无状态):组件自身是没有状态的
2.Instanceless(无实例):组件自身没有实例,也就是没有this。export default { name: 'functional-button', functional: true, render(createElement, context) { return createElement('button', 'click me') } }
context对象
- props:提供所有prop的对象
- children:VNode子节点的数组
- slots:一个函数,返回了包含所有插槽的对象
- scopedSlots:(2.6.0+)一个暴露传入的作用域插槽的对象,也以函数形式暴露普通插槽。
- data:传递给组件的整个数据对象,作为 createElement的第二个参数传入组件,该对象可选
- parent:对父组件的引用
- listeners:(2.3.0+)一个包含了所有父组件为当前组件注册的事件监听器的对象。这是data.on的一个别名。
- injections:(2.3.0+)如果使用了 inject 选项,则该对象包含了应当被注入的属性。