@@ -1146,7 +1146,7 @@ obj.foo = 10 // 修改可以触发执行
1146
1146
1147
1147
## 自动脱 ref
1148
1148
1149
- 在 Vue.js 中,如下面代码所示 :
1149
+ 在 Vue.js 中,有下面代码 :
1150
1150
1151
1151
``` vue
1152
1152
<template>{{ msg }}</template>
@@ -1161,11 +1161,13 @@ export default {
1161
1161
</script>
1162
1162
```
1163
1163
1164
- 可以看到,我们不需要在模板中使用 ` {{ msg.value }} ` 来获取属性值,而是直接使用 ` {{ msg }} ` ,这是怎么实现的呢?
1164
+ 可以看到,我们不需要在模板中使用 ` {{ msg.value }} ` 来获取属性值,而是直接使用了 ` {{ msg }} ` ,我们不禁好奇,这是怎么实现的?
1165
1165
1166
1166
---
1167
1167
1168
- 我们知道,在 ` setup() ` 函数中会返回所有的响应式数据,那么是不是可以对返回值做一个代理,当访问 ` ref ` 数据时自动脱 ref 呢?
1168
+ 我们知道,在 ` setup() ` 函数中会统一返回所有的响应式数据,那么是不是可以对返回的数据做一个代理,当访问 ` ref ` 数据时自动脱 ref 呢?
1169
+
1170
+ > ** 自动脱 ref** : 比如,在模板中访问 ` {{ msg }} ` (ref),通过代理拦截,判断如果是一个 ` ref ` ,那么就访问 ` msg.value `
1169
1171
1170
1172
``` js
1171
1173
< script>
@@ -1364,11 +1366,14 @@ const NodeTypes = {
1364
1366
1365
1367
---
1366
1368
1367
- ## 模板解析器 parser
1369
+ ## 模板解析 parse
1368
1370
1369
1371
模板是如何被解析成 AST 的呢?
1370
1372
1371
1373
``` js
1374
+ /**
1375
+ * @params {String} str 模板字符串
1376
+ */
1372
1377
function parse (str ) {
1373
1378
/* ... */
1374
1379
}
@@ -1834,7 +1839,8 @@ function render(_ctx) {
1834
1839
我们看到,代码字符串中有 ` h ` 函数,` h ` 函数实际上就是对 ` createVNode ` 的封装,它们都是用于创建 ` VNode ` 的。
1835
1840
1836
1841
``` js
1837
- // 源码位置: packages/runtime-core/src/h.ts
1842
+ // packages/runtime-core/src/h.ts
1843
+
1838
1844
function h (tag , props , children ) {
1839
1845
// 我们这里就简单的返回一个对象,实际源码中会复杂很多
1840
1846
return {
@@ -1848,6 +1854,8 @@ function h(tag, props, children) {
1848
1854
` _toDisplayString ` 函数是 ` toDisplayString ` 的别名,它用于将插值表达式转换为字符串:
1849
1855
1850
1856
``` js
1857
+ // packages/shared/src/toDisplayString.ts
1858
+
1851
1859
const toDisplayString = (val ) => {
1852
1860
return String (val)
1853
1861
}
@@ -2168,6 +2176,24 @@ function compileToFunction(template) {
2168
2176
2169
2177
---
2170
2178
2179
+ ## 关于编译优化
2180
+
2181
+ 我这里其实没做任何的优化,只是把主体逻辑走通了,让代码可以跑起来,而且还有很多功能都没去实现,比如指令的处理,组件的支持等等。
2182
+
2183
+ 实际上在编译阶段,Vue3 内部是做了很多优化处理的,比如:
2184
+
2185
+ - 动态节点标记 patchFlag,为后续的 diff 做准备
2186
+ - 静态提升
2187
+ - 事件缓存
2188
+ - ...
2189
+
2190
+
2191
+ 关于编译优化,可以看看 Vue3 提供的一个模板解析工具大致了解下。
2192
+
2193
+ [ Vue3 Template Explorer] ( https://template-explorer.vuejs.org/ )
2194
+
2195
+ ---
2196
+
2171
2197
## 挂载&更新
2172
2198
2173
2199
前面我们实现了 ** 响应式系统** 和 ** 编译** (丐中丐版),已经有能力将模板编译成渲染函数了,现在我们将它们整合起来,同时为了能将代码跑起来,我们还需要稍微简单实现下 ** 挂载和更新** (这里不涉及 patch)。
@@ -2438,24 +2464,6 @@ createApp({
2438
2464
2439
2465
</div >
2440
2466
2441
- ---
2442
-
2443
- ## 关于编译优化
2444
-
2445
- 我这里其实没做任何的优化,只是把主体逻辑走通了,让代码可以跑起来,而且还有很多功能都没去实现,比如指令的处理,组件的支持等等。
2446
-
2447
- 实际上在编译阶段,Vue3 内部是做了很多优化处理的,比如:
2448
-
2449
- - 动态节点标记 patchFlag,为后续的 diff 做准备
2450
- - 静态提升
2451
- - 事件缓存
2452
- - ...
2453
-
2454
-
2455
- 关于编译优化,可以看看 Vue3 提供的一个模板解析工具大致了解下。
2456
-
2457
- [ Vue3 Template Explorer] ( https://template-explorer.vuejs.org/ )
2458
-
2459
2467
---
2460
2468
layout: image
2461
2469
image: /mikoto-misaka.jpg
0 commit comments