React-antd5样式兼容360浏览器(基于antd封装自己的message轻提示,完美兼容360)

1,730 阅读3分钟

最近写了几个后台管理,用的antd5最新版。开始都一切正常,直到测试提到360浏览器的样式有问题。才发现antd5的样式全部添加了css新语法,360浏览器完全不认识。

详情请戳:ant.design/docs/react/…

这部分比较简单。按照官网来就可以了。

1."@ant-design/cssinjs": "^1.5.6",
    npm i @ant-design/cssinjs


2.在入口index.tsx里面


import App from "./App";
import store from "./store/index";

import { Provider } from "react-redux";
import { createRoot } from "react-dom/client";

import { ConfigProvider } from "antd";

// 兼容360浏览器
import {
  StyleProvider,
  legacyLogicalPropertiesTransformer,
} from "@ant-design/cssinjs";

import "dayjs/locale/zh-cn";
import locale from "antd/locale/zh_CN";

const container = document.getElementById("root") as HTMLElement;
const root = createRoot(container);

root.render(
  <ConfigProvider
    locale={locale}
    theme={{
      token: {
        colorPrimary: "#863326",
      },
    }}
  >
    <Provider store={store}>
      <StyleProvider
        hashPriority="high"
        transformers={[legacyLogicalPropertiesTransformer]}
      >
        <App />
      </StyleProvider>
    </Provider>
  </ConfigProvider>
);

麻烦的来了(antd的message轻提示,无法获取上下文,也就是说在上面的入口index.tsx,全局配置的ConfigProvider是无效的。)

具体参考官网:ant.design/components/…

1.jpg

由于已经在项目中使用了很多从的message静态调用。修改的代价很大。于是考虑封装一个自己的message轻提示,尽量和之前的语法一样。

ps:本人的项目使用了reduxreact-redux

一:封装自己的Message组件

src/components/Message/index.tsx
import React, { useEffect } from "react";
import { message } from "antd";
import { useSelector } from "react-redux";
import { RootState } from "@/store";

function MessageCom() {
  // 从仓库中获取 antd 轻提示信息
  const messageReducerInfo = useSelector(
    (state: RootState) => state.loginStore.message
  );

  const [messageApi, contextHolder] = message.useMessage();

  useEffect(() => {
  //当仓库的message信息改变的时候触发,
  //messageReducerInfo.txt为空的时候不触发,避免一进页面就触发的bug
    if (messageReducerInfo.txt) {
      messageApi.open({
        type: messageReducerInfo.type,
        content: messageReducerInfo.txt,
        duration: messageReducerInfo.duration,
      });
    }
  }, [messageApi, messageReducerInfo]);

  return <>{contextHolder}</>;
}

const MemoMessage = React.memo(MessageCom);

export default MemoMessage;

二:message相关的仓库信息

import { MessageType } from "@/utils/message";

// 初始化状态
const initState = {

  // antd轻提示(兼容360浏览器)
  message: {
    txt: "",
    type: "info",
    duration: 3,
  } as MessageType,
};

// 定义 action 类型
type LoginActionType =
  | { type: "login/message"; payload: MessageType };

export default function loginReducer(
  state = initState,
  action: LoginActionType
) {
  switch (action.type) {
    // antd轻提示(兼容360浏览器)
    case "login/message":
      return { ...state, message: action.payload };
    default:
      return state;
  }
}

三:封装自己的MessageFu函数

src/utils/message.ts


import store from "@/store";

export type MessageType = {
  txt: string;
  type: "info" | "success" | "error" | "warning";
  duration: number;
};

export const MessageFu = {
  info: (txt: string, duration?: number) => {
    store.dispatch({
      type: "login/message",
      payload: {
        txt,
        type: "info",
        duration: duration === undefined ? 3 : duration,
      },
    });
  },
  success: (txt: string, duration?: number) => {
    store.dispatch({
      type: "login/message",
      payload: {
        txt,
        type: "success",
        duration: duration === undefined ? 3 : duration,
      },
    });
  },
  error: (txt: string, duration?: number) => {
    store.dispatch({
      type: "login/message",
      payload: {
        txt,
        type: "error",
        duration: duration === undefined ? 3 : duration,
      },
    });
  },
  warning: (txt: string, duration?: number) => {
    store.dispatch({
      type: "login/message",
      payload: {
        txt,
        type: "warning",
        duration: duration === undefined ? 3 : duration,
      },
    });
  },
};


四:别忘了在总App.tsx组件里面使用(主要是最后一句代码,其他的可以忽略)


import "@/assets/styles/base.css";
// 关于路由
import React from "react";
import { Router, Route, Switch } from "react-router-dom";
import history from "./utils/history";
import AuthRoute from "./components/AuthRoute";
import SpinLoding from "./components/SpinLoding";
import AsyncSpinLoding from "./components/AsyncSpinLoding";
import { Image } from "antd";
import { useDispatch, useSelector } from "react-redux";
import { RootState } from "./store";
import UpAsyncLoding from "./components/UpAsyncLoding";
import VideoLookDom from "./components/VideoLookDom";
import MessageCom from "./components/Message";
const Layout = React.lazy(() => import("./pages/Layout"));
const Login = React.lazy(() => import("./pages/Login"));
const H5Code = React.lazy(() => import("./pages/H5Code"));

export default function App() {
  const dispatch = useDispatch();

  // 从仓库中获取查看图片的信息
  const lookBigImg = useSelector(
    (state: RootState) => state.loginStore.lookBigImg
  );

  return (
    <>
      {/* 关于路由 */}
      <Router history={history}>
        <React.Suspense fallback={<SpinLoding />}>
          <Switch>
            <Route path="/login" component={Login} />
            <Route path="/code" component={H5Code} />
            <AuthRoute path="/" component={Layout} />
          </Switch>
        </React.Suspense>
      </Router>

      {/* 发送请求的加载组件 */}
      <AsyncSpinLoding />

      {/* 所有图片点击预览查看大图 */}
      <Image
        preview={{
          visible: lookBigImg.show,
          src: lookBigImg.url,
          onVisibleChange: (value) => {
            // 清除仓库信息
            dispatch({
              type: "login/lookBigImg",
              payload: { url: "", show: false },
            });
          },
        }}
      />

      {/* 上传附件的进度条元素 */}
      <UpAsyncLoding />

      {/* 点击预览视频组件 */}
      <VideoLookDom />

      {/* antd 轻提示 ---兼容360浏览器 */}
      <MessageCom />
    </>
  );
}


五:使用:

之前直接调用antd message的静态轻提示:

引入:import {message} from "antd";

使用:message.success("操作成功!");

现在的使用(完美兼容 粑粑360浏览器):

引入:import { MessageFu } from "@/utils/message";

使用:MessageFu.success("删除成功!");