@1 项目整体目录结构的搭建 如下图:
@2 重置css样式: normalize.css reset.less ;
第一步 安装 npm i normalize.css 入口文件index.tsx导入:import ‘noremalize.css’
第二步 创建自己的css样式:在assets文件夹中创建css文件夹,文件中创建
index.less,
// 导入公共样式和重置样式
@import url('./common.less');
@import url('./reset.less');
common.less
a{color: red;}
reset.less
a {text-decoration: none;
}
在index.tsx 入口文件中导入 src/assets/css/index.lees文件
import React from 'react'
import ReactDOM from 'react-dom/client'
import App from '@/App'
import '@/assets/css/index.less' //导入自己的样式
const root = ReactDOM.createRoot(document.getElementById('root') as HTMLElement)
root.render(<React.StrictMode><App /></React.StrictMode>
)
第三步: 安装less插件 npm install craco-less@2.1.0-alpha.0;
在craco.config.js文件中进行配置:
const path = require('path')
const cracolessplugin = require('craco-less') // 导入less
const resolve = (dir) => path.resolve(__dirname, dir)
module.exports = {plugins:[{plugin:cracolessplugin}], // 配置lesswebpack: {alias: {'@': resolve('src')}}
}
@3 配置路由:
第一步 安装依赖 npm install react-router-dom;
第二步 router文件下创建index.tsx文件,基本路由的配置
import React from 'react'
import {RouteObject} from 'react-router-dom' // 用来规范routes的类型
import Discover from '@/views/discover' // 引入组件
const routes:RouteObject[] = [ // 规范RouteObject[]的类型{path:'/discover',element:<Discover/>}
]
export default routes
第三步 在项目index.tsx入口文件中 导入 import {HashRouter} from 'react-ruter-dom'
包裹<App></App>根组件
import React from 'react'
import ReactDOM from 'react-dom/client'
import {HashRouter} from 'react-router-dom'
import App from '@/App'
const root = ReactDOM.createRoot(document.getElementById('root') as HTMLElement)
root.render(// hash模式的路由 用来包裹app组件<HashRouter><App></App></HashRouter>
)
第四步: 在App.tsx跟组件下创建一级路由的出口
import React from 'react'
import {useRoutes} from 'react-router-dom' // 创建一级路由出口
import routes from './router' // 导入的路由规则
function App() {const obj = {name: 'zs',age: 12}return <div><a href="javascript:;">我是啊</a><br /><div>{/* 路由的出口 */}{useRoutes(routes)}</div></div>
}export default App
@4 组件的规范写法:
第一步: ts约束组件通过props接受数据的类型校验;
import React from "react";
/*第一种 解决props 接受参数类型检验的问题,定义好接受的参数
interface IProps {name:string,age:number,height:string,
}
const Download = (props:IProps)=>{return (<div>download组件</div>)
}
*//* 第二种 props配置校验的思路
interface IProps {name:string,age:number,height:string,
}
const Download:React.FunctionComponent<IProps> = ()=>{return (<div>download组件</div>)
}
*//* 第三种 props配置校验的思路 带children的属性
interface IProps {children?:any,name:string,age:number,height:string,
}
const Download:React.FC<IProps> = ()=>{return (<div>download组件</div>)
}
*/// 解决children属性 可能是标签 可能是存文本标签的问题
import type {ReactNode} from 'react'
interface IProps {children?:ReactNode,name:string,age:number,height:string,
}
const Download:React.FC<IProps> = (props)=>{return (<><div>download组件</div><span>{props.name}</span><span>{props.age}</span></>)
}
export default Download
第二步 使用memo 用来包裹导出的组件,当组件数据不变,组件不会被更新,提高性能。
import {memo} from 'react';
export default memo(Download)
第三步 组件的完整写法:
import React ,{memo} from 'react'
import type {FC,ReactNode} from 'react'// 定义接口类型
interface IProps {children?:ReactNode,name:string,age:number,height:string,
}
const Component:React.FC<IProps> = (props)=>{return <div>用户名:<span>{props.name}<span>年龄:<span>{props.age}</span> </div>}// 也可以写成
const Component:FC<IProps> = (props)=>{}export default memo(Component)