当前位置: 首页 > 工具软件 > Express Map > 使用案例 >

js:Vue3.js+Express实现SSR服务端渲染

阎晋
2023-12-01

常用的基于vue/react的服务端渲染方案,如下:

  • 使用next.js/nuxt.js的服务端渲染方案
  • 使用node+vue-server-renderer实现vue项目的服务端渲染
  • 使用node+React renderToStaticMarkup实现react项目的服务端渲染
  • 传统网站通过模板引擎来实现ssr(比如ejs, jade, pug等)
  • 使用rendertron实现SPA项目的服务端渲染

文档:

Vue SSR 基础示例

pnpm install vue

example.js

// 此文件运行在 Node.js 服务器上
import { createSSRApp } from "vue";
// Vue 的服务端渲染 API 位于 `vue/server-renderer` 路径下
import { renderToString } from "vue/server-renderer";

const app = createSSRApp({
  data: () => ({ count: 1 }),
  template: `<button @click="count++">{{ count }}</button>`,
});

renderToString(app).then((html) => {
  console.log(html);
});

运行

$ node example.js

<button>1</button>

Vue SSR + Express 示例

项目结构

$ tree -I node_modules
.
├── app.js
├── client.js
├── index.html
├── package.json
└── server.js

package.json

{
    "type": "module",
    "dependencies": {
        "express": "^4.18.1",
        "twig": "^1.15.4",
        "vue": "^3.2.40",
        "vue-server-renderer": "^2.7.10"
    }
}

服务端 server.js

// server.js
import express from "express";
import Twig from "twig";
import { renderToString } from "vue/server-renderer";
import { createApp } from "./app.js";

const server = express();

// 设置模板引擎
server.engine("html", Twig.renderFile);
server.set("view engine", "html");
server.set("views", "./");

server.get("/", (req, res) => {
  const app = createApp();

  renderToString(app).then((html) => {
    res.render("index.html", {
      html: html,
    });
  });
});

// 托管客户端文件
server.use(express.static("."));

server.listen(3000, () => {
  console.log("server: http://localhost:3000");
});

app.js

// app.js (在服务器和客户端之间共享)
import { createSSRApp } from "vue";

export function createApp() {
  return createSSRApp({
    data() {
      return {
        count: 1,
      };
    },

    template: `<button @click="handleClick">+{{ count }}</button>`,

    methods: {
      handleClick() {
        this.count++;
      },
    },

    created() {
      // server client
      console.log("created");
    },

    mounted() {
      // client
      console.log("mounted");
    },
  });
}

客户端

// client.js
import { createApp } from "./app.js";

createApp().mount("#app");

index.html

<!DOCTYPE html>
<html>
  <head>
    <title>Vue SSR Example</title>
    <script type="importmap">
      {
        "imports": {
          "vue": "https://unpkg.com/vue@3/dist/vue.esm-browser.js"
        }
      }
    </script>

    <script type="module" src="/client.js"></script>
  </head>
  <body>
    <div id="app">{{html}}</div>
  </body>
</html>

启动服务

$ node server.js

访问地址:http://localhost:3000/

渲染后返回的html


<!DOCTYPE html>
<html>
  <head>
    <title>Vue SSR Example</title>
    <script type="importmap">
      {
        "imports": {
          "vue": "https://unpkg.com/vue@3/dist/vue.esm-browser.js"
        }
      }
    </script>

    <script type="module" src="/client.js"></script>
  </head>
  <body>
    <div id="app"><button>+1</button></div>
  </body>
</html>

其他方案

 类似资料: