umijs+antd v5+cordova套壳App开发常见浏览器兼容性问题及配置解决

文章描述了一家公司开发平板应用过程中遇到的umijs和antd在老旧webview中的兼容性问题,包括语法错误、样式失效和适配方案。解决了webview版本过低导致的兼容性问题,以及使用rem适配不同终端和antd暗黑模式配置的方法。
摘要由CSDN通过智能技术生成

公司项目需要开发一款平板应用,用于公司内部作业人员使用。考虑到使用人数较少、对应用性能无较高要求,决定沿用前端现有技术栈,最后使用cordova打包成套壳App的开发方案。由于拿到的平板系统过于老旧,所以出现了一些webview兼容性问题,下面记录了相应的问题和解决方案。

umijs兼容问题

问题: 打包之后,运行到平板上时,出现白屏等无法加载的问题,控制台有Uncaught TypeError报错。
原因: 因为webview版本太低,js很多新的语法不支持,所有需要解决webview即低版本浏览器的兼容问题。
方案: umi配置文件中,targets属性,可配置需要兼容的浏览器最低版本
在这里插入图片描述
umi官方配置文档

antd样式兼容问题

问题: 打包之后再运行到平板上时,App可以运行,但发现antd的样式失效了。
原因: antd v5中CSS-in-JS 默认通过 :where 选择器降低 CSS Selector 优先级,低版本浏览器不支持:where的写法。
方案: 使用 @ant-design/cssinjs 取消默认的降权操作
注意: 请注意版本保持与 antd 一致,自己没注意这句话,就踩坑里了,如果安装过@ant-design/cssinjs之后,再变更antd版本,对应的@ant-design/cssinjs要卸载重装
在这里插入图片描述
ant design 样式兼容

其他问题: 知道怎么配置了,不过一开始没找到项目的主入口文件中如何配置StyleProvider,后来在umi的运行时配置文档中找到了配置方法。
方案: umi的rootContainer配置,可以修改交给 react-dom 渲染时的根组件,在外面包一个 Provider。

export function rootContainer(container) {
  return React.createElement(StyleProvider, {
  	hashPriority: 'high'
  }, container);
}

umi运行时配置

其他问题: 配置完成之后,发现其他组件都正常,但是message、modal等组件的样式还存在问题
原因: 浏览器中调试发现message的样式还是:where书写方式,在平板上运行发现message组件的样式丢失了,结论认定还是message的样式中:where移除失败,后来提了issues,感谢antd项目人员的快速回复。原来antd message组件的文档里已记录了此常见问题
方案: 更改message的调用方式

// 通过App包裹组件的方式

import React from 'react';
import { App, Button} from 'antd';
// Sub page
const MyPage = () => {
  const { message, modal, notification } = App.useApp();
  const showMessage = () => {
    message.success('Success!');
  }
  return (
      <Button type="primary" onClick={showMessage}>
        Open message
      </Button> );
};
// Entry component
export default () => (
  <App>
    <MyPage />
  </App>
);

antd message FAQ

rem适配方案

问题: 因为项目的优先级不高,所以没有安排UI设计高保真页面,由经理临时画了个原型,分辨率并未做考虑,再加上现在调试的平板和作业员手中的可能会有差异,用传统的px写法不适用,flex布局效果也不是太好。
方案: 最后决定采用rem的写法,来适配不同终端

// 通过js设置根字体大小 = *( 当前设备横向独立像素值 100) / 设计稿宽度
// 编写样式时,直接以rem为单位,值为:设计值 / 100
function adapter() {
  const rootFontSize = document.documentElement.clientWidth * 100 / 1366
  document.documentElement.style.fontSize = rootFontSize + "px" 
}
adapter()
// 视口发生变化的时候触发
window.onresize = adapter

其他问题: 自己的页面适配了,antd的组件样式也要改成rem的方式
方案: antd 是支持配置px单位转rem的,直接按说明配置即可

import { StyleProvider, px2remTransformer } from '@ant-design/cssinjs';

// 往之前的rootContainer配置中加入对应的transformers
const px2rem = px2remTransformer({
  rootValue: document.documentElement.clientWidth * 100 / 1366,  
});
export function rootContainer(container) {   
  return React.createElement(StyleProvider, {
    transformers: [px2rem]
    , hashPriority: "high"
  }, container);
}

antd rem适配

antd 暗黑模式配置

方案: 使用antd提供的预设算法方案

import { StyleProvider, px2remTransformer } from '@ant-design/cssinjs';
import { ConfigProvider, theme } from 'antd';

// 在之前的rootContainer中嵌套一层ConfigProvider的配置即可
export function rootContainer(container:any) {   
  return React.createElement(StyleProvider, {
    transformers: [px2rem]
    , hashPriority: "high"
  }, React.createElement(ConfigProvider, { 
    theme: { algorithm: theme.darkAlgorithm }
  },  container)); 
} 
  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
要自定义 Ant Design Pro 中的 headerRender,可以按照以下步骤进行: 1. 打开 src/layouts/BasicLayout.tsx 文件。 2. 在 render() 函数中找到 Header(头部)组件,将其替换为自定义的组件。可以使用 Ant Design 的 Layout.Header 组件或者其他 UI 库中的组件。 3. 在自定义 Header 组件中,可以通过 props 获取到当前用户信息、菜单信息等相关数据,并渲染出对应的 UI 界面。 以下是一个简单的示例代码: ```jsx import React from 'react'; import { Layout, Avatar, Menu, Dropdown } from 'antd' import { UserOutlined } from '@ant-design/icons'; import { useModel } from 'umi'; const CustomHeader: React.FC = () => { const { initialState } = useModel('@@initialState'); const { currentUser } = initialState || {}; const handleMenuClick = (e: any) => { console.log(e) } const menu = ( <Menu onClick={handleMenuClick}> <Menu.Item key="1">个人中心</Menu.Item> <Menu.Item key="2">退出登录</Menu.Item> </Menu> ) return ( <Layout.Header> <div style={{ display: 'flex', alignItems: 'center' }}> <Avatar size="small" icon={<UserOutlined />} /> <span style={{ marginLeft: '10px' }}>{currentUser?.name}</span> <Dropdown overlay={menu} trigger={['click']}> <a href="#" style={{ marginLeft: '10px' }}>操作</a> </Dropdown> </div> </Layout.Header> ) } export default CustomHeader; ``` 在这个示例中,我们通过 useModel 获取到了当前用户信息,然后在自定义的 Header 组件中渲染出了用户头像、名称和一个下拉菜单,通过点击下拉菜单中的选项可以触发对应的事件。你可以根据自己的需求来修改这个示例代码,实现自己想要的 Header UI 界面。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值