Skip to content

Commit c7d6627

Browse files
inouetakuyakazupon
authored andcommitted
Japanese Translation: ja/head.md (#33)
* Translate head.md via GitLocalize * Translate head.md via GitLocalize * expose はモジュールとして公開するという意味なので公開という言葉を使うようにした * コードのコメントの翻訳が漏れていた
1 parent dd4e707 commit c7d6627

File tree

1 file changed

+100
-0
lines changed

1 file changed

+100
-0
lines changed

Diff for: ja/head.md

+100
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
# ヘッドの管理
2+
3+
アセットの挿入と同様に、ヘッドの管理も同じ考えに追従しています。つまり、コンポーネントのライフサイクルのレンダリング `context` に動的にデータを付随させ、そして `template` 内にデータを挿入できるという考えです。
4+
5+
そうするためには、ネストしたコンポーネントの内側で SSR コンテキストへアクセスできる必要があります。単純に `context``createApp()` へ渡し、これをルートインスタンスの `$options` で公開することができます。
6+
7+
```js
8+
// app.js
9+
export function createApp (ssrContext) {
10+
// ...
11+
const app = new Vue({
12+
router,
13+
store,
14+
// this.$root.$options.ssrContext というように、すべての子コンポーネントは this にアクセスできます
15+
ssrContext,
16+
render: h => h(App)
17+
})
18+
// ...
19+
}
20+
```
21+
22+
これと同様のことが `provide/inject` 経由でも可能ですが、そうすると context が `$root` 上に存在することになるため、インジェクションを解決するコストを避けたほうが良いでしょう。
23+
24+
インジェクトされた context を用いて、タイトルを管理する単純な mixin を書くことができます:
25+
26+
```js
27+
// title-mixin.js
28+
function getTitle (vm) {
29+
// コンポーネントはシンプルに `title` オプションを提供し、
30+
// これには文字列または関数を入れることができます
31+
const { title } = vm.$options
32+
if (title) {
33+
return typeof title === 'function'
34+
? title.call(vm)
35+
: title
36+
}
37+
}
38+
const serverTitleMixin = {
39+
created () {
40+
const title = getTitle(this)
41+
if (title) {
42+
this.$root.$options.ssrContext.title = title
43+
}
44+
}
45+
}
46+
const clientTitleMixin = {
47+
mounted () {
48+
const title = getTitle(this)
49+
if (title) {
50+
document.title = title
51+
}
52+
}
53+
}
54+
// VUE_ENV は webpack.DefinePlugin を使って挿入できます
55+
export default process.env.VUE_ENV === 'server'
56+
? serverTitleMixin
57+
: clientTitleMixin
58+
```
59+
60+
このようにすれば、ルートコンポーネントはドキュメントのタイトルをコントロールするために context を利用することができます。
61+
62+
```js
63+
// Item.vue
64+
export default {
65+
mixins: [titleMixin],
66+
title () {
67+
return this.item.title
68+
}
69+
asyncData ({ store, route }) {
70+
return store.dispatch('fetchItem', route.params.id)
71+
},
72+
computed: {
73+
item () {
74+
return this.$store.state.items[this.$route.params.id]
75+
}
76+
}
77+
}
78+
```
79+
80+
そしてタイトルは `template` 内でバンドルレンダラーに渡されます:
81+
82+
```html
83+
<html>
84+
<head>
85+
<title>{{ title }}</title>
86+
</head>
87+
<body>
88+
...
89+
</body>
90+
</html>
91+
```
92+
93+
**メモ:**
94+
95+
- XSS 攻撃を防ぐために double-mustache(HTML エスケープした挿入)を使うこと。
96+
- レンダリング中にタイトルをセットするコンポーネントがない場合に備えて、`context` オブジェクトを作成する際にはデフォルトのタイトルをセットするようにすべきです。
97+
98+
---
99+
100+
同様のやり方で、この mixin を包括的にヘッドを管理するユーティリティに容易に拡張できます。

0 commit comments

Comments
 (0)