@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}], // 配置less
webpack: {
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跟组件下创建一级路由的出口
javascript
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接受数据的类型校验;
XML
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)
第三步 组件的完整写法:
XML
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)