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
相关产品推荐
相关产品推荐

