1. 架构设计:响应式 + 自适应
(1) 响应式布局(Responsive Design)
- 核心思想:通过 CSS媒体查询(Media Queries) 和 弹性布局(Flex/Grid) 实现不同屏幕尺寸的适配。
- 适用场景:适用于大部分内容结构相似,仅布局需要调整的情况。
(2) 自适应设计(Adaptive Design)
- 核心思想:针对不同设备(PC/Tablet/Mobile)提供 不同的HTML结构或组件,甚至不同的路由。
- 适用场景:适用于移动端和PC端交互差异较大的情况(如电商详情页、后台管理系统)。
2. 具体实现方案
(1) 响应式布局实现(CSS + Flex/Grid)
① 使用 CSS 媒体查询
.container {
padding: 10px;
}
@media (min-width: 768px) {
.container {
padding: 20px;
}
}
@media (min-width: 1024px) {
.container {
max-width: 1200px;
margin: 0 auto;
}
}
② 弹性布局(Flexbox/Grid)
.navbar {
display: flex;
flex-direction: column;
}
@media (min-width: 768px) {
.navbar {
flex-direction: row;
}
}
.grid-container {
display: grid;
grid-template-columns: 1fr;
}
@media (min-width: 768px) {
.grid-container {
grid-template-columns: repeat(3, 1fr);
}
}
(2) 自适应设计实现(动态组件 + 条件渲染)
① 根据设备类型动态加载不同组件
import { useMediaQuery } from 'react-responsive';
const DesktopComponent = () => <div>PC端专属组件</div>;
const MobileComponent = () => <div>移动端专属组件</div>;
function App() {
const isMobile = useMediaQuery({ maxWidth: 768 });
return (
<div>
{isMobile ? <MobileComponent /> : <DesktopComponent />}
</div>
);
}
② Vue 动态组件
<template>
<component :is="isMobile ? 'MobileComponent' : 'DesktopComponent'" />
</template>
<script>
import MobileComponent from './MobileComponent.vue';
import DesktopComponent from './DesktopComponent.vue';
export default {
components: { MobileComponent, DesktopComponent },
computed: {
isMobile() {
return window.innerWidth <= 768;
},
},
};
</script>
(3) 交互优化(触控 vs 鼠标)
① 移动端优化(触控事件)
// 移动端优化:增加 touch 事件
<button
onClick={handleClick}
onTouchStart={handleTouchStart} // 优化触控反馈
onTouchEnd={handleTouchEnd}
>
按钮
</button>
② PC端优化(hover 效果)
.button {
transition: background 0.3s;
}
@media (hover: hover) {
.button:hover {
background: #f0f0f0;
}
}
(4) 性能优化(按需加载 + 图片适配)
① 按需加载组件(Code Splitting)
const DesktopComponent = React.lazy(() => import('./DesktopComponent'));
const MobileComponent = React.lazy(() => import('./MobileComponent'));
function App() {
return (
<Suspense fallback={<Loading />}>
{isMobile ? <MobileComponent /> : <DesktopComponent />}
</Suspense>
);
}
② 响应式图片(srcset + picture)
<picture>
<source media="(max-width: 768px)" srcset="mobile.jpg">
<source media="(min-width: 1024px)" srcset="desktop.jpg">
<img src="default.jpg" alt="响应式图片">
</picture>
3. 工具链支持
(1) 检测设备类型
- React:
react-responsive / react-device-detect
- Vue:
vue-mq / vue-device-detector
- 通用:
window.matchMedia()
(2) CSS 预处理(Sass/Less)
// 使用 Sass 变量管理断点
$mobile: 768px;
$tablet: 1024px;
.container {
@media (max-width: $mobile) {
padding: 10px;
}
@media (min-width: $tablet) {
max-width: 1200px;
}
}
(3) 构建优化(Webpack/Vite)
- 动态导入(Dynamic Import) :减少初始加载体积。
- PostCSS + Autoprefixer:自动添加浏览器前缀。
4. 最佳实践总结
| 方案 | 适用场景 | 示例 |
|---|
| 响应式布局 | 布局调整,内容相同 | @media + Flex/Grid |
| 自适应组件 | 交互差异大 | isMobile ? <Mobile /> : <Desktop /> |
| 动态加载 | 减少首屏体积 | React.lazy / import() |
| 图片优化 | 适配不同分辨率 | <picture> + srcset |
5. 完整代码示例(React + TailwindCSS)
import React, { useState, useEffect } from 'react';
import { useMediaQuery } from 'react-responsive';
const DesktopNav = () => <nav className="hidden md:flex">PC导航</nav>;
const MobileNav = () => <nav className="md:hidden">移动导航</nav>;
function App() {
const isMobile = useMediaQuery({ maxWidth: 768 });
return (
<div className="container mx-auto p-4">
{isMobile ? <MobileNav /> : <DesktopNav />}
<picture>
<source media="(max-width: 768px)" srcSet="mobile.jpg" />
<source media="(min-width: 1024px)" srcSet="desktop.jpg" />
<img src="default.jpg" alt="响应式图片" />
</picture>
</div>
);
}
export default App;
- 响应式布局:适用于布局调整,使用
@media + Flex/Grid。
- 自适应组件:适用于交互差异大的场景,动态加载不同组件。
- 性能优化:按需加载 + 响应式图片。
- 工具链:
react-responsive / vue-mq + Webpack/Vite 优化。