You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Vue SSR中如何依据EJS信息切换组件复用createSSRApp?

动态切换Vue组件的实现方案

一、核心实现步骤

1. 在EJS模板中传递组件标识

在服务端渲染的EJS模板里,给挂载节点(比如#app)添加自定义属性,或者在全局window对象中注入组件名称,让前端main.ts能读取到服务端传递的标识:

<!-- 方式1:通过DOM属性传递 -->
<div id="app" data-component="<%= targetComponent %>"></div>

<!-- 方式2:通过全局变量传递 -->
<script>
window.__INITIAL_COMPONENT__ = "<%= targetComponent %>";
</script>

这里的targetComponent是服务端根据请求逻辑生成的组件名称(比如"Home"、"About")。

2. 在main.ts中动态加载对应组件

在main.ts里,先读取服务端传递的组件标识,再通过动态导入加载对应的Vue组件,最后创建SSR应用并挂载:

import { createSSRApp } from 'vue';

// 读取组件标识(二选一)
const targetComponent = document.getElementById('app')?.dataset.component || 'App';
// 或者 const targetComponent = window.__INITIAL_COMPONENT__ || 'App';

// 定义组件映射表,避免随意导入未知组件,提升安全性
const componentMap = {
  App: () => import('./App.vue'),
  Home: () => import('./views/Home.vue'),
  About: () => import('./views/About.vue')
};

// 动态加载组件
const loadComponent = async () => {
  const componentLoader = componentMap[targetComponent as keyof typeof componentMap] || componentMap.App;
  const { default: RootComponent } = await componentLoader();
  
  const app = createSSRApp(RootComponent);
  app.mount('#app');
};

loadComponent();

二、为什么直接在EJS中导入组件无效?

EJS是服务端渲染模板,运行在Node.js环境中,而Vue单文件组件(.vue)需要经过Vite/Webpack等构建工具的编译处理(解析template、script、style),Node.js无法直接识别和加载.vue文件,自然无法完成挂载渲染。必须通过前端的构建入口(main.ts)来处理组件的导入和挂载逻辑。

三、架构扩展性优化建议

当前硬编码挂载单一组件的模式扩展性差,建议结合以下方案优化:

  • 引入Vue Router SSR:把组件切换逻辑交给路由系统,服务端根据请求URL匹配路由组件,前端通过路由自动加载对应组件,无需手动传递组件标识。
  • 抽离组件配置:把组件映射表(componentMap)抽离成单独的配置文件(比如component.config.ts),新增组件时只需修改配置,无需改动main.ts。
  • 服务端预渲染数据:如果组件需要服务端数据,可以在EJS中同时注入__INITIAL_STATE__全局变量,前端组件挂载时直接取用,实现数据预传递。

内容的提问来源于stack exchange,提问作者Luke Steinbicker

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.05 01:17:14