|
| 1 | +# Head 태그 관리 |
| 2 | + |
| 3 | +에셋 인젝션과 마찬가지로 Head 관리도 동일한 아이디어를 사용합니다. 즉 컴포넌트의 라이프사이클에서 렌더링 `context`에 데이터를 동적으로 추가한 다음 `template`에서 해당 데이터를 보간할 수 있습니다. |
| 4 | + |
| 5 | +> 2.3.2 버전 이후에서 컴포넌트의 SSR 컨텍스트에 `this.$ssrContext`로 직접 액세스할 수 있습니다. 이전 버전에서는 `createApp()`에 SSR 컨텍스트를 전달하고 이를 루트 인스턴스의 `$options`에 노출시켜 수동으로 SSR 컨텍스트를 주입해야합니다. 그러면 자식 컴포넌트가 `this.$root.$options.ssrContext`를 통해 액세스할 수 있습니다. |
| 6 | +
|
| 7 | +타이틀 관리를 위해 간단한 mixin을 작성합니다. |
| 8 | + |
| 9 | +```js |
| 10 | +// title-mixin.js |
| 11 | +function getTitle (vm) { |
| 12 | + // components can simply provide a `title` option |
| 13 | + // which can be either a string or a function |
| 14 | + const { title } = vm.$options |
| 15 | + if (title) { |
| 16 | + return typeof title === 'function' |
| 17 | + ? title.call(vm) |
| 18 | + : title |
| 19 | + } |
| 20 | +} |
| 21 | +const serverTitleMixin = { |
| 22 | + created () { |
| 23 | + const title = getTitle(this) |
| 24 | + if (title) { |
| 25 | + this.$ssrContext.title = title |
| 26 | + } |
| 27 | + } |
| 28 | +} |
| 29 | +const clientTitleMixin = { |
| 30 | + mounted () { |
| 31 | + const title = getTitle(this) |
| 32 | + if (title) { |
| 33 | + document.title = title |
| 34 | + } |
| 35 | + } |
| 36 | +} |
| 37 | +// VUE_ENV can be injected with webpack.DefinePlugin |
| 38 | +export default process.env.VUE_ENV === 'server' |
| 39 | + ? serverTitleMixin |
| 40 | + : clientTitleMixin |
| 41 | +``` |
| 42 | + |
| 43 | +이제 라우트 컴포넌트를 사용하여 document의 title을 제어할 수 있습니다. |
| 44 | + |
| 45 | +```js |
| 46 | +// Item.vue |
| 47 | +export default { |
| 48 | + mixins: [titleMixin], |
| 49 | + title () { |
| 50 | + return this.item.title |
| 51 | + } |
| 52 | + asyncData ({ store, route }) { |
| 53 | + return store.dispatch('fetchItem', route.params.id) |
| 54 | + }, |
| 55 | + computed: { |
| 56 | + item () { |
| 57 | + return this.$store.state.items[this.$route.params.id] |
| 58 | + } |
| 59 | + } |
| 60 | +} |
| 61 | +``` |
| 62 | + |
| 63 | +번들 렌더러에 전달된 `template` 내부 |
| 64 | + |
| 65 | +```html |
| 66 | + |
| 67 | + |
| 68 | + <title data-segment-id="430996">{{ title }}</title> |
| 69 | + |
| 70 | + |
| 71 | + ... |
| 72 | + |
| 73 | + |
| 74 | +``` |
| 75 | + |
| 76 | +**참고** |
| 77 | + |
| 78 | +- 두개의 mustache(HTML 이스케이프된 보간)를 사용해 XSS 공격을 피해야 합니다. |
| 79 | +- 렌더링하는 동안 컴포넌트에 title을 설정하지 않은 경우 `context` 개체를 만들 때 기본 title을 제공해야합니다. |
| 80 | + |
| 81 | +--- |
| 82 | + |
| 83 | +동일한 방법을 사용하면 이 mixin을 일반 Head 관리 유틸리티로 만들 수 있습니다. |
0 commit comments