低代码组件设计思路(Vue.js 3 的设计思路)

从全局视角了解 Vue.js 3 的设计思路、工作机制及其重要的组成部分

声明式地描述 UI

如何设计一个声明式的UI框架

编写前端页面

  • 具体页面内容
    • DOM 元素:例如是 div 标签还是 a 标签
    • 属性:如 a 标签的 href 属性,再如 id、class 等通用属性
    • 事件:如 click、keydown 等
    • 元素的层级结构:DOM 树的层级结构,既有子节点,又有父节点
  • 声明式的描述页面的内容
    • 模板式声明
    • 使用与 HTML 标签一致的方式来描述 DOM 元素
      • 例如描述一个div 标签时可以使用
    • 使用与 HTML 标签一致的方式来描述属性
      • 例如
    • 使用 : 或 v-bind 来描述动态绑定的属性
      • 例如
    • 使用 @ 或 v-on 来描述事件
      • 例如点击事件 <div @click="handler">
    • 使用与 HTML 标签一致的方式来描述层级结构
      • 例如一个具有span 子节点的 div 标签
    • JavaScript 对象描述
    • 两者差异
      • 使用 JavaScript 对象描述 UI 更加灵活
      • 在 Vue.js 组件中手写的渲染函数就是使用虚拟 DOM 来描述 UI 的
      • 渲染函数
        • h 函数的返回值就是一个对象,其作用是让我们编写虚拟DOM 变得更加轻松
        • 简单的渲染函数

初识渲染器

渲染器的作用就是把虚拟 DOM 渲染为真实 DOM

渲染器的作用

渲染器的简单实现

  • 虚拟 DOM
    • tag 用来描述标签名称,所以 tag: 'div' 描述的就是一个
      标签
    • props 是一个对象,用来描述
      标签的属性、事件等内容。可以看到,给 div 绑定一个点击事件
    • children 用来描述标签的子节点。在上面的代码中,children是一个字符串值,意思是 div 标签有一个文本子节点:
      click me
  • 简单渲染器
    • renderer 函数接收如下两个参数
      • vnode:虚拟 DOM 对象
      • container:一个真实 DOM 元素,作为挂载点,渲染器会把虚拟 DOM 渲染到该挂载点下
  • 渲染器 renderer 的实现思路
    • 创建元素:把 vnode.tag 作为标签名称来创建 DOM 元素
    • 为元素添加属性和事件:遍历 vnode.props 对象,如果 key 以on 字符开头,说明它是一个事件,把字符 on 截取掉后再调用toLowerCase 函数将事件名称小写化,最终得到合法的事件名称,例如 onClick 会变成 click,最后调用addEventListener 绑定事件处理函数
    • 处理 children:如果 children 是一个数组,就递归地调用renderer 继续渲染,注意,此时我们要把刚刚创建的元素作为挂载点(父节点);如果 children 是字符串,则使用createTextNode 函数创建一个文本节点,并将其添加到新创建的元素内

渲染器数据更新

  • 修改vnode
  • 需要精确地找到 vnode 对象的变更点并且只更新变更的内容

组件的本质

组件是什么呢?组件和虚拟 DOM 有什么关系?渲染器如何渲染组件?

定义

  • 组件就是一组 DOM 元素的封装

组件的渲染

  • 定义一个函数来代表组件
    • 返回值是虚拟DOM
  • 让虚拟 DOM 对象中的 tag 属性来存储组件函数
  • 修改前面的提到的 renderer 函数
      • mountElement
        • 与上文中 renderer 函数的内容一致
      • mountComponent

模板的工作原理

模板是如何工作的呢?

编译器的作用

  • 将模板编译为渲染函数
    • 对于编译器来说,模板就是一个普通的字符串
    • 会分析该字符串并生成一个功能与之相同的渲染函数
  • 无论是使用模板还是直接手写渲染函数,对于一个组件来说,它要渲染的内容最终都是通过渲染函数产生
  • 渲染器再把渲染函数返回的虚拟 DOM 渲染为真实 DOM,这就是模板的工作原理,也是 Vue.js 渲染页面的流程

Vue.js 是各个模块组成的有机整体

Vue.js 的各个模块之间是互相关联、互相制约的,共同构成一个有机整体

  • 假设有如下模板
  • 编译器会把这段代码编译成渲染函数
      • cls 是一个变量,它可能会发生变化
      • 渲染器的作用之一就是寻找并且只更新变化的内容,所以当变量 cls 的值发生变化时,渲染器会自行寻找变更点
      • 编译器有能力分析动态内容,并在编译阶段把这些信息提取出来,然后直接交给渲染器
      • 编译器能识别出哪些是静态属性,哪些是动态属性
      • 渲染器看到这个标志时就知道:只有 class 属性会发生改变。对于渲染器来说,就相当于省去了寻找变更点的工作量,性能自然就提升了
相关推荐
爱生活的苏苏10 分钟前
vue生成二维码图片+文字说明
前端·vue.js
拉不动的猪13 分钟前
安卓和ios小程序开发中的兼容性问题举例
前端·javascript·面试
炫彩@之星18 分钟前
Chrome书签的导出与导入:步骤图
前端·chrome
贩卖纯净水.29 分钟前
浏览器兼容-polyfill-本地服务-优化
开发语言·前端·javascript
前端百草阁35 分钟前
从npm库 Vue 组件到独立SDK:打包与 CDN 引入的最佳实践
前端·vue.js·npm
夏日米米茶36 分钟前
Windows系统下npm报错node-gyp configure got “gyp ERR“解决方法
前端·windows·npm
且白1 小时前
vsCode使用本地低版本node启动配置文件
前端·vue.js·vscode·编辑器
程序研1 小时前
一、ES6-let声明变量【解刨分析最详细】
前端·javascript·es6
siwangqishiq22 小时前
Vulkan Tutorial 教程翻译(四) 绘制三角形 2.2 呈现
前端
李三岁_foucsli2 小时前
js中消息队列和事件循环到底是怎么个事,宏任务和微任务还存在吗?
前端·chrome