@@ -2183,9 +2183,7 @@ function compileToFunction(template) {
2183
2183
</ul >
2184
2184
```
2185
2185
2186
- 经过编译后,其对应的渲染函数和VNode分别如下:
2187
-
2188
- <div grid =" ~ cols-2 gap-2 " >
2186
+ 经过编译后,其对应的渲染函数如下:
2189
2187
2190
2188
``` js
2191
2189
function render () {
@@ -2204,6 +2202,16 @@ function render() {
2204
2202
}
2205
2203
```
2206
2204
2205
+ ---
2206
+
2207
+ 执行渲染函数:
2208
+
2209
+ ``` js
2210
+ render ()
2211
+ ```
2212
+
2213
+ 会生成下面的 ** 虚拟DOM** :
2214
+
2207
2215
``` js
2208
2216
// VNode
2209
2217
{
@@ -2222,15 +2230,14 @@ function render() {
2222
2230
}
2223
2231
```
2224
2232
2225
- </div >
2226
-
2227
2233
---
2228
2234
2229
- 渲染函数的执行会生成虚拟 DOM,接下来我们尝试手动将虚拟 DOM 渲染到页面上 。
2235
+ 有了虚拟DOM,现在我们尝试手动将其渲染到页面中去 。
2230
2236
2231
2237
<div grid =" ~ cols-2 gap-2 " >
2232
2238
2233
2239
``` js
2240
+ // 挂载
2234
2241
function mount (vnode , container ) {
2235
2242
const el = document .createElement (vnode .tag )
2236
2243
if (vnode .props ) {
@@ -2247,7 +2254,7 @@ function mount(vnode, container) {
2247
2254
vnode .children .forEach (child => {
2248
2255
mount (child, el)
2249
2256
})
2250
- } else {
2257
+ } else { // text node
2251
2258
el .textContent = vnode .children
2252
2259
}
2253
2260
container .appendChild (el)
@@ -2266,8 +2273,19 @@ mount(vnode, document.body)
2266
2273
2267
2274
---
2268
2275
2276
+ 前文中,我们已经实现了** 挂载** ,现在我们将代码封装一下,并实现自动** 更新** 的功能。
2277
+
2269
2278
<div grid =" ~ cols-2 gap-2 " >
2270
2279
2280
+ ``` js
2281
+ // 挂载
2282
+ let _mount = mount
2283
+
2284
+ function mount (vnode , container ) {
2285
+ // ...
2286
+ }
2287
+ ```
2288
+
2271
2289
``` js
2272
2290
function createApp (options = {}) {
2273
2291
const app = {
@@ -2280,13 +2298,11 @@ function createApp(options = {}) {
2280
2298
const setupFn = options .setup || noop
2281
2299
const setupResult = setupFn () || {}
2282
2300
const data = proxyRefs (setupResult)
2283
-
2284
2301
const reload = () => {
2285
- const vnode = render (data, { h, _toDisplayString : function toString ( val ) { return val && val . toString () } } )
2302
+ const vnode = render (data)
2286
2303
container .innerHTML = ' '
2287
2304
_mount (vnode, container)
2288
2305
}
2289
- // 副作用函数
2290
2306
effect (() => {
2291
2307
reload ()
2292
2308
})
@@ -2296,35 +2312,6 @@ function createApp(options = {}) {
2296
2312
}
2297
2313
```
2298
2314
2299
- ``` js
2300
- // 挂载
2301
- function _mount (vnode , container ) {
2302
- const el = document .createElement (vnode .tag )
2303
- if (vnode .props ) {
2304
- for (let key in vnode .props ) {
2305
- if (key .startsWith (' on' )) { // 事件绑定
2306
- const eventName = key .slice (2 ).toLowerCase ()
2307
- el .addEventListener (eventName, vnode .props [key])
2308
- } else {
2309
- el .setAttribute (key, vnode .props [key])
2310
- }
2311
- }
2312
- }
2313
- if (Array .isArray (vnode .children )) {
2314
- if (vnode .children .length === 1 && typeof vnode .children [0 ] != ' object' ) {
2315
- el .textContent = vnode .children [0 ]
2316
- } else {
2317
- vnode .children .forEach (child => {
2318
- _mount (child, el)
2319
- })
2320
- }
2321
- } else { // string
2322
- el .textContent = vnode .children
2323
- }
2324
- container .appendChild (el)
2325
- }
2326
- ```
2327
-
2328
2315
</div >
2329
2316
2330
2317
---
@@ -2335,7 +2322,7 @@ function _mount(vnode, container) {
2335
2322
2336
2323
---
2337
2324
2338
- ## counter 计数器 demo
2325
+ ## Counter 计数器 demo
2339
2326
2340
2327
demo: ` 22-counter.html `
2341
2328
0 commit comments