无论是服务端渲染还是客户端渲染,它们都使用的同一个页面模板。

    页面中的 body 是动态渲染出来的,但是页面的 head 是写死的,也就说我们希望不同的页面可以拥有自己的 head 内容,例如页面的 title、meta 等内容,所以下面我们来了解一下如何让不同的页面来定制自己的 head 头部内容。

    官方文档这里专门描述了关于页面 Head 的处理,相对于来讲更原生一些,使用比较麻烦,有兴趣的同学可以了解一下。

    我这里主要给大家介绍一个第三方解决方案:vue-meta

    Vue Meta 是一个支持 SSR 的第三方 Vue.js 插件,可让你轻松的实现不同页面的 head 内容管理。

    使用它的方式非常简单,而只需在页面组件中使用 metaInfo 属性配置页面的 head 内容即可。

    1. <template>
    2. ...
    3. </template>
    4. <script>
    5. export default {
    6. metaInfo: {
    7. title: 'My Example App',
    8. titleTemplate: '%s - Yay!',
    9. htmlAttrs: {
    10. lang: 'en',
    11. amp: true
    12. }
    13. }
    14. }
    15. </script>

    页面渲染出来的结果:

    1. <html lang="en" amp>
    2. <head>
    3. <title>My Example App - Yay!</title>
    4. ...
    5. </head>

    安装:

    1. npm i vue-meta

    在通用入口中通过插件的方式将 vue-meta 注册到 Vue 中。

    1. import Vue from 'vue'
    2. import VueMeta from 'vue-meta'
    3. Vue.use(VueMeta)
    4. Vue.mixin({
    5. metaInfo: {
    6. titleTemplate: '%s - 拉勾教育'
    7. }
    8. })

    然后在服务端渲染入口模块中适配 vue-meta:

    1. // entry-server.js
    2. import { createApp } from './app'
    3. export default async context => {
    4. // 因为有可能会是异步路由钩子函数或组件,所以我们将返回一个 Promise,
    5. // 以便服务器能够等待所有的内容在渲染前,
    6. // 就已经准备就绪。
    7. const { app, router } = createApp()
    8. const meta = app.$meta()
    9. // 设置服务器端 router 的位置
    10. router.push(context.url)
    11. context.meta = meta
    12. // 等到 router 将可能的异步组件和钩子函数解析完
    13. await new Promise(router.onReady.bind(router))
    14. return app
    15. }

    最后在模板页面中注入 meta 信息:

    1. <head>
    2. {{{ meta.inject().title.text() }}}
    3. {{{ meta.inject().meta.text() }}}
    4. </head>

    下面就是直接在组件中使用即可:

    Home.vue

    1. {
    2. metaInfo: {
    3. title: '首页' // 首页 - 拉勾教育
    4. }
    5. }

    About.vue

    1. {
    2. metaInfo: {
    3. title: 'About' // About - 拉勾教育
    4. }
    5. }

    关于使用 vue-meta 管理页面 Head 我们就介绍这些,大家可以根据自己的需求,多查阅文档,灵活使用即可。