vue的渲染模式

默认情况下,Vue是客户端渲染(CSR):Vue组件是在浏览器中生成和操作DOM的。
然而, Vue也支持服务端渲染(SSR):将组件在服务端直接渲染成HTML字符串,作为服务端响应返回给浏览器,最后在浏览器端将静态的HTML“激活”为能够交互的客户端应用。

SPA就是在客户端渲染(CSR)概念下实现的一种现代Web设计模式。
SPA的优势是:

  • 局部更新:通过JavaScript驱动来实现在同一网页文档(即单个HTML文件)内动态更新内容和导航,无需整页刷新。
  • 更快的交互体验:它不需要每次都通过HTTP请求获取全新的页面,而是通过AJAX或其他数据通信手段仅请求所需的数据并局部更新页面内容。
  • SPA在初次加载时通常会从服务器获取初始的HTML、CSS和JavaScript文件,但后续视图的渲染和数据的交互主要发生在客户端。

SSR的优缺点

优点

  • 更快的首屏加载:
    • 服务端渲染的 HTML 无需等到所有的 JavaScript 都下载并执行完成之后才显示,所以你的用户将会更快地看到完整渲染的页面。
    • 数据获取过程在首次访问时在服务端完成,相比于从客户端获取,可能有更快的数据库连接。
  • 更好的SEO:由于html页面是由服务端直接返回的,所以搜索引擎爬虫可以直接看到完全渲染的页面。

缺点

  • 开发限制:浏览器中的特定代码只能在生命周期钩子中使用(如,window),一些外部库,需要特殊处理才能在服务端渲染的应用中运行

  • 环境依赖:服务端渲染的应用需要一个能让 Node.js 服务器运行的环境,不像完全静态的 SPA 那样可以部署在任意的静态文件服务器上。

      	SPA项目通常在开发环境下还是需要node环境的,通过node环境构建和部署项目,
      	但是在生产环境下通常已经打包成静态文件部署到服务器上,此时就不需要node环境了。
    
  • 更高的服务器负载:在 Node.js 中渲染一个完整的应用要比仅仅托管静态文件更加占用 CPU 资源。

SSR渲染示例

服务端准备

这里以Node为例:

  • 创建一个文件夹,cd进入
  • 执行npmi init -y
  • 在 package.json 中添加 "type": "module" 使 Node.js 以 ES modules 模式运行
  • 执行 npm install vue express
  • 创建一个 example.js 文件:
    • createSSRApp 可以创建一个SSR的vue应用实例
    • renderToString() 接收一个 Vue 应用实例作为参数,返回一个 Promise。它的.then回调函数的参数是vue应用实例template模板的html内容。

server.js

import express from 'express'
import { createSSRApp } from 'vue'
import { renderToString } from 'vue/server-renderer'

const server = express()

server.get('/', (req, res) => {
  const app = createSSRApp({
    data: () => ({ count: 1 }),
    template: `<button @click="count++">{{ count }}</button>`
  })

  renderToString(app).then((html) => {
    res.send(`
    <!DOCTYPE html>
    <html>
      <head>
        <title>Vue SSR Example</title>
      </head>
      <body>
        <div id="app">${html}</div>
      </body>
    </html>
    `)
  })
})

server.listen(3000, () => {
  console.log('ready')
})

执行 node server.js,访问 http://localhost:3000。可以看到页面中的按钮了:
在这里插入图片描述

客户端激活

虽然直接访问服务端提供的接口路径可以在浏览器渲染出html页面,但是由于Vue还没有在浏览器中加载,所以这段html是完全静态的。为了使客户端的应用可交互,vue需要执行一个激活的步骤。(如果你的逻辑是使用的纯js代码编写的,就可以直接在浏览器中实现点击数字增加的效果)。

vue的激活:app.mount('#app'),Vue 会创建一个与服务端中定义的完全相同的应用实例,然后将每个组件与它应该控制的 DOM 节点相匹配,并添加 DOM 事件监听器。

具体实现:

  • app.js

    // 通用代码,服务端和客户端共享
    import { createSSRApp } from 'vue'
    
    export const createApp = ()=>{
        return createSSRApp({
            data: () => ({ count: 1 }),
            template: `<button id="countButton" @click="count++">{{ count }}</button>`
          })
    }
    
  • client.js

    // 客户端代码
    import { createApp } from "./app.js"
    createApp().mount("#app")
    
  • server.js

    // 服务端代码
    import express from 'express'
    import { renderToString } from 'vue/server-renderer'
    import { createApp } from './app.js'
    
    const server = express()
    
    // 静态资源, 配置之后才可以通过express访问./文件夹下的资源
    server.use(express.static('./'))
    
    // 请求
    server.get('/', (req, res) => {
      const app = createApp()
      renderToString(app).then((html) => {
        res.send(`
        <!DOCTYPE html>
        <html>
          <head>
            <title>Vue SSR Example</title>
            <!-- 
                支持在浏览器中使用 import * from 'vue', 因为客户端和服务端使用的vue来源不一样所以需要单独引入
                服务端:npm包安装的vue
                客户端:cdn引入的vue
            -->
            <script type="importmap">
              {
                "imports": {
                  "vue": "https://unpkg.com/vue@3/dist/vue.esm-browser.js"
                }
              }
            </script>
            <!-- 
                通过htm引入的js理解为静态资源
            -->
            <script type="module" src="./client.js"></script>
          </head>
          <body>
            <div id="app">${html}</div>
          </body>
        </html>
        `)
      })
    })
    
    server.listen(3000, () => {
      console.log('ready')
    })
    

在这里插入图片描述

vue实现SSR的工具

手动实现SSR,需要在服务器请求处理函数中,确保返回的 HTML 包含正确的客户端资源链接和最优的资源加载提示 (如 prefetch 和 preload)。我们可能还需要在 SSR 和 SSG 模式之间切换,甚至在同一个应用中混合使用这两种模式。完整的实现很复杂,推荐使用vue生态中的SSR解决方案。

  • Nuxt :Nuxt 是一个构建于 Vue 生态系统之上的全栈框架,它为编写 Vue SSR 应用提供了很好的开发体验。同时它还支持静态站点的生成
  • Quasar:Quasar 是一个基于 Vue 的完整解决方案,它可以让你用同一套代码库构建不同目标的应用,如 SPA、SSR、PWA、移动端应用、桌面端应用及浏览器插件
  • Vite SSR:Vite 提供了内置的 Vue 服务端渲染支持,但它在设计上是偏底层的。如果你想要直接使用 Vite,可以看看 vite-plugin-ssr,一个帮你抽象掉许多复杂细节的社区插件。
Logo

openEuler 是由开放原子开源基金会孵化的全场景开源操作系统项目,面向数字基础设施四大核心场景(服务器、云计算、边缘计算、嵌入式),全面支持 ARM、x86、RISC-V、loongArch、PowerPC、SW-64 等多样性计算架构

更多推荐