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函数再去渲染呢?

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

相关推荐
剑之所向1 小时前
.NET 官方`System.Threading.Channels`
前端·javascript·数据库
计算机魔术师1 小时前
GPT-6 Astra幻觉砍到2%,却被一种老招数轻松绕过
前端
cjy0001112 小时前
2026AI 产品如何从一次性 Demo 变成可重复使用的业务工具?
前端·人工智能·fde
IT_陈寒2 小时前
React的状态更新坑得我差点加班到天亮
前端·人工智能·后端
风骏时光牛马2 小时前
深挖底层逻辑:XX源码深度拆解分析
前端
电商API_180079052472 小时前
电商商品价格监控工具淘宝京东商品价格抓取API项目实操分享
java·大数据·开发语言·前端·数据挖掘
sxmas3 小时前
用状态机与DAG建模四阶段业务流程:以MIND模型为例
前端
倔强的石头1063 小时前
【Linux指南】动静态库系列(七):符号表与重定位:链接器如何把函数调用接起来
linux·前端·javascript
a1117765 小时前
3D 脑图谱 / Bilingual 3D Brain Atlas 项目
前端
T1mzhou5 小时前
ARM64 Linux 6.10内核启动流程2-rootfs 怎么挂上
linux·服务器·前端