Skip to content

Commit 37c101b

Browse files
committed
add page titles
1 parent 8c49916 commit 37c101b

33 files changed

+279
-148
lines changed

docs/BuiltInComponents/keep-alive.md

+11-7
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
---
2+
title: keep-alive
3+
---
4+
15
## 1. 前言
26

37
`<keep-alive>``Vue` 实现的一个内置组件,也就是说 `Vue` 源码不仅实现了一套组件化的机制,也实现了一些内置组件,关于`<keep-alive>`组件,官网如下介绍:
@@ -362,7 +366,7 @@ if (cache[key]) {
362366
/* 调整该组件key的顺序,将其从原来的地方删掉并重新放在最后一个 */
363367
remove(keys, key)
364368
keys.push(key)
365-
}
369+
}
366370
/* 如果没有命中缓存,则将其设置进缓存 */
367371
else {
368372
cache[key] = vnode
@@ -379,7 +383,7 @@ vnode.data.keepAlive = true
379383
首先获取组件的`key`值:
380384
381385
```javascript
382-
const key = vnode.key == null?
386+
const key = vnode.key == null?
383387
componentOptions.Ctor.cid + (componentOptions.tag ? `::${componentOptions.tag}` : '')
384388
: vnode.key
385389
```
@@ -393,7 +397,7 @@ if (cache[key]) {
393397
/* 调整该组件key的顺序,将其从原来的地方删掉并重新放在最后一个 */
394398
remove(keys, key)
395399
keys.push(key)
396-
}
400+
}
397401
```
398402
399403
直接从缓存中拿 `vnode` 的组件实例,此时重新调整该组件key的顺序,将其从原来的地方删掉并重新放在`this.keys`中最后一个。
@@ -450,10 +454,10 @@ let A = {
450454
console.log('Comp A mounted')
451455
},
452456
activated(){
453-
console.log('Comp A activated')
457+
console.log('Comp A activated')
454458
},
455459
deactivated(){
456-
console.log('Comp A deactivated')
460+
console.log('Comp A deactivated')
457461
}
458462
}
459463

@@ -466,10 +470,10 @@ let B = {
466470
console.log('Comp B mounted')
467471
},
468472
activated(){
469-
console.log('Comp B activated')
473+
console.log('Comp B activated')
470474
},
471475
deactivated(){
472-
console.log('Comp B deactivated')
476+
console.log('Comp B deactivated')
473477
}
474478
}
475479

docs/complie/HTMLParse.md

+29-25
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
---
2+
title: 模板解析阶段(HTML解析器)
3+
---
4+
15
## 1. 前言
26

37
上篇文章中我们说到,在模板解析阶段主线函数`parse`中,根据要解析的内容不同会调用不同的解析器,
@@ -25,19 +29,19 @@ export function parse(template, options) {
2529
shouldDecodeNewlines: options.shouldDecodeNewlines,
2630
shouldDecodeNewlinesForHref: options.shouldDecodeNewlinesForHref,
2731
shouldKeepComment: options.comments,
28-
// 当解析到开始标签时,调用该函数
32+
// 当解析到开始标签时,调用该函数
2933
start (tag, attrs, unary) {
3034

3135
},
3236
// 当解析到结束标签时,调用该函数
3337
end () {
3438

3539
},
36-
// 当解析到文本时,调用该函数
40+
// 当解析到文本时,调用该函数
3741
chars (text) {
3842

3943
},
40-
// 当解析到注释时,调用该函数
44+
// 当解析到注释时,调用该函数
4145
comment (text) {
4246

4347
}
@@ -62,7 +66,7 @@ export function parse(template, options) {
6266
start (tag, attrs, unary) {
6367
let element = createASTElement(tag, attrs, currentParent)
6468
}
65-
69+
6670
export function createASTElement (tag,attrs,parent) {
6771
return {
6872
type: 1,
@@ -95,7 +99,7 @@ export function parse(template, options) {
9599
let element = {
96100
type: 3,
97101
text
98-
}
102+
}
99103
}
100104
}
101105
```
@@ -169,7 +173,7 @@ function advance (n) {
169173
html = html.substring(n)
170174
}
171175
```
172-
为了更加直观地说明 `advance` 的作用,请看下图:
176+
为了更加直观地说明 `advance` 的作用,请看下图:
173177
![](~@/complie/5.png)
174178

175179
调用 `advance` 函数:
@@ -295,7 +299,7 @@ if (start) {
295299

296300
所谓不符合开始标签的结束特征是指当前剩下的字符串不是以开始标签结束符开头的,我们知道一个开始标签的结束符有可能是一个`>`(非自闭合标签),也有可能是`/>`(自闭合标签),如果剩下的字符串(如`></div>`)以开始标签的结束符开头,那么就表示标签属性已经被提取完毕了。
297301

298-
302+
299303

300304
2. 解析标签是否是自闭合
301305

@@ -360,7 +364,7 @@ function parseStartTag () {
360364
/**
361365
* <div a=1 b=2 c=3></div>
362366
* 从<div之后到开始标签的结束符号'>'之前,一直匹配属性attrs
363-
* 所有属性匹配完之后,html字符串还剩下
367+
* 所有属性匹配完之后,html字符串还剩下
364368
* 自闭合标签剩下:'/>'
365369
* 非自闭合标签剩下:'></div>'
366370
*/
@@ -551,7 +555,7 @@ if (endTagMatch) {
551555
let textEnd = html.indexOf('<')
552556
// '<' 在第一个位置,为其余5种类型
553557
if (textEnd === 0) {
554-
// ...
558+
// ...
555559
}
556560
// '<' 不在第一个位置,文本开头
557561
if (textEnd >= 0) {
@@ -610,7 +614,7 @@ while (
610614
!comment.test(rest) &&
611615
!conditionalComment.test(rest)
612616
) {
613-
617+
614618
}
615619
```
616620

@@ -643,7 +647,7 @@ while (
643647

644648
## 4. 如何保证AST节点层级关系
645649

646-
上一章节我们介绍了`HTML`解析器是如何解析各种不同类型的内容并且调用钩子函数创建不同类型的`AST`节点。此时你可能会有个疑问,我们上面创建的`AST`节点都是单独创建且分散的,而真正的`DOM`节点都是有层级关系的,那如何来保证`AST`节点的层级关系与真正的`DOM`节点相同呢?
650+
上一章节我们介绍了`HTML`解析器是如何解析各种不同类型的内容并且调用钩子函数创建不同类型的`AST`节点。此时你可能会有个疑问,我们上面创建的`AST`节点都是单独创建且分散的,而真正的`DOM`节点都是有层级关系的,那如何来保证`AST`节点的层级关系与真正的`DOM`节点相同呢?
647651

648652
关于这个问题,`Vue`也注意到了。`Vue``HTML`解析器的开头定义了一个栈`stack`,这个栈的作用就是用来维护`AST`节点层级的,那么它是怎么维护的呢?通过前文我们知道,`HTML`解析器在从前向后解析模板字符串时,每当遇到开始标签时就会调用`start`钩子函数,那么在`start`钩子函数内部我们可以将解析得到的开始标签推入栈中,而每当遇到结束标签时就会调用`end`钩子函数,那么我们也可以在`end`钩子函数内部将解析得到的结束标签所对应的开始标签从栈中弹出。请看如下例子:
649653

@@ -664,7 +668,7 @@ while (
664668
<div><p><span></p></div>
665669
```
666670

667-
按照上面的流程解析这个模板字符串时,当解析到结束标签`</p>`时,此时栈顶的标签应该是`p`才对,而现在是`span`,那么就说明`span`标签没有被正确闭合,此时控制台就会抛出警告:‘tag has no matching end tag.’相信这个警告你一定不会陌生。这就是栈的第二个用途: 检测模板字符串中是否有未正确闭合的标签。
671+
按照上面的流程解析这个模板字符串时,当解析到结束标签`</p>`时,此时栈顶的标签应该是`p`才对,而现在是`span`,那么就说明`span`标签没有被正确闭合,此时控制台就会抛出警告:‘tag has no matching end tag.’相信这个警告你一定不会陌生。这就是栈的第二个用途: 检测模板字符串中是否有未正确闭合的标签。
668672

669673
OK,有了这个栈的概念之后,我们再回看上一章`HTML`解析器解析不同内容的代码。
670674

@@ -701,28 +705,28 @@ function parseHTML(html, options) {
701705
if (textEnd === 0) {
702706
// 解析是否是注释
703707
if (comment.test(html)) {
704-
708+
705709
}
706710
// 解析是否是条件注释
707711
if (conditionalComment.test(html)) {
708-
712+
709713
}
710714
// 解析是否是DOCTYPE
711715
const doctypeMatch = html.match(doctype)
712716
if (doctypeMatch) {
713-
717+
714718
}
715719
// 解析是否是结束标签
716720
const endTagMatch = html.match(endTag)
717721
if (endTagMatch) {
718-
722+
719723
}
720724
// 匹配是否是开始标签
721725
const startTagMatch = parseStartTag()
722726
if (startTagMatch) {
723-
727+
724728
}
725-
}
729+
}
726730
// 如果html字符串不是以'<'开头,则解析文本类型
727731
let text, rest, next
728732
if (textEnd >= 0) {
@@ -755,15 +759,15 @@ function parseHTML(html, options) {
755759
parseEndTag();
756760
//parse 开始标签
757761
function parseStartTag() {
758-
762+
759763
}
760764
//处理 parseStartTag 的结果
761765
function handleStartTag(match) {
762-
766+
763767
}
764768
//parse 结束标签
765769
function parseEndTag(tagName, start, end) {
766-
770+
767771
}
768772
}
769773
```
@@ -813,7 +817,7 @@ if (html === last) {
813817
while (html) {
814818
// 确保即将 parse 的内容不是在纯文本标签里 (script,style,textarea)
815819
if (!lastTag || !isPlainTextElement(lastTag)) {
816-
820+
817821
} else {
818822
// parse 的内容是在纯文本标签里 (script,style,textarea)
819823
}
@@ -933,7 +937,7 @@ if (pos >= 0) {
933937
// Remove the open elements from the stack
934938
stack.length = pos;
935939
lastTag = pos && stack[pos - 1].tag;
936-
}
940+
}
937941
```
938942

939943
最后把`pos`位置以后的元素都从`stack`栈中弹出,以及把` lastTag`更新为栈顶元素:
@@ -956,10 +960,10 @@ lastTag = pos && stack[pos - 1].tag;
956960

957961
```javascript
958962
if (lowerCasedTagName === 'br') {
959-
if (options.start) {
963+
if (options.start) {
960964
options.start(tagName, [], true, start, end) // 创建<br>AST节点
961965
}
962-
}
966+
}
963967
// 补全p标签并创建AST节点
964968
if (lowerCasedTagName === 'p') {
965969
if (options.start) {

docs/complie/codegen.md

+8-4
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
---
2+
title: 代码生成阶段
3+
---
4+
15
## 1. 前言
26

37
经过前几篇文章,我们把用户所写的模板字符串先经过解析阶段解析生成对应的抽象语法树`AST`,接着再经过优化阶段将`AST`中的静态节点及静态根节点都打上标记,现在终于到了模板编译三大阶段的最后一个阶段了——代码生成阶段。所谓代码生成阶段,到底是要生成什么代码?答:要生成`render`函数字符串。
@@ -38,7 +42,7 @@ ast = {
3842
'type': 1,
3943
'tag': 'p',
4044
'plain': false,
41-
'static':false,
45+
'static':false,
4246
'children': [
4347
{
4448
'type': 2,
@@ -95,7 +99,7 @@ ast = {
9599

96100
```javascript
97101
res.render = createFunction(compiled.render, fnGenErrors)
98-
102+
99103
function createFunction (code, errors) {
100104
try {
101105
return new Function(code)
@@ -197,7 +201,7 @@ children ? `,${children}` : '' // children
197201
let data = '{'
198202
const dirs = genDirectives(el, state)
199203
if (dirs) data += dirs + ','
200-
204+
201205
// key
202206
if (el.key) {
203207
data += `key:${el.key},`
@@ -213,7 +217,7 @@ children ? `,${children}` : '' // children
213217
if (el.pre) {
214218
data += `pre:true,`
215219
}
216-
// 篇幅所限,省略其他情况的判断
220+
// 篇幅所限,省略其他情况的判断
217221
data = data.replace(/,$/, '') + '}'
218222
return data
219223
}

docs/complie/index.md

+4
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
---
2+
title: 模板编译篇综述
3+
---
4+
15
## 1. 前言
26

37
在前几篇文章中,我们介绍了`Vue`中的虚拟`DOM`以及虚拟`DOM``patch`(DOM-Diff)过程,而虚拟`DOM`存在的必要条件是得先有`VNode`,那么`VNode`又是从哪儿来的呢?这就是接下来几篇文章要说的模板编译。你可以这么理解:把用户写的模板进行编译,就会产生`VNode`

docs/complie/optimize.md

+5-1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
---
2+
title: 优化阶段
3+
---
4+
15
## 1. 前言
26

37
在前几篇文章中,我们介绍了模板编译流程三大阶段中的第一阶段模板解析阶段,在这一阶段主要做的工作是用解析器将用户所写的模板字符串解析成`AST`抽象语法树,理论上来讲,有了`AST`就可直接进入第三阶段生成`render`函数了。其实不然,`Vue`还是很看重性能的,只要有一点可以优化的地方就要将其进行优化。在之前介绍虚拟`DOM`的时候我们说过,有一种节点一旦首次渲染上了之后不管状态再怎么变化它都不会变了,这种节点叫做静态节点,如下:
@@ -129,7 +133,7 @@ if (node.type === 3) { // 不包含变量的纯文本节点
129133
如果`type`值为1,说明该节点是元素节点,那就需要进一步判断。
130134

131135
```javascript
132-
node.pre ||
136+
node.pre ||
133137
(
134138
!node.hasBindings && // no dynamic bindings
135139
!node.if && !node.for && // not v-if or v-for or v-else

docs/complie/parse.md

+4
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
---
2+
title: 模板解析阶段(整体运行流程)
3+
---
4+
15
## 1. 整体流程
26

37
上篇文章中我们说了,在模板解析阶段主要做的工作是把用户在`<template></template>`标签内写的模板使用正则等方式解析成抽象语法树(`AST`)。而这一阶段在源码中对应解析器(`parser`)模块。

docs/complie/summary.md

+7-3
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
---
2+
title: 模板编译篇总结
3+
---
4+
15
## 1. 前言
26

37
到现在,模板编译的三大阶段就已经全部介绍完毕了,接下来本篇文章,就以宏观角度回顾并梳理一下模板编译整个流程是怎样的。
@@ -20,7 +24,7 @@ Vue.prototype.$mount = function (el){
2024
// 获取模板,先尝试获取内部模板,如果获取不到则获取外部模板
2125
let template = options.template
2226
if (template) {
23-
27+
2428
} else {
2529
template = getOuterHTML(el)
2630
}
@@ -89,7 +93,7 @@ export const createCompiler = createCompilerCreator(function baseCompile (
8993
```javascript
9094
export function createCompilerCreator (baseCompile) {
9195
return function createCompiler (baseOptions) {
92-
96+
9397
}
9498
}
9599
```
@@ -100,7 +104,7 @@ export function createCompilerCreator (baseCompile) {
100104
function createCompiler (baseOptions) {
101105
function compile (){
102106

103-
}
107+
}
104108
return {
105109
compile,
106110
compileToFunctions: createCompileToFunctionFn(compile)

0 commit comments

Comments
 (0)