一个框架的设计要有全局视角的把控。
比如一个项目,再大也是存在一条核心思路的;一个小说再长,它也会有至少一条主线、暗线,故事也将围绕此进行铺展开来。
声明式的UI
前文已经提过,Vue.js3
是声明式的UI
框架。设计这样的框架,我们至少要考虑这些问题:
Dom
元素:是a
标签还是div
标签。- 属性:比如
class
、id
等属性,亦或者a
标签的href
属性。 - 事件:
keydown
、click
等等。 - 元素的层级结构:有子节点又有父节点。
其实熟悉vue的朋友都知道,我们在描述dom节点的时候一般就是两种方式。
-
模板
<template> <!-- a --> <div class="vuejs3" :name="vuejs3" @click="clickVuejs3" > vue.js 3 </div> </template>
上述内容就是我们常写的vue文件里的部分内容。那么一一拆解开来,
a处对应的就是
div
标签。class
是它绑定的类名属性、name
是它动态绑定的属性、@click
便是声明式的来声明事件等等…… -
虚拟
dom
上述模板使用虚拟
dom
可以如下描述{ tag: "div", props:{ onClick: clickVuejs3, class: "vuejs3", name: vuejs3, }, children:["vue.js 3"], // 嵌套式的描述子组件 }
其实虚拟dom
就是一个JavaScript
对象,是一种对UI的描述方式。我们常使用的h
函数其实就是在创建虚拟dom
。相比于模板,虚拟dom
会更加灵活,可玩性更高。
渲染器
简单来说,渲染器的作用便是
虚拟dom
=> 渲染器 => 真实dom
。
那么对于模板,我们还需要将其编译成虚拟dom
,或者说生成一个功能相同的渲染函数。如果了解编译原理知识的朋友便知道大致步骤其实是类似的,这本书对其的详细介绍放在了第十五章之后,后面如果更新会再详细解释。现在只需知道模板最终生成的结果是虚拟dom即可。
感兴趣的朋友可以自己尝试写一个简单的渲染器,但注意生成props
的时候需要区分事件、区分动态属性等等,无非加一层判断条件;注意子节点的递归生成……
组件的本质
一句话总结:组件就是一组dom
元素的封装。
之前我们通过tag
描述当前的标签,如果是一个组件的话
const vnode = {
tag: MyComponent
}
对于MyComponent
来说,你就需要返回一个虚拟dom
即可,这时,它便可以是一个函数;当然也可以是一个对象直接进行描述。
const MyComponent = function() {
return {
tag: "div",
// props ……
}
}
同时,我们在渲染的时候就需要多一些判断,对于不同的格式进行一些不同的操作即可。
总结
vue其实是各个模块的有机整体,其实我们在写一个.vue
组件的时候就可以看出,模板、渲染函数其实是可以组合而用的。它们之间可以相互进行配合,进一步提升框架的性能。