不爱贞子爱爽子
バキューン

1、初始安装react+ts

 npx create-react-app my-app   

npx create-react-app react-ts  --template typescript  安装为ts

2、安装好react 后面加上ts

   2.1 tsc --init  生产tsconfig.js


{
  "compilerOptions": {
    "target": "es5" /**指定ECMAScript目标版本**/,
    "module": "commonjs" /**指定生成哪个模块系统代码**/,
    "allowJs": true /**允许编译js文件**/,
    "jsx": "preserve" /**支持JSX**/,
    "outDir": "build" /**编译输出目录**/,
    "strict": true /**启用所有严格类型检查选项**/,
    "noImplicitAny": false /**在表达式和声明上有隐含的any类型时报错**/,
    "skipLibCheck": true /**忽略所有的声明文件的类型检查**/,
    "forceConsistentCasingInFileNames": true /**禁止对同一个文件的不一致的引用**/,
    "baseUrl": "./",
    "paths": {
      "@/*": ["src/*"],
      "@assets/*": ["src/assets/*"],
      "@components/*": ["src/components/*"],
      "@pages/*": ["src/pages/*"],
      "@utils/*": ["src/utils/*"],
      "@store/*": ["src/store/*"]
    }
  },
  "include": ["src"] /**指定编译目录**/
}

 

  2.2 引入ts   yarn add typescript   yarn add @types/react @types/react-dom

  2.3 react 里面的文件.js  需要修改为.tsx  包含jsx的都需要改为tsx

3、react 里面的文件.js  需要修改为.tsx

4、安装mobx

yarn add mobx  mobx-react-lite

---React Developer Tools安装

---1 下载包 https://www.crx4chrome.com/crx/3068/  下载crx包

---2 将报的后缀名修改为rar或者zip

---3 解压完成后如下

 ---4打包完成后在chrome加载已解压的文件 

----5加载的文件夹不能删除 删除了插件就找不到了   可以放在一个地方

5、类型断言   

JSON.parse(getUserInfo() as string)   用于ts警告报错
6、token持久化配置  存储到localstorage
utils/userInfo.js
//封装userinfo 存到localstorage
const Key = "userInfo"

//set
const setUserInfo = (userInfo)=> {
    return window.localStorage.setItem(Key, userInfo)
}

// get
const getUserInfo = ():string|null=> {
    return window.localStorage.getItem(Key)
}

//remove
const removeUserInfo = ()=> {
    return window.localStorage.removeItem(Key)
}

export {setUserInfo, getUserInfo, removeUserInfo}

保存的时候

let userInfo = {
      token: resp.data.token,
      sessionId: resp.sessionId,
      username: enterpriseAccount,
      relateEnterpriseName: resp.userInfo.enterpriseName,
      relateEnterpriseId: resp.userInfo.id,
      isSuperAdmin: resp.userInfo.isSuperAdmin,
    };
setUserInfo(JSON.stringify(userInfo));

7、组件鉴权  没有token信息就跳转到login

AuthComponent.tsx

//判断用户信息token是否存在
//存在直接渲染
//不存在直接跳转
//AuthComponent 里面加入需要鉴权的组件
import { getUserInfo } from "@/utils/index"
import { Navigate } from "react-router-dom"
function AuthComponent({ children }) {
    const userInfo = JSON.parse(getUserInfo() as string);
    let token = userInfo ? userInfo.token : '';
    if (token !=="") {
        return <>{children}</>
    } else {
        //跳转到登录页
        return <Navigate to={"/login"} />
    }
}

export { AuthComponent }

使用

/*路有需要鉴权的地方使用*/
<Route path="/" element={
            <AuthComponent><Layout /></AuthComponent>
}></Route>

8、ts 设置router index 跳转首页

 <Route index element={
              <AuthComponent><Home /></AuthComponent>
            }></Route>

9、错误信息 

Do you need to change your target library? Try changing the 'lib' compiler option to 'es2021' or later.

 "compilerOptions": {
    "target": "es5" /**指定ECMAScript目标版本**/,
    "module": "commonjs" /**指定生成哪个模块系统代码**/,
    "allowJs": true /**允许编译js文件**/,
    "jsx": "preserve" /**支持JSX**/,
    "outDir": "build" /**编译输出目录**/,
    "strict": true /**启用所有严格类型检查选项**/,
    "noImplicitAny": false /**在表达式和声明上有隐含的any类型时报错**/,
    "skipLibCheck": true /**忽略所有的声明文件的类型检查**/,
    "forceConsistentCasingInFileNames": true /**禁止对同一个文件的不一致的引用**/,
    "baseUrl": "./",
    "paths": {
      "@/*": ["src/*"],
      "@assets/*": ["src/assets/*"],
      "@components/*": ["src/components/*"],
      "@pages/*": ["src/pages/*"],
      "@utils/*": ["src/utils/*"],
      "@store/*": ["src/store/*"]
    }
  },
"lib": [ "dom", "es5", "es2015.promise" ,"es2015", "es2017"],

 10、antd menu

菜单点击跳转

const navigate = useNavigate();
//跳转
navigate(key);

菜单点击高亮当前菜单

const [current, setCurrent] = React.useState("/");
//高亮当前
setCurrent(key);
<Menu
   mode="inline"
   defaultSelectedKeys={['/']}
   selectedKeys={[current]}
   className="layout-menu"
   items={MenuList}
    onClick={menuClickHandler}
/>
                  

路由刷新高亮菜单

const location = useLocation();
// 获取当前路由
setCurrent(location.pathname)

11、userEffect [] 调用了两次

去掉严格模式   

  // <React.StrictMode>
    <App />
  // </React.StrictMode>

12、配置多环境变量  

yarn add dotenv-cli
新建env文件  .env  & .env.production
#REACT_APP开头
REACT_APP_URL = ''
REACT_APP_URL_initialize = ''
REACT_APP_ENV=production
package.json 
 "start": "craco start",
 "production": "dotenv -e .env.production craco start",
 "build": "dotenv -e .env.production craco build",

获取参数

const base_obj = {
  base: process.env.REACT_APP_URL,
  initialize: process.env.REACT_APP_URL_initialize,
};

13、外部配置路由跳转

   1.安装history  yarn add history

  2.创建history.ts

import { createBrowserHistory } from 'history'
const browserHistory  = createBrowserHistory()
export default browserHistory 

  3.创建自定义路由文件组件CutstomBrowserRouter.tsx

import * as React from "react";

import { Router } from "react-router-dom";
import browserHistory from "@/utils/history";


export default function CustomBrowserRouter({ basename="", children, window="" }) {
  let historyRef = React.useRef();
  if (historyRef.current == null) {
    //@ts-ignore
    historyRef.current = browserHistory;
  }

  let history:any = historyRef.current;
  let [state, setState] = React.useState({
    action: history.action,
    location: history.location,
  });

  React.useLayoutEffect(() => history.listen(setState), [history]);

  return (
    <Router
      basename={basename}
      children={children}
      location={state.location}
      navigationType={state.action}
      navigator={history}
    />
  );
}

  4.index.tsx使用

import CustomBrowserRouter from "@/components/CutstomBrowserRouter";
<CustomBrowserRouter>
    <App />
  </CustomBrowserRouter>

把原来的BrowserRouter替换为CustomBrowserRouter 

14、类型“JSX.IntrinsicElements”上不存在属性“children”。

//Children  需要大写
function BaseSeacrh({ children }) {
return <div className="baseSeacrh"> {<children/>} </div> }

15、路由表配置

router/index.tsx
/* eslint-disable import/no-anonymous-default-export */
import * as React from "react";
import { lazy, Suspense, ReactNode, ComponentType, LazyExoticComponent } from "react";
import NotFound from "@/pages/NotFound";
import { AuthComponent } from '@/components/AuthComponent'

interface IRoute {
    path: string,
    element: ReactNode
    children?: IRoute[]
}
function lazyLoad(path: string) {
    const Comp: LazyExoticComponent<ComponentType<any>> = lazy(() => import("@/pages/" + path));
    return (
        <Suspense fallback={<div>加载中……</div>}>
            <Comp />
        </Suspense>
    );
}

const Routers: IRoute[] = [
    {
        path: "/login",
        element: lazyLoad("Login"),
    },
    {
        path: "/",
        element: <AuthComponent>{lazyLoad("LayoutView")}</AuthComponent>,
        children: [
            {
                path: "home",
                element: lazyLoad("Home"),
            },
            {
                path: "menu",
                element: lazyLoad("Menu"),
            },
            {
                path: "role",
                element: lazyLoad("Role"),
            },
            {
                path: "user",
                element: lazyLoad("User"),
            },
            {
                path: "dict",
                element: lazyLoad("Dict"),
            },
            {
                path: "logs",
                element: lazyLoad("Logs"),
            },
            {
                path: "module",
                element: lazyLoad("Module"),
            },
        ],
    },
    {
        path: "*",
        element: <NotFound />,
    },
];
export default Routers

使用

index.js / index.jsx

import { BrowserRouter } from 'react-router-dom'; 
 <BrowserRouter>
    <App />
    </BrowserRouter>

app.js/app.tsx

import { useRoutes } from "react-router-dom";
import "./App.css";
import routes from "@/router"
function App() {
  const element = useRoutes(routes);
  return (
    // <BrowserRouter>
      <div className="App">
        {/* <Routes> */}
          {/* 鉴权 */}
          {/* <Route path="/" element={
            <AuthComponent><LayoutView /></AuthComponent>
          }>
            <Route index element={
              <AuthComponent><Home /></AuthComponent>
            }></Route>
            <Route path="/menu" element={
              <AuthComponent><Menu /></AuthComponent>
            }></Route>
            <Route path="/role" element={
              <AuthComponent><Role /></AuthComponent>
            }></Route>
            <Route path="/user" element={
              <AuthComponent><User /></AuthComponent>
            }></Route>
             <Route path="/dict" element={
              <AuthComponent><Dict /></AuthComponent>
            }></Route>
            <Route path="/logs" element={
              <AuthComponent><Logs /></AuthComponent>
            }></Route>
            <Route path="/module" element={
              <AuthComponent><Module /></AuthComponent>
            }></Route>
          </Route>
          <Route path="/login" element={<Login />}></Route>
        </Routes> */}
        {element}
      </div>
    // </BrowserRouter>
  );
}

export default App;

16、and table增加序号

{
      title: "序号",
      width: 70,
      render: (text, record, index) => `${index + 1}`,
    },

 17、吊用组件函数useRef ref  forwardRef useImperativeHandle 

const RoleFormComRef = useRef<any>(null)
 <RoleForm record={record} ref={RoleFormComRef} />
子组件
需要弹出的方法
function RoleForm({ record }, ref) {
useImperativeHandle(ref,
        () => ({
            getTableList,
            setPage
}))
}
export default   forwardRef(RoleForm )
父组件调用
TableRef?.current?.getTableList()
 
posted on 2023-07-13 09:23  不爱贞子爱爽子  阅读(28)  评论(0编辑  收藏  举报

! !