vue3源码中需要弄清楚的几个概念

作为开发人员,我们经常听到两种编程范式:

  1. 命令式编程
  2. 声明式编程

这二者到底有什么区别呢?下面的解释让你一目了然。

命令式编程

命令式 过程、步骤清晰。

javascript 复制代码
// 1. 获取到指定的 div
const divEle = document.querySelector('#app')
// 2. 为该 div 设置 innerHTML 为 hello world
divEle.innerHTML = 'hello world'

声明式编程

声明式 看不到 具体步骤,只关注结果。

javascript 复制代码
<div id="app">
    <p>{{ msg }}</p>
</div>

明白了什么是命令式和声明式编程,那么对于一个完整的功能来说,使用哪种编程方式比较好呢?在开发过程中,我们需要考虑代码的性能可维护性,通过分析对比可知:

  1. 性能:命令式 > 声明式
  2. 可维护性:命令式 < 声明式

因此,Vue实质上将两种编程方式结合,用命令式编程封装内部逻辑,暴露出声明式接口供大家使用。对于Vue 而言,它的设计原则就是:在保证可维护性的基础上,尽可能的减少性能的损耗

什么是runtime运行时

vue3源码中存在一个render渲染函数,运行时可以利用render函数把vnode渲染成真实 dom 节点。实现逻辑如下:

javascript 复制代码
<head>
  <meta charset="UTF-8">
  <title>Document</title>
  <script src="https://unpkg.com/vue@3.2.36/dist/vue.global.js"></script>
</head>

<body>
  <div id="app"></div>
</body>

<script>
  const { render, h } = Vue
  // 生成 VNode
  const vnode = h('div', {
    class: 'test'
  }, 'hello render')

  // 承载的容器
  const container = document.querySelector('#app')

  // 渲染函数
  render(vnode, container)
</script>

此时有木有人疑惑,vnode是什么,从哪来?

什么是h函数

h函数用来生成一个vnode,打印vnode,精简结构如下:

javascript 复制代码
{
  // 是否是一个 VNode 对象
	"__v_isVNode": true,
  // 当前节点类型
	"type": "div",
  // 当前节点的属性
	"props": { "class": "test" }
  // 它的子节点
	"children": "hello render"
}

到这里,就可以通过render函数结合h函数完成渲染了。那么 HTML标签结构如何实现渲染呢?那就需要 complier编译时了。

什么是编译时

编译时就是解析html节点,将其编译成render函数,请看如下案例:

javascript 复制代码
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <title>Document</title>
  <script src="https://unpkg.com/vue@3.2.36/dist/vue.global.js"></script>
</head>

<body>
  <div id="app"></div>
</body>

<script>
  const { compile, createApp } = Vue

  // 创建一个 html 结构
  const html = `
    <div class="test">hello compiler</div>
  `
  // 利用 compile 函数,生成 render 函数
  const renderFn = compile(html)

  // 创建实例
  const app = createApp({
    // 利用 render 函数进行渲染
    render: renderFn
  })
  // 挂载
  app.mount('#app')
</script>

</html>

vue 通过 compiler 解析 html 模板,生成 render 函数,然后通过 runtime 解析 render,从而挂载真实 dom

到这里,估计有人疑惑了,既然compiler 可以解析 html 模板,为什么还要生成render函数再去渲染呢?

那就涉及到初次渲染和更新渲染的逻辑了,内容比较多,也比较重要,下一篇详细说明,欢迎大家指正。

相关推荐
代码AI弗森2 分钟前
前端周刊第 467 期[特殊字符] 本期精选目录
前端
随便的名字3 分钟前
前端路由的底层逻辑:URL 中 # 和 ? 的区别与关系详解
前端
kongba0075 分钟前
ttyd Web终端安装指南(OpenCloudOS 9)
linux·前端
zhoumeina995 分钟前
前端串行合成流程 + 每张图上传接口
前端·状态模式
风骏时光牛马7 分钟前
Swift 基于MVVM架构实现完整列表数据展示与交互功能实战案例
前端
就叫_这个吧16 分钟前
JavaScript基础数据类型、运算符、数组、函数的定义及DOM方式应用
开发语言·前端·javascript
作业逆流成河23 分钟前
别再一次性重构枚举了:如何把一个真实后台项目的状态字典,渐进式迁移到enum-plus?
前端·javascript·开源
暗不需求23 分钟前
React 性能优化秘籍:深入理解 `useMemo` 与 `useCallback`
前端·react.js·面试
专注VB编程开发20年29 分钟前
我制作excel工作簿的选项卡,发给deep seek, 昨天修改了一天
前端·vue.js·excel
light blue bird35 分钟前
工序路径主子表单工序组装图表组件
前端·数据库·信息可视化·.net·web端·razor page