zoukankan      html  css  js  c++  java
  • 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

    虽然现在走得很慢,但不会一直这么慢
  • 相关阅读:
    linux sysfs (2)
    微软——助您启动云的力量网络虚拟盛会
    Windows Azure入门教学系列 全面更新啦!
    与Advanced Telemetry创始人兼 CTO, Tom Naylor的访谈
    Windows Azure AppFabric概述
    Windows Azure Extra Small Instances Public Beta版本发布
    DataMarket 一月内容更新
    和Steve, Wade 一起学习如何使用Windows Azure Startup Tasks
    现实世界的Windows Azure:与eCraft的 Nicklas Andersson(CTO),Peter Löfgren(项目经理)以及Jörgen Westerling(CCO)的访谈
    正确使用Windows Azure 中的VM Role
  • 原文地址:https://www.cnblogs.com/xxm980617/p/10753525.html
Copyright © 2011-2022 走看看