| 场景 | UI选型 | 项目结构 | 技术落地 |
|---|---|---|---|
| PC + iPad + Mobile差异小 | 单套UI库 + 响应式 | 单项目 | MediaQuery + 核心组件 |
| PC + iPad + Mobile差异中等 | 核心组件 + 端特化UI | 单项目 | 条件渲染 + 核心组件复用 |
| PC + iPad + Mobile差异大 | 多套UI库 | 多项目 | monorepo共享逻辑 + npm核心组件包 |
| 横竖屏优化 | CSS Media Query + JS监听 | 单/多项目均可 | 动态类切换 + 主题变量 |
「一套」vs「多套」的核心抉择标准
| 对比维度 | 一套代码(响应式) | 多套代码(同构核心) | 跨端框架(一次开发) |
|---|---|---|---|
| 开发成本 | 最低 | 中等 | 最高(前期)/ 最低(后期) |
| 维护成本 | 最低 | 中等 | 最低(后期) |
| 端侧体验 | 一般 | 优秀 | 优秀(接近原生) |
| 落地速度 | 最快 | 中等 | 最慢(前期) |
| 团队要求 | 低(熟悉 Vue/React 即可) | 中(熟悉 Monorepo) | 高(熟悉跨端框架) |
2. 业务逻辑复用的核心保障(面试必答)
核心逻辑复用:
-
统一核心组件库
-
包括表单、按钮、表格、图表
-
核心逻辑可复用(props + events)
-
-
端特化组件
-
PC端复杂表格、大屏、图表、拖拽、复杂交互
-
移动端卡片列表、滑动操作
-
Ipad:横竖屏切换、触控优化
-
-
共享状态管理(业务可以抽出公共core、utils复用)
-
Vue: Pinia / Vuex
-
React: Redux / Zustand / Recoil
-
-
端特化主题
-
CSS Variables 或 Tailwind 配合端主题
-
横竖屏可切换布局(动态 class 或 style)
-
-
业务逻辑统一
-
API 层统一(REST / GraphQL)
-
公共逻辑层(utils、hooks / composables)
-
状态共享可用 monorepo 或 npm 私服包
-
-
解耦:业务逻辑与 UI 层严格分离,业务逻辑不依赖任何 UI 组件 / 端侧 API。
-
封装:核心业务逻辑抽离为独立包 / 函数,通过「接口化」暴露能力,避免直接操作数据。
-
版本控制:多套方案中,公共包采用语义化版本,避免更新导致各端兼容问题。
-
测试:公共业务包单独编写单元测试,保障稳定性,避免影响所有端侧。
类似结构:
css
vue:
src/
components/ # 核心可复用组件
Button/
Input/
views/ # 业务页面
pc/
mobile/
ipad/
store/
utils/
router/
React:
src/
components/
core/ # 公共核心组件
pc/ # PC专用组件
mobile/ # Mobile专用组件
pages/
Home/
index.jsx
hooks/
store/
// router/index.js
const routes = window.innerWidth > 1024 ? pcRoutes : isTablet ? ipadRoutes : mobileRoutes;
//使用 styled-components 的 theme 支持端主题:
const theme = isMobile ? mobileTheme : pcTheme;
<ThemeProvider theme={theme}>
<App />
</ThemeProvider>
//横竖屏监听
window.addEventListener('resize', () => {
setOrientation(window.innerWidth > window.innerHeight ? 'landscape' : 'portrait');
});
1、多套UI
如:Ant Design + Ant Design Mobile/AntD Next(React/Vue)、Element Plus (PC) + Element Plus Mobile
核心:业务逻辑与 UI 层解耦,将接口请求、数据处理、状态管理等核心业务逻辑抽离为「全局工具函数 / Hooks / Composables」,UI 层只负责渲染,不处理业务逻辑。
- 搭建多个工程(PC 工程、Pad 工程、Mobile 工程) ,但抽离「核心业务层」为独立公共包(NPM 私有包 / Monorepo 子包),各端工程仅负责「UI 层 + 端侧专属逻辑」,实现「业务核心复用,UI 层分离」。
- 核心原则:「核心同构,UI 异构」,业务逻辑、数据模型、API 请求统一复用,UI 层根据端侧特性单独设计,兼顾体验与复用性。
- 一个工程:多入口打包
- 多个工程:可以单独管理或者使用Monorepo 落地,如采用
pnpm workspace/lerna搭建 Monorepo
css
├── monorepo-root/
│ ├── packages/
│ │ ├── core/ # 核心公共包(所有端复用)
│ │ │ ├── api/ # 统一API请求
│ │ │ ├── utils/ # 统一工具函数
│ │ │ ├── store/ # 统一状态管理模型
│ │ │ ├── business/ # 统一业务逻辑(如订单处理、用户管理)
│ │ │ └── package.json # 发布为私有NPM包
│ │ ├── pc/ # PC端工程(Vue/React)
│ │ │ ├── src/
│ │ │ │ ├── components/ # PC专属UI组件
│ │ │ │ ├── views/ # PC专属页面
│ │ │ │ └── main.js # 入口文件
│ │ │ └── package.json
│ │ ├── pad/ # Pad端工程(Vue/React)
│ │ │ └── ...(结构同pc)
│ │ └── mobile/ # Mobile端工程(Vue/React/原生)
│ │ └── ...(结构同pc)
│ ├── pnpm-workspace.yaml # Monorepo配置
│ └── package.json
ui选型:
| 技术栈 | 核心 UI 库(首选,兼顾多端) | 补充工具(横竖屏 / 适配) | 选型理由(面试重点) |
|---|---|---|---|
| Vue2/Vue3 | Element Plus(PC 优先,支持响应式)+ Vant 4(移动端优先,可与 Element Plus 共存)备选:Naive UI(性能更优,响应式友好,支持自定义主题) | postcss-px-to-viewport(px 转 vw/vh)、postcss-preset-env(自动补全兼容)、vueuse(useScreenOrientation 检测横竖屏) | 1. Element Plus/Naive UI 成熟稳定,社区生态完善,bug 率低;2. Vant 针对移动端优化,渲染性能好,支持横竖屏适配,可与 Element Plus 通过「端侧判断」按需引入;3. 配套 PostCSS 工具可自动化适配,减少手动开发成本。 |
| React/React Native Web | Ant Design 5.x(PC 优先,轻量化,性能优)+ Taro UI / NutUI(移动端优先,多端兼容)备选:Mantine UI(响应式强大,内置多端适配工具) | tailwindcss(原子化 CSS,快速做响应式)、react-use(useMediaQuery 检测端侧 / 横竖屏)、postcss-px-to-rem | 1. Ant Design 5.x 重构后体积更小,渲染性能提升,支持响应式布局,稳定性经过大厂验证;2. Taro UI 专为多端适配设计,可无缝衔接 React,横竖屏适配 API 完善;3. Tailwind CSS 原子化样式,减少冗余 CSS,提升渲染性能,快速实现端侧样式差异化。 |

关键注意点:一套工程中引入双 UI 库时,必须做「端侧判断」按需加载,避免打包体积过大影响性能,例如:PC 端加载 Element Plus/Ant Design,移动端 / Pad 加载 Vant/Taro UI。
css
//1、判断端类型:userAgent、window.innerWidth 或 screen.width 判断端
const isMobile = /Mobi|Android/i.test(navigator.userAgent);
const isTablet = /iPad|Tablet/i.test(navigator.userAgent);
const platform = isMobile ? 'mobile' : isTablet ? 'ipad' : 'pc';
//2、懒加载防止一上来引入三个ui chunk包
import { Button, Input, Table } from 'antd'; //pc.js
import { Button, Field as Input, List as Table } from 'vant'; //mobile.js
let UI;
if(platform === 'pc') UI = await import('./ui/pc');
else if(platform === 'ipad') UI = await import('./ui/ipad');
else UI = await import('./ui/mobile');
//动态使用
React: <UI.App />
Vue: <component :is="UI.App"/>
//或者直接导出对应组件,页面使用从此处导入ui组件
const { Button, Input, Table } = UI;
//或者直接通过别名引入:
// vite.config.js
import { defineConfig } from 'vite';
export default defineConfig(({ mode }) => {
let platform = process.env.PLATFORM; // 'pc' | 'mobile' | 'ipad'
return {
resolve: {
alias: {
'@ui': `/src/ui/${platform}.js`
}
}
}
});
//import { Button, Input } from '@ui';
//可用 CSS 变量 + 响应式布局,不必单独切换组件库
//对于极端交互差异,可在端模块内 export 两套布局组件:
export const Button = isLandscape ? LandscapeButton : PortraitButton;
多入口:
css
src/
main.pc.js
main.ipad.js
main.mobile.js
build: {
rollupOptions: {
input: {
pc: 'src/main.pc.js',
ipad: 'src/main.ipad.js',
mobile: 'src/main.mobile.js'
}
}
}
访问时可以通过服务器设置,根据访问设备信息,访问对应的html+css等资源,也可以按照上面同一个项目多入口返回:
css
if ($http_user_agent ~* 'Mobi|Android') {
rewrite ^/$ /mobile/index.html;
}
if ($http_user_agent ~* 'iPad|Tablet') {
rewrite ^/$ /ipad/index.html;
}
多项目独立部署的:
公共业务逻辑抽成 npm 包或 monorepo
-
Nginx / CDN 根据 User-Agent 重定向(多个项目可以统一域名 + 不同子目录:主域名相同,如youtube.com 和 m.youtube.com)
-
或前端根路由根据 UA 跳转:
cssif(isMobile) location.href = '/mobile'; else if(isTablet) location.href = '/ipad'; else location.href = '/pc';
2、统一的ui库:一套组件库多端适配
一套代码工程(Vue/React)、一套 UI 组件库、一套业务逻辑,通过CSS 响应式 + 横竖屏检测 + 端侧适配逻辑,适配所有端(PC/Pad/Mobile)。
核心原则:「样式适配差异化,业务逻辑统一化」,只在 UI 层做端侧 / 横竖屏区分,业务层无感知。
1)TDesign(腾讯):支持 React / Vue / 小程序 / H5 / PC=》业界少数真正"一套组件跨端"的 UI 库
2)NutUI(京东):Vue / React 都有版本,移动端和 H5 / PC 支持同一套设计体系=》PC端功能可能有限,不适合复杂后台系统
3)自研组件库 + 响应式布局:布局响应式:
javascript
import { useMediaQuery, useWindowSize } from 'react-use'
import { useState, useEffect } from 'react'
const DeviceAdapter = () => {
const [currentDevice, setCurrentDevice] = useState('')
const { width } = useWindowSize()
// 检测横竖屏
const isPortrait = useMediaQuery('(orientation: portrait)')
const isLandscape = useMediaQuery('(orientation: landscape)')
// 检测端侧(防抖)
useEffect(() => {
const debounceCheck = setTimeout(() => {
if (width >= 1441) setCurrentDevice('pc')
else if (width >= 768 && width <= 1440) setCurrentDevice('pad')
else setCurrentDevice('mobile')
}, 300)
return () => clearTimeout(debounceCheck)
}, [width])
// 监听端侧+横竖屏变化
useEffect(() => {
console.log(`当前端侧:${currentDevice},当前方向:${isPortrait ? '竖屏' : '横屏'}`)
}, [currentDevice, isPortrait])
return null
}
//Vue:
<script setup>
import { useScreenOrientation } from '@vueuse/core'
import { ref, watch } from 'vue'
const { orientation, isPortrait, isLandscape } = useScreenOrientation()
const currentDevice = ref('') // 记录当前端侧:pc/pad/mobile
// 1. 检测端侧
const checkDevice = () => {
const width = window.innerWidth
if (width >= 1441) currentDevice.value = 'pc'
else if (width >= 768 && width <= 1440) currentDevice.value = 'pad'
else currentDevice.value = 'mobile'
}
// 2. 初始化+监听窗口大小变化(防抖,避免频繁触发影响性能)
const debounce = (fn, delay = 300) => {
let timer = null
return () => {
clearTimeout(timer)
timer = setTimeout(() => fn(), delay)
}
}
checkDevice()
window.addEventListener('resize', debounce(checkDevice))
// 3. 横竖屏+端侧变化触发业务逻辑(如重新渲染布局)
watch([() => currentDevice.value, isPortrait], ([device, portrait]) => {
console.log(`当前端侧:${device},当前方向:${portrait ? '竖屏' : '横屏'}`)
// 可触发布局重置、组件重新适配等逻辑
})
</script>
-
使用 Flex / Grid + Media Query
-
使用 VW/VH/rem/rem+媒体查询等单位
-
React/Vue 中结合 CSS Variables、styled-components / CSS Modules / SCSS 管理
-
横竖屏切换:
css@media (orientation: landscape) { ... } @media (orientation: portrait) { ... } -
适合: PC + iPad + Mobile 有相似结构的系统
-
优点: 一套代码,多端维护简单
-
缺点: 对复杂端差异(如桌面复杂表格 vs 移动卡片)不好处理,可以考虑混合:公用UI(如input、button)+端特化 UI
3、跨端技术实现多端
- 使用跨端框架,一套代码通过框架编译,生成各端(PC/Pad/Mobile/ 甚至原生 App)的可运行代码,框架内置多端适配 / 横竖屏适配能力,无需手动处理端侧差异。
- 核心原则:「框架封装差异,开发者聚焦业务」,通过框架屏蔽各端底层差异,实现「一次开发,多端部署」。
Ant Design + Taro / Uni-UI / uni-app
-
Uni-UI 提供 跨端组件(Web / 小程序 / Mobile)
-
Taro + React / Vue → 通过同一套组件映射到不同平台
-
结论 :更偏向 移动端 + 小程序 + H5,不完全覆盖 PC 桌面端复杂场景
1. 主流跨端框架选型(Vue/React 对应,可落地)
| 技术栈 | 跨端框架 | 配套 UI 库 | 选型理由(面试重点) |
|---|---|---|---|
| Vue | Taro 3.x(支持 Vue3) | Taro UI 3.x | 1. 支持 Vue3,编译为 H5(PC/Pad/Mobile)、小程序、原生 App;2. 内置响应式布局 / 横竖屏适配能力,无需手动配置;3. Taro UI 专为跨端设计,组件兼容性强,渲染性能优;4. 生态完善,文档详细,落地难度低于 UniApp(大型项目)。 |
| React | React Native + React Native Web | Native Base / UI Kitten | 1. React Native Web 可将 React Native 代码编译为 H5(PC/Pad/Mobile),兼顾原生 App 与 Web 端;2. Native Base 支持跨端适配,组件样式统一,稳定性高;3. 生态成熟,大厂(如 Meta、阿里)广泛使用,长期维护有保障;4. 横竖屏适配通过 React Native 内置 API 实现,灵活高效。 |
| 通用(Vue/React) | UniApp(支持 Vue3 为主,React 支持有限) | Uni UI | 1. 入门门槛低,落地速度快,支持 H5、小程序、原生 App;2. Uni UI 内置多端适配组件,横竖屏适配完善;3. 社区生态活跃,问题解决方案多,适合快速落地;4. 缺点:React 支持有限,大型项目编译性能略低。 |
关键注意点:跨端框架并非「银弹」,复杂端侧专属逻辑仍需通过「条件编译」处理,不可完全依赖框架封装。
如taro,编译为 H5(PC/Pad/Mobile)、编译为小程序、编译为原生 App