Vue-好像很神秘的「h」

還是自己寫的筆記比較好懂。

簡述

簡單來說他只是另一種建立「Component」的方式,平常我們都是用 SFC 來建立,像這樣:

1
2
3
4
5
6
7
8
9
10
11
12
13
<template>
<div class="navbar">
<div class="container">
<div>
<h1>The dojo</h1>
</div>
<div class="links">
<router-link :to="{ name: 'Home' }">Home</router-link>
<router-link :to="{ name: 'Create' }">Create</router-link>
</div>
</div>
</div>
</template>

h 其實只是另一種建立 Component 的方式,他是透過「Function」來建立,寫起來會像這樣的感覺:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// @/components/VNode.js
import { h } from 'vue'

export default function VNode() {
return {
render() {
return h(`h${this.level}`, { id: 'heading' }, this.$slots.default())
},
props: {
level: {
type: Number,
required: true
}
}
}
}

接著在把它 Register 到某個元件上就能用了,像這樣:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<template>
<div>My VNode</div>
<heading :level="1">Heading 1</heading>
<heading :level="2">Heading 2</heading>
<heading :level="3">Heading 3</heading>
<heading :level="4">Heading 4</heading>
<heading :level="5">Heading 5</heading>
</template>

<script>
import VNode from './components/VNode'

export default {
components: {
heading: VNode() // 因為是函式所以要記得 invoke
}
}
</script>

附註:這樣看很抽象的話到可以看我寫的範例

這邊只是透過 level 來決定要渲染出 <h1> 還是 <h2> 等等?就這麼單純!

不過你可能會想說「好好的 SFC 不寫,寫成這樣是在哈囉?」

讓我們來看看寫成 SFC 的話會長什麼樣子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
<!-- @/components/VNode2.js -->
<template>
<h1 v-if="level === 1">
<slot></slot>
</h1>
<h2 v-else-if="level === 2">
<slot></slot>
</h2>
<h3 v-else-if="level === 3">
<slot></slot>
</h3>
<h4 v-else-if="level === 4">
<slot></slot>
</h4>
<h5 v-else-if="level === 5">
<slot></slot>
</h5>
<h6 v-else-if="level === 6">
<slot></slot>
</h6>
</template>

<script>
export default {
props: {
level: {
type: Number,
required: true
}
}
}
</script>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<template>
<p>My VNode</p>
<VNode :level="1">Heading1</VNode>
<VNode :level="2">Heading2</VNode>
<VNode :level="3">Heading3</VNode>
<VNode :level="4">Heading4</VNode>
<VNode :level="5">Heading5</VNode>
</template>

<script>
import VNode from './components/VNode2'

export default {
components: {
VNode
}
}
</script>

不懂的話一樣到這邊看範例

這樣你應該明白差別在哪了吧?一個是「可讀性」比較好,但寫邏輯很麻煩,另一個是可讀性很爛,但方便「處理邏輯」的部分。

所以在某些情況下 render function 可能會是一個更好的選擇。

Vue-Router Vue-監聽特定的值(watch)
Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×