react 适配移动端 H5 项目

主要介绍使用create-react-app创建项目,实现移动端 H5 项目的框架适配,主要有视口 viewport 适配、rem 适配及路由配置等等

1. 视口 viewport 适配

public/index.html 中添加如下配置, 适应网页在移动设备上的视口(viewport):

html 复制代码
<meta
  name="viewport"
  content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no, viewport-fit=cover"
/>
  • width=device-width: 设置视口的宽度等于设备的屏幕宽度,确保网页内容可以完全显示在屏幕上。
  • initial-scale=1.0: 设置页面的初始缩放比例为 1.0,即不进行缩放。
  • minimum-scale=1.0: 设置用户可以缩小页面的最小缩放比例为 1.0,即不允许缩小。
  • maximum-scale=1.0: 设置用户可以放大页面的最大缩放比例为 1.0,即不允许放大。
  • user-scalable=no: 禁止用户对页面进行缩放操作,保持页面的固定缩放比例。
  • viewport-fit=cover: 告诉浏览器将网页内容完全覆盖整个设备的屏幕,防止在一些设备上出现页面过小的情况。

2. rem 适配

通过设置 htmlfont-size 来实现 rem 适配。

我使用的 UI 设计稿是 IPhone 6/7/8 的 375*667分辨率,通过如下配置,在该型号手机上,html 的 font-size 为 100px,即 1rem=100px,方便计算。

public/index.html 中添加如下配置

html 复制代码
<script src="%PUBLIC_URL%/js/flexible.js"></script>

flexible.js 代码如下所示:

通过监听窗口大小变化,动态设置 html 的 font-size,实现移动端适配

js 复制代码
(function (d, c) {
  var e = d.documentElement,
    b = "orientationchange" in window ? "orientationchange" : "resize",
    a = function () {
      var f = e.clientWidth;
      if (!f) {
        return;
      }
      if (
        !/Android|webOS|iPhone|iPod|BlackBerry|SymbianOS|Windows Phone/i.test(
          navigator.userAgent
        )
      ) {
        // PC端不设置
        // e.style.fontSize = "100px";
        return;
      }
      // 根据屏幕宽度动态设置font-size
      e.style.fontSize = 100 * (f / 375) + "px";
    };
  if (!d.addEventListener) {
    return;
  }
  c.addEventListener(b, a, false);
  d.addEventListener("DOMContentLoaded", a, false);
})(document, window);

3. 路由配置

3.1 移动端路由

router/index.tsx 中进行路由区分配置,PC 端和移动端路由不同。

通过 isPC() 函数判断设备类型,选择相应的路由方式

js 复制代码
// PC端路由配置
const pcRouter = [{ path: "/", element: <Index /> }];
// 移动端路由配置
const mobileRouter = [{ path: "/", element: <MIndex /> }];
// 根据设备类型选择对应的路由配置
export default !!isPC() ? pcRouter : mobileRouter;

3.2 一级路由

一级路由在 App.tsx 中进行配置,具体代码如下所示:

我使用的是 React Router 6.x,详细 useRoutes 配置可以查看官网,reactrouter.com/en/main/hoo...

js 复制代码
import { useRoutes } from "react-router-dom";
import router from "./router";

const App = () => {
  // 根据路由配置渲染页面
  return <>{useRoutes(router)}</>;
};

router/index.tsx 文件如下所示:

js 复制代码
// 移动端路由配置
const mobileRouter = [
  { path: "/", element: <MIndex /> }, // 首页路由
  { path: "/login", element: <MLogin /> }, // 登录页面路由
  { path: "*", element: <M404 /> }, // 未匹配上 404页面路由
];

3.3 二级路由

可以在二级路由中配置公共框架组件,二级路由通过 children 属性来进行配置

js 复制代码
// router/index.tsx
const MIndex = lazy(() => import("src/mobile/index"));
const MHome = lazy(() => import("src/mobile/home"));

const mobileRouter = [
  {
    path: "/",
    // MIndex页面作为一级路由
    element: <MIndex />, 
    // 子路由配置,例如/home路由
    children: [{ path: "/home", element: <Home /> }],
  },
];

手机版一般分为头部,尾部和内容区,MIndex 页面可以共用这些配置。

子路由占位使用 Outlet 标签,具体配置可查看官网reactrouter.com/en/main/com...

js 复制代码
// mobile/index/index.tsx
import { Outlet } from "react-router-dom";

function Page() {
  return (
    <div className="m_layout">
      {/* 头部组件  */}
      <MHeader />
      {/* 渲染子路由 */}
      {<Outlet />}
      {/* 底部组件 */}
      <MFooter />
    </div>
  );
}

参考文档:

相关推荐
WeilinerL3 分钟前
泛前端代码覆盖率探索之路
前端·javascript·测试
浮游本尊7 分钟前
React 18.x 学习计划 - 第五天:React状态管理
前端·学习·react.js
-睡到自然醒~12 分钟前
[go 面试] 前端请求到后端API的中间件流程解析
前端·中间件·面试
洛卡卡了20 分钟前
Sentry 都不想接,这锅还让我背?这xx工作我不要了!
前端·架构
咖啡の猫24 分钟前
Vue 实例生命周期
前端·vue.js·okhttp
JNU freshman38 分钟前
vue 之 import 的语法
前端·javascript·vue.js
剑亦未配妥39 分钟前
Vue 2 响应式系统常见问题与解决方案(包含_demo以下划线开头命名的变量导致响应式丢失问题)
前端·javascript·vue.js
凉柚ˇ42 分钟前
Vue图片压缩方案
前端·javascript·vue.js
慧一居士42 分钟前
vue 中 directive 作用,使用场景和使用示例
前端
慧一居士44 分钟前
vue 中 file-saver 功能介绍,使用场景,使用示例
前端