低代码组件设计思路(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 属性会发生改变。对于渲染器来说,就相当于省去了寻找变更点的工作量,性能自然就提升了
相关推荐
喵叔哟25 分钟前
重构代码之取消临时字段
java·前端·重构
还是大剑师兰特1 小时前
D3的竞品有哪些,D3的优势,D3和echarts的对比
前端·javascript·echarts
王解1 小时前
【深度解析】CSS工程化全攻略(1)
前端·css
一只小白菜~1 小时前
web浏览器环境下使用window.open()打开PDF文件不是预览,而是下载文件?
前端·javascript·pdf·windowopen预览pdf
方才coding1 小时前
1小时构建Vue3知识体系之vue的生命周期函数
前端·javascript·vue.js
阿征学IT1 小时前
vue过滤器初步使用
前端·javascript·vue.js
王哲晓1 小时前
第四十五章 Vue之Vuex模块化创建(module)
前端·javascript·vue.js
丶21361 小时前
【WEB】深入理解 CORS(跨域资源共享):原理、配置与常见问题
前端·架构·web
发现你走远了1 小时前
『VUE』25. 组件事件与v-model(详细图文注释)
前端·javascript·vue.js
Mr.咕咕1 小时前
Django 搭建数据管理web——商品管理
前端·python·django