You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
// an object format describing a single-file component.declaretypeSFCDescriptor={template: ?SFCBlock;
script: ?SFCBlock;
styles: Array<SFCBlock>;
customBlocks: Array<SFCBlock>;};
由于是专题学习,所以很多与专题关联不大的内容可能不会进行详细进行说明,尽量保持专题内容的内聚性,所以如果有疑问的点,可以在群内讨论,也可以参考下历史的分享文档
下面的分享内容仅代表自己的一些理解,有错误的地方也欢迎大家及时指出讨论
今天分享的内容主要有以下三点:
组件化的由来
在介绍现在的组件化思路之前,我们可以回忆下使用PHP或者JSP编写前端相关代码的时候,当时的代码编写思路
最初的思路是如何将页面从后端传回给浏览器作展示。每当用户点击link的时候,服务端渲染新的page,然后浏览器跳转的新的page即可
这些页面大都是静态页面,但是如果是构建一个需要处理用户交互的web应用,这类静态页面就有无法满足需求了
此时我们可以在返回的page上 head / body 内加一些 script 来实现逻辑处理
但随着业务体量变大,需求越来越多,这么编写代码的维护成本也会越来越高,代码就需要做一定的拆分
传统的拆分方法
传统的业务的代码拆分把 HTML / JS / CSS 单独的用特定的文件从page中拆离出来:
这样可能更加直观一些:
这类拆分方法一定程度上的降低了维护难度,将内容拆解到了相关的文件中,解耦了页面内容
但其中 JS 的模块加载管理,CSS的作用域、优先级等的逻辑统一管理起来成本依然很高,并且这类代码组织方式可能会让项目 割裂严重,编辑成本很高,可能排查个问题需要连续查找并编辑多个不同的文件,才能完成
vue中的拆分方法
那么vue为了解决这些问题,选择了把page中逻辑上相关联的 HTML / CSS / JS 抽离出来统一管理:
这样单独拆分出来的内容,在Vue内可以用*.vue的文件进行组织,这类 功能内聚 且 相互间有关联的 template / script / style 的内容可称为 Vue组件
Tips: SFC 的解析
在vue中,框架允许使用者以一种名为单文件组件 SFC(single file component) 的格式撰写 Vue 组件,但是浏览器并不支持这类文件的解析,所以在打包的时候还是得走一遍编译,在vue-loader 中调用 vue-template-compiler 走一遍简单的处理,最后被处理完为一个JS对象 SFCDescriptor
vue-loader 中的 vue-template-compiler 的这部分代码其实是从vue源码中抽离的,真正的代码在 src/platforms/web/entry-compiler.js 中
组件化的实现
上面介绍完了Vue组件的由来,我们从一个最简单的组件demo看起,看看一个实际的组件,是怎么在vue内跑起来的
这里我们就跳过编译部分,直接在这里写render函数了
组件化的实现逻辑
实例化过程
下面我们就进入源码分析环节,难度会有一部分的提升
首先我们回顾下Vue实例化的整个流程
这里大部分的内容我们在第一次的Vue实例化分享中基本都有提到,组件化这次需要额外关注这两个地方:
__patch__
首先我们来看看createComponent
createComponent
这里的逻辑主要三个点,我们顺着思维导图依次看一下:
(源码地址)
patch
patch这部分我们在前面文章内也大致分析过(链接)
当时点到了createElm这个函数,我们现在来详细分析下这个函数的功能
这里又回到了上面讲到的init部分的内容了,我们详细看看init这部分的逻辑
接下来的过程就和我们普通实例化流程基本一样了,走一遍render / $mount, 在patch中先创建一个父节点占位符,然后再遍历所有子 VNode 递归调用 createElm,在遍历的过程中,如果遇到子 VNode 是一个组件的 VNode,则重复本节开始的过程,这样通过一个递归的方式就可以完整地构建了整个组件树
那么完整串起来,我们的整个逻辑就是这样的了
局部注册 / 全局注册
讲完了实例化,我们再来看看组件注册的两种方式,理解起来就更顺了
异步组件
我们在开发大型应用的时候,往往会把一些首屏没有用到的组件,或者不影响应用使用的组件做异步加载,用于减小首屏代码体积,提升应用性能
异步组件一共有三种类型,我们这里直接看下最复杂的这种高级异步组件
那这个功能在Vue中是怎么实现的呢?我们顺着思维导图再看看
(代码)
组件化的未来
到这里,基本上我们就把Vue2.x中的组件化大概的实例化过程和一部分高级功能做了较为详细的分析
在组件化的这个方向上,还有哪些其他的思考点呢,我们再来看看
Web 开发由于其存在方式,必然需要在「避免构建」和「提高生产力」之前作出选择,Vue这类组件方案,其实最后还是构建成了一个普通的JS对象,否则是无法直接被浏览器识别加载的,但是web component解决了这个问题
web component
原生组件是一个5年前,就提出的概念了,目前的特性支持率也很高了
优点:
但是似乎主流框架没有并没有把它整合到现有的组件实现逻辑中,这是为啥呢?
优点:
但是似乎主流框架没有并没有把它整合到现有的组件实现逻辑中,主要原因可能有下面几点:
现有的组件实现逻辑相比web component,短时间内还是有很大的优势
延伸问题讨论
分享到这里,我们本次的Vue组件化分享的主要内容就已经基本分享完毕了,接下来我们可以再一起讨论下上周在群内收集到的关于hoc和mixin的这个问题
HOC / mixin in Vue
HOC定义:
仅使用mixin带来的问题:
vue现有的mixin demo:
用于实现hoc的demo:
vue3 中 Composition-api 的实现,对于复杂minxin的优化问题,将会是一个不错的解决方案
参考内容
The text was updated successfully, but these errors were encountered: