如何正确学习vue3.0源码

智数星罗盘
• 阅读 519

为什么要学源码

  • 技术是第一生产力
  • 学习 API 的设计目的、思路、取舍
  • 学习优秀的代码风格
  • 学习组织代码的方式
  • 学习实现方法的技巧
  • 学习 ES67 新 API、TS 高级用法
  • 不给自己设限,不要让你周围人的技术上限成为你的上限
  • 面试加分项
  • 装逼利器

学习源码副作用

  • 画虎不成反类犬(强行上马 vue3,自己焦头烂额、项目难以维护、同事苦不堪言)
  • 为了用而用,而不是因地制宜
  • 喜欢炫技写一下看似搞大上,实际没有可读性,影响团队协作的奇技淫巧

vue3 设计动机与目的

  • 更好的逻辑复用与代码组织

    • vue2 option api 的代码风格将同一逻辑点的代码分散在各处,会导致读者关注点分离,也不利于代码的逻辑复用;而 vue3 composition api 将同一业务逻辑的代码聚合在一起命名为 useXXX 函数,再通过 setup 将不同的逻辑组装起来并返回给组件 data,明显更方便逻辑复用。
    • vue2 mixin 用于逻辑复用的时候容易导致命名冲突和数据来源不清晰;而 vue3 provide/inject 配合 composition api 可以很方便的找到数据来源并通过解构重命名,明显更方便逻辑复用。
  • 更好的类型推导

    • 在 methods 中 this 指向组件实例而不是 method 本身,不利于类型推导。
    • 例如 this.router、this.store,每个新的插件都会需要向 Vue 追加类型定义。

更新前后对比

优化

  • 打包更小(全局 API tree-shaking)
  • 渲染、更新更快,内存占用减少
  • 使用 proxy 取代 Object.defineProperty
  • v-model 代替以前的 v-model 和.sync
  • 生命周期变更 例如 destroyed beforeDestroy 改为 unmounted beforeUnmount
  • 自定义指令 API 与生命周期保持一致
  • Diff 算法的提升(静态标记、静态提升)

新特性

  • Template 支持多个根标签
  • composition API 实现逻辑模块化和复用
  • Teleport 传送门组件 代码块挂载到任意位置
  • Suspense 悬停组件 异步加载组件使用(实验属性)
  • 使用 @vue/runtime-core 的 createRenderer 自定义渲染器(跨平台利器)
  • 使用 ts 编写源码,更好的类型推导、更好的适配 ts

更多变化

  • v3.cn.vuejs.org/guide/migra…

疑问解答

问题一:compostion api 根本没有解决任何问题,只是追逐新玩意的东西

尤雨溪: 不同意这个观点。
Vue 最开始很小,但是现在被广泛应用到不同级别复杂度的业务领域,有些可以基于 option API 很轻松处理,但是有些不可以。例如下面的场景:

  • 有很多逻辑的大型组件(数百行)
  • 在多个组件可复用的逻辑

对于问题 1,你需要把每个逻辑拆分到不同选项,例如,一段逻辑需要一些响应数据,一个计算属性,一些监听属性还有方法。你去了解这段逻辑时,需要不断上下移动阅读,虽然你知道一些属性是什么类型,但是你并不知道他具体的作用。当一个组件包含多个逻辑,情况就更糟糕了。如果用新的 API,可以将数据和逻辑组合在一起,最重要的是,你可以干净的把这些逻辑提取到一个函数,甚至一个单独的文件中。

问题二:使用新 API 导致逻辑分散到不同地方,违背"关注点分离"

尤雨溪: 这个问题和项目文件组织方式问题类似。我们很多人都同意按文件类型组织(布局放 HTML,样式 CSS,逻辑 JS)并不是正确的方式,因为强制把相关代码分割到三个文件,只是给人一种“关注点分离”的错觉。这里的关键是“关注点”不是由文件类型定义。相反,我们大多数选择以功能或者职责来组织文件,这正是人们喜欢 Vue 单文件组件的原因。SFC 就是按功能组织代码的方法,但讽刺的是当首次引入 SFC 时,许多人也是拒绝的,认为它违反了关注点分离。

问题三:新的语法让 Vue 失去简单性,导致"意大利面条式代码"的出现,降低项目维护性。

尤雨溪: 正好相反,新的 API 就是为了提高项目长期维护性的。如果我们查看任何 javascript 项目,都会从入口文件开始阅读,该文件的本质是你的应用启动时被隐式调用的"main"函数。如果只有一个函数入口,会导致意大利面条代码,那所有的 js 项目都是意大利面条代码。显然不是的,因为开发人员通过代码模块化或者较小的函数来组织代码。另外,我同意新的 API 理论上会降低代码质量的最低门槛。但是我们可以使用以往防止代码变成意大利面条的手段缓解这种情况。另一方面,新的 API 可以提升代码质量的最高上限,相比 option api,你可以重构为质量更高的代码。而且,基于 Option api 你还得解决类似 mixins 的问题。很多人认为"Vue 失去简单性",实际上只是失去组件内代码类型检查能力(就是你不知道一个变量时 data、method、还是 computed)。但是用新的 API,实现一个类型检测器也是非常容易实现以前的特性的。也就是说,你不应该被 option api 限制思维,而更多关注逻辑内聚问题

源码调试

  • 安装源码及依赖(安装依赖出错一般是 npm 淘宝源的问题或者需要梯子)
git clone https://github.com/vuejs/vue-next.git
yarn install
yarn dev --sourcemap
  • 在源码中打入 debugger 如何正确学习vue3.0源码
  • 对源码进行打包
yarn dev --sourcemap
  • 新建 packages/vue/examples/index.html 用于测试
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Title</title>
</head>
<body>
<div id="app">
  <div>
    <div>test demo {{msg}}</div>
    <div>test demo {{msgMore}}</div>
  </div>
</div>
<script src="../dist/vue.global.js"></script>
<script>
  Vue.createApp({    setup() {      const msg = Vue.ref('Hello')      const msgMore = Vue.computed(()=>msg.value+' world')      return {        msg,        msgMore      }    }  }).mount('#app')
</script>
</body>
</html>

参考Vue3源码视频讲解:进入学习

  • 谷歌浏览器打开 index.html F12 如何正确学习vue3.0源码 如何正确学习vue3.0源码
点赞
收藏
评论区
推荐文章
Jacquelyn38 Jacquelyn38
4年前
Vue3.0系列——「vue3.0性能是如何变快的?」
前言1.先学习vue2.x,很多2.x内容依然保留;2.先学习TypeScript,vue3.0是用TS重写的,想知其然知其所以然必须学习TS。为什么学习vue3.0?性能比vue2.x快1.2~2倍按需编译,体积比vue2.x更小组合API(类似ReactHook)更好的TS支持
Karen110 Karen110
4年前
盘点JavaScript中Eval函数的使用方法
大家好,我是进阶学习者。一、前言内建函数eval函数允许执行一个代码字符串。语法:letresulteval(code);例:letcode'alert("Hello")';eval(code);//Hello运行结果:代码字符串可能会比较长,包含换行符、函数声明和变量等。eval的结果是最后一条语句的结果。例:let
虾米大王 虾米大王
3年前
java代码055
code055.jsp问卷调查表调查问卷你经常使用的编程语言有哪些:JAVAPHP.NETC你目前掌握的技术有哪些:HTMLCSSJavascriptJSP在学习中哪一部分感觉有困难:JAVAPHP.NETC
Wesley13 Wesley13
4年前
java通过sina端口提取股票历史数据并存入MySQL
 1.提取股票代码代码见:http://www.oschina.net/code/snippet\_2688840\_55337(http://www.oschina.net/code/snippet_2688840_55337) 2抓取sina股票的json页面数据;代码见:http://www.oschina.net/code/snip
虾米大王 虾米大王
3年前
java代码056
code056.jsp保存调查问卷调查结果你经常使用的编程语言你目前掌握的技术在学习中感觉困难的部分
Wesley13 Wesley13
4年前
CRC32用途及写法
CRC32今天在看rocketmq源码时,看到CRC32,就记录下来以供学习。主要用途: 在远距离数据通信中,为确保高效而无差错地传送数据,必须对数据进行校验即差错控制。循环冗余校验CRC(CyclicRedundancyCheck/Code)是对一个传送数据块进行校验,是一种高效的差错控制方法。if(!checksum(c
Wesley13 Wesley13
4年前
JAVA_将二进制流转换成图片文件
_1. __\代码\_将二进制流转换成图片文件晚风工作室www.soservers.com    _跳至\1\(http://www.oschina.net/code/snippet_931591_1760429253)\全屏预览\(http://www.oschina.net/code/piece_full?code17
Wesley13 Wesley13
4年前
Oracle:Pivot 转多列并包含多个名称
SELECTFROM(SELECTl.DISTRIBUTOR_ID,d.SKU_CODE,d.WH_CODE,d.ORDER_PACKAGES,d.PRICE,d.YEARLY||d.MONTHLYasYM,d
Stella981 Stella981
4年前
Code
ylbtechCodeNFine:NFine介绍1\.NFine平台介绍返回顶部1、使用时请务必保留来源,请勿用于违反我国法律的web平台、如诈骗等非法平台网站。版权最终解释权归《NFine团队》所有NFine是一套基于ASP.NETMVCEF6Bootstrap开发出来的框架,源代码完全开源,可以帮助你解
Stella981 Stella981
4年前
PowerDesigner列名、注释内容互换
在用PowerDesigner时,常常在NAME或Comment中写中文在Code中写英文,Name只会显示给我们看,Code会使用在代码中,但Comment中的文字会保存到数据库TABLE的Description中,有时候我们写好了Name再写一次Comment很麻烦,以下两段代码就可以解决这个问题。在PowerDesigner中PowerDesig
五、飞鹅官网API接口文档
接口列表1.获取网站信息请求方法:GET请求URL:/api/site/getSiteInfo请求参数无返回结果json"code":1,"data":"id":1,//id"title":"SampleSiteName",//网站名称"intro":"T