Vue.js SSR Head 管理

2021-01-07 15:55 更新

類似于資源注入,Head 管理遵循相同的理念:我們可以在組件的生命周期中,將數(shù)據(jù)動(dòng)態(tài)地追加到渲染上下文 (render context),然后在模板中的占位符替換為這些數(shù)據(jù)。

在 2.3.2+ 的版本,你可以通過(guò) this.$ssrContext 來(lái)直接訪問(wèn)組件中的服務(wù)器端渲染上下文(SSR context)。在舊版本中,你必須通過(guò)將其傳遞給 createApp() 并將其暴露于根實(shí)例的 $options 上,才能手動(dòng)注入服務(wù)器端渲染上下文(SSR context) - 然后子組件可以通過(guò) this.$root.$options.ssrContext 來(lái)訪問(wèn)它。

我們可以編寫(xiě)一個(gè)簡(jiǎn)單的 mixin 來(lái)完成標(biāo)題管理:

// title-mixin.js


function getTitle (vm) {
  // 組件可以提供一個(gè) `title` 選項(xiàng)
  // 此選項(xiàng)可以是一個(gè)字符串或函數(shù)
  const { title } = vm.$options
  if (title) {
    return typeof title === 'function'
      ? title.call(vm)
      : title
  }
}


const serverTitleMixin = {
  created () {
    const title = getTitle(this)
    if (title) {
      this.$ssrContext.title = title
    }
  }
}


const clientTitleMixin = {
  mounted () {
    const title = getTitle(this)
    if (title) {
      document.title = title
    }
  }
}


// 可以通過(guò) `webpack.DefinePlugin` 注入 `VUE_ENV`
export default process.env.VUE_ENV === 'server'
  ? serverTitleMixin
  : clientTitleMixin

現(xiàn)在,路由組件可以利用以上 mixin,來(lái)控制文檔標(biāo)題 (document title):

// Item.vue
export default {
  mixins: [titleMixin],
  title () {
    return this.item.title
  },


  asyncData ({ store, route }) {
    return store.dispatch('fetchItem', route.params.id)
  },


  computed: {
    item () {
      return this.$store.state.items[this.$route.params.id]
    }
  }
}

然后模板中的內(nèi)容將會(huì)傳遞給 bundle renderer:

<html>
  <head>
    <title>{{ title }}</title>
  </head>
  <body>
    ...
  </body>
</html>

注意:

  • 使用雙花括號(hào)(double-mustache)進(jìn)行 HTML 轉(zhuǎn)義插值(HTML-escaped interpolation),以避免 XSS 攻擊。

  • 你應(yīng)該在創(chuàng)建 context 對(duì)象時(shí)提供一個(gè)默認(rèn)標(biāo)題,以防在渲染過(guò)程中組件沒(méi)有設(shè)置標(biāo)題。

使用相同的策略,你可以輕松地將此 mixin 擴(kuò)展為通用的頭部管理工具 (generic head management utility)。

以上內(nèi)容是否對(duì)您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號(hào)
微信公眾號(hào)

編程獅公眾號(hào)