Vue.js 3 是一个声明式的 UI 框架,意思是说用户在使用 Vue.js 3 开发页面时是声明式地描述 UI 的。如何设计一个声明式框架呢?
一、声明式描述 UI
vue.js 3 是一个声明式的 UI 框架,如何设计 UI 框架,需要明确前端页面涉及的内容:
1、DOM 元素:例如标签;
2、属性:例如 class、id、style、src 等;
3、事件:例如 click、mouseover、keydown 等;
4、元素层级结构:DOM 树的层级结构,既有子节点,又有父节点。
如何声明式的描述上面前端页面涉及的内容呢?vue.js 3 解决方案:
1、使用 HTML 标签一致的方式来描述 dom 元素,例如:<div></div>
;
2、使用 HTML 标签一致的方式来描述属性,例如:<div class='app'></div>;v-bind 来描述动态绑定的属性,例如:<div :id="wrapper"></div>
;
3、使用 v-on 来描述事件,例如:<div @click="handleClick"></div>
;
4、使用 HTML 标签一致的方式来描述元素层级结构,例如:<div><span></span></div>
;
js 对象描述 UI 页面:
1 |
|
对应的 vue.js 模板就是:
1 |
|
js 对象来描述 UI 更具灵活性
1 |
|
vue.js 使用 JS 对象来描述 UI 的方式,其实就是所谓的虚拟 DOM。其实我们在 vue.js 组件中手写渲染函数就是使用虚拟 DOM 来描述 UI 的。
1 |
|
上面的 h 函数返回值就是一个对象,其作用是让我们编写虚拟 DOM 变的更加轻松。
如果把上面的 h 函数调用嗲买改成 js 对象,就需要写更多内容了:
1 |
|
如果还有子节点,写的内容就更多了,所以 h 函数就是一个辅助创建虚拟 dom 的工具函数,仅此而已。
什么是组件的渲染函数?
一个组件要渲染的内容是通过渲染函数来描述的,就是上面的 render 函数,vue.js 会根据组件的 render 函数的返回值拿到虚拟 dom,然后就可以把组件的内容渲染出来了。
二、渲染器
我们知道了虚拟 DOM 其实就是用 js 对象来描述真实的 dom 结构,那么 vue.js 是如何把虚拟 DOM 渲染成真实的 DOM 呢?
渲染器的作用就是把虚拟 DOM 渲染为真实 DOM。
编写一个渲染器,实现点击 div 标签,alert hello 功能
1 |
|
渲染器将上面虚拟 DOM 渲染为真实 DOM:
1 |
|
renderer 函数的 2 个参数说明:
- vnode:虚拟 DOM 对象
- container:真实 DOM 元素,作为挂载点,渲染器会把虚拟 DOM 渲染到该挂载点下。
renderer 渲染器的实现思路:
创建元素:把 vnode.tag 作为标签名称来创建 DOM 元素。
为元素添加属性和事件:遍历 vnode.props 对象,如果 key 以 on 字符开头,说明它是一个事件,把字符 on 截取掉后再调用 toLowerCase 函数将事件名称小写化,最终得到合法的事件名称,例如 onClick 会变成 click,最后调用 addEventListener 绑定事件处理函数。
处理 children:如果 children 是一个数组,就递归地调用 renderer 继续渲染,注意,此时我们要把刚刚创建的元素作为挂载点(父节点);如果 children 是字符串,则使用
createTextNode 函数创建一个文本节点,并将其添加到新创建的元素内。
三、组件的本质
1. 组件的定义
组件就是一组 DOM 元素的封装,这组 DOM 元素就是组件要渲染的内容,因此
我们可以定义一个函数来代表组件,而函数的返回值就代表组件要渲染的内容: