Vue源码分析及实现-序章

101 阅读3分钟

最近被裁了😂,正好有大把时间来深入一下Vue源码了,笔者开发是主React,副Vue的,可能出现错误敬请谅解。

作为任务的开始,我们先来了解一些常见基础概念。

编程范式

编程范式分为:

  • 命令式:关注过程的一种编程范式,描述了完成一个功能的详细逻辑和步骤,当项目越复杂,描述难度越大
  • 声明式:关注结果的一种编程范式,并不关心完成一个功能的详细逻辑与步骤

声明式 VS 命令式

  • 性能:命令式>=声明式
  • 可维护性:声明式>=命令式

.vue中的html如何转化

  • 编译时:compiler:把html的节点,编译成render函数
  • 运行时:runtime:利用rendervnode渲染成真实dom节点
  • 运行时+编译时:runtime+compiler

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

为什么vue要设计成一个 运行时+编译时的框架

首先要理清dom渲染是如何进行的,可以分为两部分: - 初次渲染,可以叫做挂载 - 更新渲染,可以叫做打补丁

初次渲染

什么是初次渲染呢? 假如有如下节点:

<div id='app'></div>

这时节点的innerHTML为空,我们在该div中渲染如下节点:

<ul>
    <li>1</li>
    <li>2</li>
</ul>

最后结果为:

<div id='app'>
    <ul>
        <li>1</li>
        <li>2</li>
    </ul>
</div>

此时就是初次渲染

更新渲染

更新渲染即,初始状况为上一步的结果时,假如我们需要对li进行更改,更改玩,就会发生浏览器渲染,这就是更新渲染。

但是浏览器更新渲染也会出现两种方式:

  1. 删除所有的节点,重新渲染新的节点
  2. 删除原位置的节点,在新位置插入

第一种是不做任何比较,直接进行:这会涉及到更多的DOM操作,更耗时 第二种会进行比较,只对需要更改的节点起作用,其他节点不变:这会涉及到js计算+少量的dom操作

答:

  • 针对纯运行时,因为不存在编译器,所以只能提供一个复杂的JS对象
  • 针对纯编译时,因为缺少运行时,所以只能把分析差异的操作,放到编译时运行,同样因为省略了运行时,所以速度可能会更快,但是这将损失灵活性,比如svelte,他就是一个纯编译时的框架,但是他的实际运行速度可能达不到理论上的速度
  • 运行时+编译时:比如 Vue或React都是通过这种方式来构建的,使其可以在保持灵活性的基础上,尽量进行性能的优化,从而达到一种平衡

什么是副作用

副作用:当我们对数据进行settergetter操作时,所产生的一系列后果

Vue中的响应核心依赖于settergetter,即赋值和取值行为能够产生副作用

Vue3基本框架设计

核心三大模块:

  • 响应性:reactivity
  • 运行时:runtime
  • 编译器:compiler

根据结构阐述

<template>
	<div>
    {{proxyTarget.name}}
  </div>
</template>

<script setup>
import {reactive} from 'vue';

const target={
  name:'伯nulee'
}

const proxyTarget=reactive(target)

</script>

对于响应性而言:上面代码响应性暴露出reactive函数,可以接收一个复杂数据类型作为被代理对象,返回一个代理对象,当proxyTarget触发settergetter行为的时候,都会产生对应的副作用

编译器:对于编译器而言,是把模板即template中代码编译成render函数

运行时:把compile编译器返回的render函数进行调用从而渲染成真实dom