Vue(服務端渲染)


 

一、前言                                                                    

                                                1、服務端渲染圖解

                                                2、簡介服務端渲染

                                                3、vue-cli腳手架項目創建,實現客戶端渲染和服務端渲染

                                                4、演示demo地址:https://github.com/4561231/ssr-vue

 

二、主要內容                                                             

1、服務端渲染圖解參照另一篇:服務端渲染和客戶端渲染

 

2、簡介服務端渲染

Vue.js是構建客戶端應用程序的框架,默認情況下,可以在瀏覽器中輸出vue組件,進行生成Dom和操作DOM, 然而,也可以將同一個組件渲染成為服務端的字符串,將他們直接發送到瀏覽器,最后將這些靜態標記“激活”為客戶端上完全可以交互的應用程序。也就是你先在前端寫好組件頁面,然后交到服務端,服務端需要通過他自家的某個程序插件,然后將客戶端的組件生成對應的html字符串,最后發送給瀏覽器。然后瀏覽器響應出來頁面。

 

3、 新建項目,安裝依賴路,創建服務端代碼

  (1)server.js

const Vue = require('vue')
const express = require('express')();

const renderer = require('vue-server-renderer').createRenderer();

//創建vue實例
const app = new Vue({
    template:'<div>hello vue</div>'
})

//服務器渲染的核心就在於:
//通過vue-server-renderer插件的renderToString()方法,將vue實例轉化為字符串插入到html中
express.get('/',(req,res)=>{
    renderer.renderToString(app, (err,html)=>{
        if(err){
            return res.state(500).end('運行錯誤')
        }
          //返回給瀏覽器一串html字符串
        res.send(`<!DOCTYPE html>
        <html lang="en">
        <head>
            <meta charset="UTF-8">
            <title>服務端渲染</title>
        </head>
        <body>
            ${html}
        </body>
        </html>`)
    })
})

express.listen(8888, ()=>{
    console.log('服務器已經啟動')
})

 

 

  (2)具體實現原理

  (3)測試,發現響應回來的文件里面有內容,這樣也說明了服務端渲染是對SEO引擎比較好的

 

   (4)小結:我們使用服務端渲染是為了彌補單頁面應用SEO能力不足的問題,實際上我們第一次在瀏覽器地址欄輸入地址的時候,並且得到返回頁面之后,所有的操作仍然是單頁面應用在控制的,我們所做的服務端渲染,只是在平時返回單頁面應用hml上增加了對應路由的頁面信息,讓爬蟲好爬取到。

所以項目可以分為客戶端渲染和服務端渲染。

 

4、用vue-cli項目實現服務端渲染

  (1)npm創建項目

  (2)npm run build的時候打包走的是webpack.prod.config.js這個文件,現在我們新建一個webpack.server.config.js這個文件,在服務器打包的時候走這個文件

  package.json里面加入如下代碼

"server":"webpack --config build/webpack.server.conf.js"

       webapck.server.config.js添加如下代碼

//引入webpack的主要配置
const webpack = require('webpack')
const merge = require('webpack-merge')

//引入webpack.base.config這個文件是依賴這個基礎文件的
const base = require('./webpack.base.config')

module.exports=merge(base, {
    target:'node',//這里要寫node 目的是讓后端支持require語法
    entry:"./src/entry-server.js",//當你服務端在打包的時候,就會走這個入口
    output:{
        filename:'bundle.server.js',//打包后生成的文件
        libraryTarget:'commonjs2'
    },
    plugins:[]
})

  (2)由於以前生成vue實例的方式是單例的,現在我們需要在每次請求的時候生成一個vue組件

  在mian.js中修改


/*
eslint-disable no-new */ //El:’#app相當於document.getElementbyId(‘#app’ 但是在node.js中識別不了這種語法,所以我們不能這樣寫 /*new Vue({ el: '#app', router, components: { App }, template: '<App/>' })*/ import {createRouter} from './router' export function createApp(){
const router = createRouter(); const app
= new Vue({ router, components:{App}, template:'<App/>' })
return {app}; }

  同理最好將路由也寫成構造函數形式

export default createrRouter(){
  return new Router({
    mode:'history',
    routes:[
    {
      path:'/',
      name:'Home',
      component:Home
    },
    {
      path:'/about',
      name:'About',
      component:About
    },

    {
      path:'/test',
      name:'Test',
      component:Test
    }

    ]
  })

  (3)npm run server打包生成文件,並在服務端引入客戶端生成的打包文件

      打包生成文件

            

  在服務端引入打包生成的文件

//需要在服務端配置打包生成的客戶端文件
const createApp = require('./dist/bundle.server.js')['default']

   (4)服務端拿到客戶端打包生成的文件,進行處理

const Vue = require('vue')
const express = require('express')();
//需要在服務端配置打包生成的客戶端文件
const createApp = require('./dist/bundle.server.js')['default']
const renderer = require('vue-server-renderer').createRenderer();
//服務器渲染的核心就在於:
//通過vue-server-renderer插件的renderToString()方法,將vue實例轉化為字符串插入到html中
express.get('*',(req,res)=>{
    const context = {url:req.url};
    createApp(context).then(app=>{//這個app就是剛剛打包之后的app
          renderer.renderToString(app, (err,html)=>{
        if(err){
            return res.state(500).end('運行錯誤')
        }
          //返回給瀏覽器一串html字符串
        res.send(`<!DOCTYPE html>
        <html lang="en">
        <head>
            <meta charset="UTF-8">
            <title>服務端渲染</title>
        </head>
        <body>
            ${html}
        </body>
        </html>`)
    })
    })//取到entry.js里面的
})

express.listen(8888, ()=>{
    console.log('服務器已經啟動')
})

 

   (5)測試看到一開始請求的時候就會出現內容,可以看到服務器返回的html文件中,已經有對應頁面的SEO信息了。

 

 

 

  

 

          但是,還沒有成功,因為現在反回過來的只是一個頁面對應信息,如果你現在切換路由又會對服務器發送一次請求,單頁面應用還沒成功。但是vue的特點就是利用單頁面,

 

接下來需要配置客戶端渲染

  (1)在package.json中配

 "client": "webpack --config build/webpack.client.conf.js"

  (2)新建webpack.client.conf.js

const webpack = require('webpack')
const path = require('path')

function resolve(dir){
  return path.join(__dirname,'..',dir)
}

module.exports={
  entry:"./src/entry-client.js",//打包時走這個文件
  output:{
    path:path.resolve(__dirname,'../dist'),
    publicPath:'/dist/',
    filename:'bundle.client.js'
  },

  plugins:[],

  resolve:{
    extensions:['.js','.vue','.json'],
    alias:{
      'vue$':'vue/dist/vue.esm.js',
      '@':resolve('src'),
    }
  },
  module: {
    rules: [
      {
        test: /\.vue$/,
        loader: 'vue-loader',
        options: {
          compilerOptions:{
            preserveWhitespace:false
          }
        }

      },
      {
        test: /\.js$/,
        loader: 'babel-loader',
        include: [resolve('src'), resolve('test'), resolve('node_modules/webpack-dev-server/client')]
      }
    ]
  }
}

  (3)entry-client.js

//客戶端也要創建,因為客戶端渲染和服務端渲染是兩個不同的vue實例
import{createApp} from './main'

const {app} =createApp();
const router =app.$router;

//這里可以拿到app了,
window.onload=function(){
    app.$mount('#app')//在window加載完成之后
}

  (4)npm run client打包生成文件

  (5)同樣需要在服務器中添加打包的客戶端文件

//客戶端渲染文件
const exp = require('express');
///將靜態文件目錄設置為:項目根目錄+/dist
express.use('/',exp.static(__dirname+'/dist'));
//客戶端打包的文件
const clientBundleFileUrl = '/bundle.client.js'
//在下面的模板中用script的方式引入
<script src="${clientBundleFileUrl}"></script>

  (6)啟動服務器,測試

4、總結:

            (1)要做ssr服務端渲染首先需要一個Sever entry他的作用是渲染SEO的信息

            (2)如果你僅僅只有這四步操作,並沒有實現單頁面應用,而是每次點擊的時候都會對服務端發起請求

 

       

 

   (3)要實現單頁面應用,需要做客戶端打包,然后將客戶端打包的文件混入到服務端

  (4)單頁面應用,只有第一次加載的時候才會發送請求,點擊a標簽的時候加載的是組件,

 

 5、

 

 

三、總結                                                                    

https://ssr.vuejs.org/zh/guide/structure.html#介紹構建步驟

https://segmentfault.com/a/1190000015964813


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM