預(yù)渲染為SEO提供了另一種可能,簡單的來說,預(yù)渲染就是當(dāng)vue-cli構(gòu)建的項(xiàng)目進(jìn)行npm run build 的時候,會按照路由的層級進(jìn)行動態(tài)渲染出對應(yīng)的html文件。
// 1、安裝prerender-spa-plugin
npm install prerender-spa-plugin --save-dev
// 2、安裝vue-meta-info
npm install vue-meta-info --save-dev
一、prerender-spa-plugin 在webpack中配置
v-cli2.0 webpack-config配置
// webpack.conf.js
var path = require('path')
var PrerenderSpaPlugin = require('prerender-spa-plugin')
module.exports = {
// ...
plugins: [
new PrerenderSpaPlugin(
// 編譯后的html需要存放的路徑
path.join(__dirname, '../dist'),
// 列出哪些路由需要預(yù)渲染
[ '/', '/about', '/contact' ]
)
]
}
v-cli3.0 vue-config配置
const PrerenderSPAPlugin = require('prerender-spa-plugin')
const Renderer = PrerenderSPAPlugin.PuppeteerRenderer
const path = require('path')
configureWebpack: () => {
if (process.env.NODE_ENV !== 'production') return
return {
plugins: [
new PrerenderSPAPlugin({
// 生成文件的路徑,也可以與webpakc打包的一致。
// 下面這句話非常重要!??!
// 這個目錄只能有一級,如果目錄層次大于一級,在生成的時候不會有任何錯誤提示,在預(yù)渲染的時候只會卡著不動。
staticDir: path.join(__dirname, 'dist'),
// 對應(yīng)自己的路由文件,比如a有參數(shù),就需要寫成 /a/param1。
routes: [
'/',
'/index',
'/technology',
'/product',
'/news',
'/newsdetail',
'/about',
],
// 這個很重要,如果沒有配置這段,也不會進(jìn)行預(yù)編譯
renderer: new Renderer({
inject: {
foo: 'bar',
},
headless: false,
// 在 main.js 中 document.dispatchEvent(new Event('render-event')),兩者的事件名稱要對應(yīng)上。
renderAfterDocumentEvent: 'render-event',
}),
}),
],
}
},
二、 vue-meta-info 在組件中的配置
全局引入 vue-meta-info
import Vue from 'vue'
import MetaInfo from 'vue-meta-info'
Vue.use(MetaInfo)
組件內(nèi)靜態(tài)使用 metaInfo
<template>
...
</template>
<script>
export default {
metaInfo: {
title: 'My Example App', // set a title
meta: [{ // set meta
name: 'keyWords',
content: 'My Example App'
},{ // set meta
name: 'Description',
content: 'My Example App'
}]
link: [{ // set link
rel: 'asstes',
href: 'https://assets-cdn.github.com/'
}]
}
}
</script>
// 此處的title是指
<title>我的主頁</title>
// 此處的meta 是指
<meta name="Keywords" Content="">
<meta name="Description" Content=">
如果你的 title 或者 meta 是異步加載的,那么你可能需要這樣使用
<template>
...
</template>
<script>
export default {
name: 'async',
metaInfo () {
return {
title: this.pageName
}
},
data () {
return {
pageName: 'loading'
}
},
mounted () {
setTimeout(() => {
this.pageName = 'async'
}, 2000)
}
}
</script>
寫到這里,大家應(yīng)該都明白了我所說的 SEO 的另一種思路是什么了,preRender + metaInfo
可以才一定層次上去解決 SEO 問題,這種方式優(yōu)點(diǎn)就是代碼侵入性最低,開發(fā)成本最少。但是也是有弊端的:
1.不能很好地處理用戶獨(dú)特性路由: 比如有個路由是 /my-profile, 預(yù)渲染可能不會很好用, 因?yàn)檫@個內(nèi)容頁是根據(jù)用戶信息變化的,所以頁面內(nèi)容也不是唯一確定的. 你可能會使用類似于這樣的路由路徑 /users/:username/profile,但是這樣也是不合適的.
2.經(jīng)常變動的文件
3.需要預(yù)渲染成千上萬的路由文件: 這個可能會導(dǎo)致你編譯時間.....額,可能你會編譯很長時間