Skip to content
This repository was archived by the owner on Aug 8, 2022. It is now read-only.

Commit b6e8203

Browse files
authored
docs: Use destructuring to access createApp render-function.md (#354)
1 parent e5be02c commit b6e8203

File tree

1 file changed

+45
-37
lines changed

1 file changed

+45
-37
lines changed

src/guide/render-function.md

Lines changed: 45 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,11 @@ Vue 推荐在绝大多数情况下使用模板来创建你的 HTML。然而在
1919
```
2020

2121
当开始写一个只能通过 `level` prop 动态生成标题 (heading) 的组件时,我们很快就可以得出这样的结论:
22+
2223
```js
23-
const app = Vue.createApp({})
24+
const { createApp } = Vue
25+
26+
const app = createApp({})
2427

2528
app.component('anchored-heading', {
2629
template: `
@@ -51,17 +54,18 @@ app.component('anchored-heading', {
5154
}
5255
})
5356
```
57+
5458
这个模板感觉不太好。它不仅冗长,而且我们为每个级别标题重复书写了 `<slot></slot>`。当我们添加锚元素时,我们必须在每个 `v-if/v-else-if` 分支中再次重复它。
5559

5660
虽然模板在大多数组件中都非常好用,但是显然在这里它就不合适了。那么,我们来尝试使用 `render` 函数重写上面的例子:
5761

5862
```js
59-
const app = Vue.createApp({})
63+
const { createApp, h } = Vue
64+
65+
const app = createApp({})
6066

6167
app.component('anchored-heading', {
6268
render() {
63-
const { h } = Vue
64-
6569
return h(
6670
'h' + this.level, // tag name
6771
{}, // props/attributes
@@ -109,7 +113,7 @@ app.component('anchored-heading', {
109113

110114
```js
111115
render() {
112-
return Vue.h('h1', {}, this.blogTitle)
116+
return h('h1', {}, this.blogTitle)
113117
}
114118
```
115119

@@ -120,7 +124,7 @@ render() {
120124
Vue 通过建立一个**虚拟 DOM** 来追踪自己要如何改变真实 DOM。请仔细看这行代码:
121125

122126
```js
123-
return Vue.h('h1', {}, this.blogTitle)
127+
return h('h1', {}, this.blogTitle)
124128
```
125129

126130
`h()` 到底会返回什么呢?其实不是一个*实际*的 DOM 元素。它更准确的名字可能是 createNodeDescription,因为它所包含的信息会告诉 Vue 页面上需要渲染什么样的节点,包括及其子节点的描述信息。我们把这样的节点描述为“虚拟节点 (virtual node)”,也常简写它为 **VNode**。“虚拟 DOM”是我们对由 Vue 组件树建立起来的整个 VNode 树的称呼。
@@ -167,7 +171,9 @@ h(
167171
有了这些知识,我们现在可以完成我们最开始想实现的组件:
168172

169173
```js
170-
const app = Vue.createApp({})
174+
const { createApp, h } = Vue
175+
176+
const app = createApp({})
171177

172178
/** Recursively get text from children nodes */
173179
function getChildrenTextContent(children) {
@@ -190,8 +196,8 @@ app.component('anchored-heading', {
190196
.replace(/\W+/g, '-') // replace non-word characters with dash
191197
.replace(/(^-|-$)/g, '') // remove leading and trailing dashes
192198

193-
return Vue.h('h' + this.level, [
194-
Vue.h(
199+
return h('h' + this.level, [
200+
h(
195201
'a',
196202
{
197203
name: headingId,
@@ -218,8 +224,8 @@ app.component('anchored-heading', {
218224

219225
```js
220226
render() {
221-
const myParagraphVNode = Vue.h('p', 'hi')
222-
return Vue.h('div', [
227+
const myParagraphVNode = h('p', 'hi')
228+
return h('div', [
223229
// 错误 - 重复的Vnode!
224230
myParagraphVNode, myParagraphVNode
225231
])
@@ -230,9 +236,9 @@ render() {
230236

231237
```js
232238
render() {
233-
return Vue.h('div',
239+
return h('div',
234240
Array.from({ length: 20 }).map(() => {
235-
return Vue.h('p', 'hi')
241+
return h('p', 'hi')
236242
})
237243
)
238244
}
@@ -257,24 +263,24 @@ render() {
257263
props: ['items'],
258264
render() {
259265
if (this.items.length) {
260-
return Vue.h('ul', this.items.map((item) => {
261-
return Vue.h('li', item.name)
266+
return h('ul', this.items.map((item) => {
267+
return h('li', item.name)
262268
}))
263269
} else {
264-
return Vue.h('p', 'No items found.')
270+
return h('p', 'No items found.')
265271
}
266272
}
267273
```
268274

269275
### `v-model`
270276

271-
`v-model` 指令扩展为 `modelValue``onUpdate:modelValue` 在模板编译过程中,我们必须自己提供这些prop
277+
`v-model` 指令扩展为 `modelValue``onUpdate:modelValue` 在模板编译过程中,我们必须自己提供这些 prop
272278

273279
```js
274280
props: ['modelValue'],
275281
emits: ['update:modelValue'],
276282
render() {
277-
return Vue.h(SomeComponent, {
283+
return h(SomeComponent, {
278284
modelValue: this.modelValue,
279285
'onUpdate:modelValue': value => this.$emit('update:modelValue', value)
280286
})
@@ -283,25 +289,25 @@ render() {
283289

284290
### `v-on`
285291

286-
我们必须为事件处理程序提供一个正确的prop名称,例如,要处理 `click` 事件,prop名称应该是 `onClick`
292+
我们必须为事件处理程序提供一个正确的 prop 名称,例如,要处理 `click` 事件,prop 名称应该是 `onClick`
287293

288294
```js
289295
render() {
290-
return Vue.h('div', {
296+
return h('div', {
291297
onClick: $event => console.log('clicked', $event.target)
292298
})
293299
}
294300
```
295301

296302
#### 事件修饰符
297303

298-
对于 `.passive``.capture``.once` 事件修饰符,Vue提供了处理程序的对象语法
304+
对于 `.passive``.capture``.once` 事件修饰符,Vue 提供了处理程序的对象语法
299305

300306
实例:
301307

302308
```javascript
303309
render() {
304-
return Vue.h('input', {
310+
return h('input', {
305311
onClick: {
306312
handler: this.doThisInCapturingMode,
307313
capture: true
@@ -321,19 +327,19 @@ render() {
321327

322328
对于所有其它的修饰符,私有前缀都不是必须的,因为你可以在事件处理函数中使用事件方法:
323329

324-
| 修饰符 | 处理函数中的等价操作 |
325-
| ----------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------- |
326-
| `.stop` | `event.stopPropagation()` |
327-
| `.prevent` | `event.preventDefault()` |
328-
| `.self` | `if (event.target !== event.currentTarget) return` |
329-
| 按键:<br>`.enter`, `.13` | `if (event.keyCode !== 13) return` (对于别的按键修饰符来说,可将 13 改为[另一个按键码](http://keycode.info/) |
330-
| 修饰键:<br>`.ctrl`, `.alt`, `.shift`, `.meta` | `if (!event.ctrlKey) return` (将 `ctrlKey` 分别修改为 `altKey`, `shiftKey`, 或 `metaKey`) |
330+
| 修饰符 | 处理函数中的等价操作 |
331+
| ---------------------------------------------- | ------------------------------------------------------------------------------------------------------------ |
332+
| `.stop` | `event.stopPropagation()` |
333+
| `.prevent` | `event.preventDefault()` |
334+
| `.self` | `if (event.target !== event.currentTarget) return` |
335+
| 按键:<br>`.enter`, `.13` | `if (event.keyCode !== 13) return` (对于别的按键修饰符来说,可将 13 改为[另一个按键码](http://keycode.info/) |
336+
| 修饰键:<br>`.ctrl`, `.alt`, `.shift`, `.meta` | `if (!event.ctrlKey) return` (将 `ctrlKey` 分别修改为 `altKey`, `shiftKey`, 或 `metaKey`) |
331337

332338
这里是一个使用所有修饰符的例子:
333339

334340
```js
335341
render() {
336-
return Vue.h('input', {
342+
return h('input', {
337343
onKeyUp: event => {
338344
// 如果触发事件的元素不是事件绑定的元素
339345
// 则返回
@@ -358,15 +364,15 @@ render() {
358364
```js
359365
render() {
360366
// `<div><slot></slot></div>`
361-
return Vue.h('div', {}, this.$slots.default())
367+
return h('div', {}, this.$slots.default())
362368
}
363369
```
364370

365371
```js
366372
props: ['message'],
367373
render() {
368374
// `<div><slot :text="message"></slot></div>`
369-
return Vue.h('div', {}, this.$slots.default({
375+
return h('div', {}, this.$slots.default({
370376
text: this.message
371377
}))
372378
}
@@ -377,11 +383,13 @@ render() {
377383
<!-- TODO: translation -->
378384

379385
```js
386+
const { h, resolveComponent } = Vue
387+
380388
render() {
381389
// `<div><child v-slot="props"><span>{{ props.text }}</span></child></div>`
382-
return Vue.h('div', [
383-
Vue.h(
384-
Vue.resolveComponent('child'),
390+
return h('div', [
391+
h(
392+
resolveComponent('child'),
385393
{},
386394
// pass `slots` as the children object
387395
// in the form of { name: props => VNode | Array<VNode> }
@@ -398,13 +406,13 @@ render() {
398406
如果你写了很多渲染函数,可能会觉得下面这样的代码写起来很痛苦:
399407

400408
```js
401-
Vue.h(
409+
h(
402410
'anchored-heading',
403411
{
404412
level: 1
405413
},
406414
{
407-
default: () => [Vue.h('span', 'Hello'), ' world!']
415+
default: () => [h('span', 'Hello'), ' world!']
408416
}
409417
)
410418
```

0 commit comments

Comments
 (0)