react 适配移动端 H5 项目

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

1. 视口 viewport 适配

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

<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 中添加如下配置

<script src="%PUBLIC_URL%/js/flexible.js"></script>

flexible.js 代码如下所示:

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

(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() 函数判断设备类型,选择相应的路由方式

// 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…

import { useRoutes } from "react-router-dom";
import router from "./router";

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

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

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

3.3 二级路由

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

// 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…

// mobile/index/index.tsx
import { Outlet } from "react-router-dom";

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

参考文档:

原文链接:https://juejin.cn/post/7313841072228040715 作者:时光足迹

(0)
上一篇 2023年12月19日 上午11:12
下一篇 2023年12月19日 下午4:05

相关推荐

发表回复

登录后才能评论