Vue.js3的设计思路

224 阅读3分钟

一个框架的设计要有全局视角的把控。

比如一个项目,再大也是存在一条核心思路的;一个小说再长,它也会有至少一条主线、暗线,故事也将围绕此进行铺展开来。

声明式的UI

前文已经提过,Vue.js3是声明式的UI框架。设计这样的框架,我们至少要考虑这些问题:

  • Dom元素:是a标签还是div标签。
  • 属性:比如classid等属性,亦或者a标签的href属性。
  • 事件:keydownclick等等。
  • 元素的层级结构:有子节点又有父节点。

其实熟悉vue的朋友都知道,我们在描述dom节点的时候一般就是两种方式。

  1. 模板

    <template>
    	<!-- a -->
    	<div
             class="vuejs3"
             :name="vuejs3"
             @click="clickVuejs3"
        >
            vue.js 3
        </div>
    </template>
    

    上述内容就是我们常写的vue文件里的部分内容。那么一一拆解开来,

    a处对应的就是div标签。class是它绑定的类名属性、name是它动态绑定的属性、@click便是声明式的来声明事件等等……

  2. 虚拟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组件的时候就可以看出,模板、渲染函数其实是可以组合而用的。它们之间可以相互进行配合,进一步提升框架的性能。