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

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

相关推荐
四岁半儿2 小时前
常用css
前端·css
你的人类朋友2 小时前
说说git的变基
前端·git·后端
姑苏洛言2 小时前
网页作品惊艳亮相!这个浪浪山小妖怪网站太治愈了!
前端
字节逆旅2 小时前
nvm 安装pnpm的异常解决
前端·npm
Jerry3 小时前
Compose 从 View 系统迁移
前端
GIS之路3 小时前
2025年 两院院士 增选有效候选人名单公布
前端
四岁半儿3 小时前
vue,H5车牌弹框定制键盘包括新能源车牌
前端·vue.js
烛阴3 小时前
告别繁琐的类型注解:TypeScript 类型推断完全指南
前端·javascript·typescript
gnip3 小时前
工程项目中.env 文件原理
前端·javascript
JefferyXZF4 小时前
Next.js Server Actions 详解: 无缝衔接前后端的革命性技术(八)
前端·全栈·next.js