<?xml version="1.0" encoding="utf-8" ?><rss version="2.0"><channel><title><![CDATA[tim1010101的博客]]></title><description><![CDATA[]]></description><link>https://blog.youkuaiyun.com/tim1010101</link><language>zh-cn</language><generator>https://blog.youkuaiyun.com/</generator><copyright><![CDATA[Copyright &copy; tim1010101]]></copyright><item><title><![CDATA[【手写简易版 vue3】究极长文详细讲解如何实现一个简易版 vue3]]></title><link>https://blog.youkuaiyun.com/tim1010101/article/details/121473903</link><guid>https://blog.youkuaiyun.com/tim1010101/article/details/121473903</guid><author>tim1010101</author><pubDate>Tue, 23 Nov 2021 13:29:49 +0800</pubDate><description><![CDATA[介绍一下 beggar-vue
笔者自己写了一个 vue3 的简易版实现，非常简易，没有阅读难度，起名 beggar-vue，意思不是 “乞丐版 vue”，而是 “乞丐看了都可怜的 vue”。虽然实现很粗糙，但实现原理方面基本完全贴合源码，少量不同的地方都会做出标注和提醒，源码传送门在这里 beggar-vue，以下是一些参考信息

References:
vue-next: vue3 源码，很值得看
vue-design: 一个大佬，vue 贡献者写的剖析 vue 设计原理的博客，很值得看
mini-vu]]></description><category></category></item><item><title><![CDATA[【手写简易版 vue3】总结]]></title><link>https://blog.youkuaiyun.com/tim1010101/article/details/121473814</link><guid>https://blog.youkuaiyun.com/tim1010101/article/details/121473814</guid><author>tim1010101</author><pubDate>Tue, 23 Nov 2021 13:21:31 +0800</pubDate><description><![CDATA[本篇总结一下整个 beggar-vue 的实现，会有些乱，但都是干货
reactivity

vue-next/packages/reactivity/src

响应式模块中我们实现了 reactive、effect、ref、computed，其中最核心的是 effect
reactive
reactive 我们做了简化，没有进行容错处理和特例处理，也因此整体结构非常清晰简单，通过 Proxy 代理 target 目标对象的存取操作，在其中进行依赖收集 track 以及触发更新 trigger
effect]]></description><category></category></item><item><title><![CDATA[编译模块7: compile 实现]]></title><link>https://blog.youkuaiyun.com/tim1010101/article/details/121473770</link><guid>https://blog.youkuaiyun.com/tim1010101/article/details/121473770</guid><author>tim1010101</author><pubDate>Tue, 23 Nov 2021 13:21:20 +0800</pubDate><description><![CDATA[源码位置:
vue-next/packages/compile-core/src/compile.ts

最后的最后就是整个模块的主入口了，只要把之前的模块整合起来即可
写一下
这里直接给出代码，不过多赘述了
// 插件预设
function getBaseTransformPreset() {
  return [
    [transformElement, transformText],
    {
      on: transformOn,
      bind: transformBind,
.]]></description><category></category></item><item><title><![CDATA[编译模块6: codegen 实现]]></title><link>https://blog.youkuaiyun.com/tim1010101/article/details/121473729</link><guid>https://blog.youkuaiyun.com/tim1010101/article/details/121473729</guid><author>tim1010101</author><pubDate>Tue, 23 Nov 2021 13:21:04 +0800</pubDate><description><![CDATA[源码位置:
vue-next/packages/compile-core/src/codegen.ts

上文实现了 transform，现在就进入整个 compile 最后的代码生成 codegen 环节了，个人感觉和前面的 transform 比起来，codegen 真的非常简单，源码位置在这里
说在开头
我的实现和源码实现区别蛮大的，因为源码中考虑了各种 helper、cache、hoist 之类的，而这些我都没实现。经过 transform 之后，AST 上的 codegenNode 节点上挂载的.]]></description><category></category></item><item><title><![CDATA[编译模块5: directiveTransforms 实现]]></title><link>https://blog.youkuaiyun.com/tim1010101/article/details/121473695</link><guid>https://blog.youkuaiyun.com/tim1010101/article/details/121473695</guid><author>tim1010101</author><pubDate>Tue, 23 Nov 2021 13:20:55 +0800</pubDate><description><![CDATA[源码位置:
vue-next/packages/compile-core/src/transforms/vOn.ts
vue-next/packages/compile-core/src/transforms/vBind.ts

到这里 transform 模块其实已经基本实现了，不过还需要专门再处理一下 v-on 和 v-bind，也以此作为一个简单的例子看看指令编译都会做些什么
解释一下
directiveTransforms 也是一类 transform plugin 转换插件，其中包括一些 tra.]]></description><category></category></item><item><title><![CDATA[编译模块4: transform 实现]]></title><link>https://blog.youkuaiyun.com/tim1010101/article/details/121473512</link><guid>https://blog.youkuaiyun.com/tim1010101/article/details/121473512</guid><author>tim1010101</author><pubDate>Tue, 23 Nov 2021 13:20:44 +0800</pubDate><description><![CDATA[源码位置:
vue-next/packages/compile-core/src/transform.ts

通过 parse 已经生成了一棵 AST，已经可以直接用这棵 AST 来生成目标代码，但是在前置知识中也有提到，并不是为了生成 AST 而生成 AST，实际上我们可以很方便的对 AST 进行修改，以实现一些其他的需求，这里的 transform 就是做这个的
讲在开头
整个 transform 的过程非常复杂，而最关键的是整个 transform 模块内聚程度很高，变量彼此联系非常紧密，难以彻底简.]]></description><category></category></item><item><title><![CDATA[编译模块3: parse 实现]]></title><link>https://blog.youkuaiyun.com/tim1010101/article/details/121473469</link><guid>https://blog.youkuaiyun.com/tim1010101/article/details/121473469</guid><author>tim1010101</author><pubDate>Tue, 23 Nov 2021 13:20:33 +0800</pubDate><description><![CDATA[源码位置:
vue-next/packages/compile-core/src/parse.ts

终于是可以开始写了，实际上，因为偷了大懒，parse 并不复杂，也不会很难理解，个人感觉更多的还是流程控制
分析一下
模板字符串实际上是一个长长的字符串，这意味着我们没法直接从结构上分析出标签的嵌套情况，这一点非常关键，因为嵌套标签，嵌套内容是非常非常常见的操作，因此在处理上需要注意，不过转念一想，其实需要递归调用 parseChildren 的只有一种情况，也就是标签中嵌套标签的情况
其实这里本来会是一.]]></description><category></category></item><item><title><![CDATA[编译模块2: parse 准备]]></title><link>https://blog.youkuaiyun.com/tim1010101/article/details/121473427</link><guid>https://blog.youkuaiyun.com/tim1010101/article/details/121473427</guid><author>tim1010101</author><pubDate>Tue, 23 Nov 2021 13:20:23 +0800</pubDate><description><![CDATA[源码位置:
vue-next/packages/compile-core/src/parse.ts

经过上文的铺垫，应该都对编译的过程以及 AST 的作用有了一定的认识，由于 parse 函数需要做的准备工作比较多，因此再分多一篇用来铺垫，下一篇就是正式实现了
解释一下
直接开一手上帝视角，照着源码的思路来进行解释
parse 做的事情简单来说就是将模板字符串中有用的信息以各种方式提取出来，并形成一个个节点，最终构建成一棵 AST。
一些准备工作
以下是实现 parse 前需要做的准备，以及一些会遇到的.]]></description><category></category></item><item><title><![CDATA[编译模块1: 一些前置知识]]></title><link>https://blog.youkuaiyun.com/tim1010101/article/details/121473356</link><guid>https://blog.youkuaiyun.com/tim1010101/article/details/121473356</guid><author>tim1010101</author><pubDate>Tue, 23 Nov 2021 13:20:12 +0800</pubDate><description><![CDATA[上回说到，我们已经完成了响应式模块 reactivity 以及运行时模块 runtime，而在 vue 的日常使用中还有一个必不可少的功能就是模板语法，虽说可以写 jsx，但是不管是 template 模板语法还是 jsx 最终其实都会被编译成 render 和 h，而且还有大量的指令需要处理，如 v-if、v-on 等，这些都是在编译模块 compiler 中实现的，接下来就来完成编译模块凑齐最后一块拼图
一轮快问快答
Q: 为什么需要编译？
A: 上面说了啊
Q: 怎么编译？
A: 这其实涉及到编译原理]]></description><category></category></item><item><title><![CDATA[渲染模块7: createApp 实现]]></title><link>https://blog.youkuaiyun.com/tim1010101/article/details/121473324</link><guid>https://blog.youkuaiyun.com/tim1010101/article/details/121473324</guid><author>tim1010101</author><pubDate>Tue, 23 Nov 2021 13:19:56 +0800</pubDate><description><![CDATA[源码位置:
vue-next/packages/runtime-core/src/apiCreateApp.ts
177 行

害这个真的很简单，就把之前写过的整合起来就行
看一下长啥样
还是不看了，因为真的就太熟了
直接写吧
createApp 需要接收根组件对象 rootComponent，返回一个 App 对象，这个 rootComponent 接口大概长这样
// vue-next/packages/runtime-core/src/componentOptions.ts
// 108 行
exp.]]></description><category></category></item><item><title><![CDATA[渲染模块6: 调度机制实现]]></title><link>https://blog.youkuaiyun.com/tim1010101/article/details/121473248</link><guid>https://blog.youkuaiyun.com/tim1010101/article/details/121473248</guid><author>tim1010101</author><pubDate>Mon, 22 Nov 2021 16:19:53 +0800</pubDate><description><![CDATA[源码位置:
vue-next/packages/runtime-core/src/scheduler.ts

其实本文中的调度机制，即 scheduler，是为了解决组件渲染时的一个渲染任务的调度问题，或者说调用时机的问题，属于是很典型的 “可以没有，但有了会更好”，但是考虑到有 nextTick 这么一个很好用的 API，且实现起来非常简单，因此顺带实现一下
为什么要调度
在前面实现的 component 的更新方法 instance.update 存在一个问题，就是 setup 中每一次 trigge.]]></description><category></category></item><item><title><![CDATA[渲染模块5: 组件渲染实现]]></title><link>https://blog.youkuaiyun.com/tim1010101/article/details/121473113</link><guid>https://blog.youkuaiyun.com/tim1010101/article/details/121473113</guid><author>tim1010101</author><pubDate>Mon, 22 Nov 2021 16:19:43 +0800</pubDate><description><![CDATA[源码位置:
vue-next/packages/runtime-core/src/component.ts
本文只实现了 Composition API，没有实现 Options API

随着前端业务越来越复杂，也就自然而然的出现了现代化的需求，如模块化、组件化、自动化、规范化，前文的 render 和 patch 都留好了坑，本文主要来实现组件的渲染
用用看
根据官网文档，定义如下全局组件(省略部分无关代码)
app.component('my-comp', {
    props: ['classN.]]></description><category></category></item><item><title><![CDATA[渲染模块4: diff 算法实现]]></title><link>https://blog.youkuaiyun.com/tim1010101/article/details/121472836</link><guid>https://blog.youkuaiyun.com/tim1010101/article/details/121472836</guid><author>tim1010101</author><pubDate>Mon, 22 Nov 2021 16:19:34 +0800</pubDate><description><![CDATA[正如上篇所说，vue3 的 diff 算法很有意思，性能也很好，但我指的不是前面那篇 patch，而是本篇的 diff 核心算法，源码中具体名为 patchKeyedChildren


以下的 diff 算法 均指 patchKeyedChildren 的实现
源码位置在'vue-next\packages\runtime-core\src\renderer.ts' 中的第 1762 行
以下所有图片中，c1 为旧的子节点，c2 为新的子节点，且上为 c1，下为 c2


解释一下

diff 算法非常重]]></description><category></category></item><item><title><![CDATA[渲染模块3: patch 实现]]></title><link>https://blog.youkuaiyun.com/tim1010101/article/details/121472739</link><guid>https://blog.youkuaiyun.com/tim1010101/article/details/121472739</guid><author>tim1010101</author><pubDate>Mon, 22 Nov 2021 16:19:22 +0800</pubDate><description><![CDATA[源码位置:
vue-next/packages/runtime-core/src/renderer.ts

在我写到这行时(2021-10-30 22:44)，vue(v3.2.1)还是三大框架(angular、react、vue)中跑 js web frameworks benchmark 最快的，抛开性能不谈，个人认为 vue3 的 diff 算法还是挺有意思的，而本文实现的是广义上的 diff 算法——patch，而由于追求精简，本文部分实现与源码有一定出入，但基本原理一致，可以放心参考
介绍一下
.]]></description><category></category></item><item><title><![CDATA[渲染模块2: render 实现]]></title><link>https://blog.youkuaiyun.com/tim1010101/article/details/121472668</link><guid>https://blog.youkuaiyun.com/tim1010101/article/details/121472668</guid><author>tim1010101</author><pubDate>Mon, 22 Nov 2021 16:19:11 +0800</pubDate><description><![CDATA[源码位置:
vue-next/packages/runtime-core/src/renderer.ts

结合上篇讲到的前置知识，本篇介绍 render 方法的实现，为了便于理解，仅保留核心部分，下文中 VNode 对象即是 虚拟 dom 对象
作为参考，暂时只实现元素节点与文本节点，关于 patch 和 diff 以及 component 的渲染后续专门介绍
分析一下
根据文档以及源码来看，vue 中使用 h 函数和 render 函数来进行渲染，组合起来如下所示
render() {
    ret.]]></description><category></category></item><item><title><![CDATA[渲染模块1: vnode & render 前置知识]]></title><link>https://blog.youkuaiyun.com/tim1010101/article/details/121472642</link><guid>https://blog.youkuaiyun.com/tim1010101/article/details/121472642</guid><author>tim1010101</author><pubDate>Mon, 22 Nov 2021 16:18:56 +0800</pubDate><description><![CDATA[在正式介绍渲染模块前，一些前置知识需要先解释一下
虚拟 dom
众所周知，vue 中运用了虚拟 dom 技术来提高性能，不过为什么虚拟 dom 是什么，为什么能提高性能呢，虚拟 dom 是最diao的么
虚拟 dom 技术简而言之指的是先将需要渲染的 dom 节点在内存中创建好，再通过渲染函数一次性渲染到页面中。
我们在 js 中进行的每一次 dom 操作都会引起页面回流或者重绘，大量的 dom 操作可能最终导致页面卡顿或白屏的情况。虽然目前大部分浏览器都有进行优化，维护一个操作队列，将所有会导致回流或者重]]></description><category></category></item><item><title><![CDATA[响应式模块4: computed 实现]]></title><link>https://blog.youkuaiyun.com/tim1010101/article/details/121472570</link><guid>https://blog.youkuaiyun.com/tim1010101/article/details/121472570</guid><author>tim1010101</author><pubDate>Mon, 22 Nov 2021 16:18:37 +0800</pubDate><description><![CDATA[本文对应源码位置
vue-next/packages/reactivity/src/computed.ts
26 行

做完前面那些，轮也该轮到 computed 了，computed 和前面的 reactive、ref 其实非常像，但是适用场景不同，原理方面也是非常非常像，先按照前面 ref 的思路写一个出来看看
照 ref 画 computed
按照源码中的实现，computed 实际上是 ComputedRefImpl 的实例对象，那么就可以按照前面的 ref 的实现照葫芦画瓢，如下
const c.]]></description><category></category></item><item><title><![CDATA[响应式模块3: ref 实现]]></title><link>https://blog.youkuaiyun.com/tim1010101/article/details/121472550</link><guid>https://blog.youkuaiyun.com/tim1010101/article/details/121472550</guid><author>tim1010101</author><pubDate>Mon, 22 Nov 2021 16:17:45 +0800</pubDate><description><![CDATA[本文对应源码位置
vue-next/packages/reactivity/src/ref.ts
91 行

ref 也是响应式数据的一种，类似于 reactive，不过通常用 ref 封装简单数据，如 Number、String、Boolean等，用 reactive 只能封装对象，如 Object、Array等。而查阅源码可以看到 ref 实际上是 RefImpl 的实例对象，因此也就很好实现了
逆向分析一下
依然是惯用的自顶向下开始分析，使用 ref 封装一个简单数据
const a = ref(0.]]></description><category></category></item><item><title><![CDATA[响应式模块2: effect 实现]]></title><link>https://blog.youkuaiyun.com/tim1010101/article/details/121472474</link><guid>https://blog.youkuaiyun.com/tim1010101/article/details/121472474</guid><author>tim1010101</author><pubDate>Mon, 22 Nov 2021 16:17:22 +0800</pubDate><description><![CDATA[本文对应源码位置
vue-next/packages/reactivity/src/effect.ts
53 行

前置知识
vue3 源码中使用了 WeakMap 来储存响应式对象与依赖的对应关系，而使用 WeakMap 个人觉得完全是出于性能考虑，因此可以使用 Map 进行代替。WeakMap 的键值必须是对象，我认为这也直接促成 reactive 在日常使用中只用来封装对象数据，这点与 ref 不同(后续实现)
写来看看
可以自顶向下进行分析，先看结果，实现雏形，之后慢慢完善细节，如下所示
cons.]]></description><category></category></item><item><title><![CDATA[响应式模块1: reactive 实现]]></title><link>https://blog.youkuaiyun.com/tim1010101/article/details/121472391</link><guid>https://blog.youkuaiyun.com/tim1010101/article/details/121472391</guid><author>tim1010101</author><pubDate>Mon, 22 Nov 2021 16:17:03 +0800</pubDate><description><![CDATA[本文对应源码位置
vue-next/packages/reactivity/src/reactive.ts
181 行

个人对响应式数据的理解为，数据更新以及数据获取时能够以某种方式主动让使用此数据的代码做出反应，简而言之就是在数据更新以及数据获取时能够执行别的操作，回归到 vue3 当中则是，数据更新时主动通过 trigger 方法触发依赖函数，获取数据时主动通过 track 方法将此依赖函数保存下来。
前置知识
响应式的核心原理通过 Proxy 和 Reflect 实现，以下内容来自MDN
Prox.]]></description><category></category></item></channel></rss>