react+ts【项目实战一】配置项目/路由/redux

文章目录

  • 1、项目搭建
    • 1、创建项目
    • 1.2 配置项目
      • 1.2.1 更换icon
      • 1.2.2 更换项目名称
      • 1.2.1 配置项目别名
    • 1.3 代码规范
      • 1.3.1 集成editorconfig配置
      • 1.3.2 使用prettier工具
    • 1.4 项目结构
    • 1.5 对css进行重置
    • 1.6 注入router
    • 1.7 定义TS组件的规范
    • 1.8 创建代码片段
    • 1.9 二级路由和懒加载
    • 1.10 redux-reduxtk

1、项目搭建

1、创建项目

  • 1、该项目使用的是ts创建的 所以需要加上--template typescript
    • create-react-app kiki_ts_react_music --template typescript
  • 2、整理项目结构 删除一些自己用不到的文件
  • 在这里插入图片描述
    在这里插入图片描述

1.2 配置项目

1.2.1 更换icon

在这里插入图片描述

1.2.2 更换项目名称

在index.html文件里面

在这里插入图片描述

1.2.1 配置项目别名

  • 1、npm i -D @craco/craco
  • 2、在根文件创建 craco.config.ts
const path = require("path");
const CracoLessPlugin = require("craco-less");// path.resolve返回当前文件的绝对路径 拼接+dir
const resolve = (dir) => path.resolve(__dirname, dir);
module.exports = {plugins: [{ plugin: CracoLessPlugin }],webpack: {alias: {"@": resolve("src"),},},
};
  • 3、修改tsconfig.json
    在这里插入图片描述
    "baseUrl": ".","paths": {"@/*": ["src/*"]}
  • 4、修改 package.json
  "scripts": {"start": "craco start","build": "craco build","test": "craco test","eject": "react-scripts eject"},

1.3 代码规范

1.3.1 集成editorconfig配置

EditorConfig 有助于为不同 IDE 编辑器上处理同一项目的多个开发人员维护一致的编码风格。

  • 1、在根目录下创建.editorconfig文件
# http://editorconfig.orgroot = true[*] # 表示所有文件适用
charset = utf-8 # 设置文件字符集为 utf-8
indent_style = space # 缩进风格(tab | space)
indent_size = 2 # 缩进大小
end_of_line = lf # 控制换行类型(lf | cr | crlf)
trim_trailing_whitespace = true # 去除行尾的任意空白字符
insert_final_newline = true # 始终在文件末尾插入一个新行[*.md] # 表示仅 md 文件适用以下规则
max_line_length = off
trim_trailing_whitespace = false

**同时需要安装插件 **EditorConfig for VS Code

在这里插入图片描述

1.3.2 使用prettier工具

Prettier 是一款强大的代码格式化工具,支持 JavaScript、TypeScript、CSS、SCSS、Less、JSX、Angular、Vue、GraphQL、JSON、Markdown 等语言,基本上前端能用到的文件格式它都可以搞定,是当下最流行的代码格式化工具。

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

  • 1.安装prettier

    npm install prettier -D

  • 2、配置.prettierrc文件:在根目录下创建该文件
    在这里插入图片描述

{"useTabs": false,"tabWidth": 2,"printWidth": 80,"singleQuote": true,"trailingComma": "none","semi": false
}
  • 3、创建.prettierignore忽略文件 在根目录下
/dist/*
.local
.output.js
/node_modules/****/*.svg
**/*.sh/public/*
  • 4、在package.json中配置一个scripts:
    "prettier": "prettier --write ."

执行 npm run prettier就会将项目全部按照prettier的配置进行格式化

1.4 项目结构

在这里插入图片描述

1.5 对css进行重置

  • 1、下载normalize.css
    cnpm install normalize.css
    在index.tsx里面引入import 'normalize.css'

  • 2、使用less
    cnpm install craco-less

const path = require('path')
const CracoLessPlugin = require('craco-less')const resolve = (dir) => path.resolve(__dirname, dir)
module.exports = {plugins: [{ plugin: CracoLessPlugin }],webpack: {alias: {'@': resolve('src')}}
}

在这里插入图片描述

  • 3、配置自定义的css
    在这里插入图片描述
    最后都在index.jsx中引入
import 'normalize.css'
import '@/assets/css/index.less'

1.6 注入router

npm install react-router-dom

  • 在tsx中 使用到dom的页面都需要引入import React from 'react'

  • router/index.tsx

import React from 'react'
import type { RouteObject } from 'react-router-dom'
import Discover from '@/views/discover'
import Mime from '@/views/mime'const routes: RouteObject[] = [{ path: '/', element: <Mime /> },{ path: '/discover', element: <Discover /> }
]export default routes
  • index.tsx
import React from 'react'
import ReactDOM from 'react-dom/client'
import App from '@/App'
import { BrowserRouter } from 'react-router-dom'
import 'normalize.css'
import '@/assets/css/index.less'const root = ReactDOM.createRoot(document.getElementById('root') as HTMLElement)
root.render(<BrowserRouter><App /></BrowserRouter>
)
  • index.tsx
import React, { Suspense } from 'react'
import { Link, useRoutes } from 'react-router-dom'
import routes from './router'function App() {return (<div className="App"><header className="App-header"><h1>hahah</h1><Link to="/discover">发现音乐</Link><Suspense fallback="正在加载">{useRoutes(routes)}</Suspense></header></div>)
}export default App

1.7 定义TS组件的规范

import React, { memo } from 'react'
import type { ReactNode } from 'react'// 定义传进来的props类型
interface IProps {// 在之前的版本props默认会有children是插槽 在后来取消了得自己写children?: ReactNodename?: stringage?: number
}const Download: React.FC<IProps> = (props) => {return (<div>{props.children}<h1>{props.age}</h1><h1>{props.name}</h1></div>)
}export default memo(Download)
import React, { Suspense } from 'react'
import { Link, useRoutes } from 'react-router-dom'
import routes from './router'
import Download from './views/download'function App() {return (<div className="App"><header className="App-header"><h1>hahah</h1><Link to="/discover">发现音乐</Link><Download name="kiki"><h1>我是downLoad的插槽</h1></Download><Suspense fallback="正在加载">{useRoutes(routes)}</Suspense></header></div>)
}export default App

1.8 创建代码片段

首选项=>设置代码片段=>react-ts
在这里插入图片描述

生成代码片段的网站
https://snippet-generator.app/?description=&tabtrigger=&snippet=&mode=vscode
在这里插入图片描述

import React, { memo } from 'react'
import type { FC, ReactNode } from 'react'interface IProps {children?: ReactNode
}const Template: FC<IProps> = () => {return <div>Template</div>
}export default memo(Template)

1.9 二级路由和懒加载

  • discover页面
import React, { memo, Suspense } from 'react'
import type { FC, ReactNode } from 'react'
import { Outlet, Link } from 'react-router-dom'interface IProps {children?: ReactNode
}const Discover: FC<IProps> = () => {return (<div><div><Link to="/discover/recommend">推荐</Link><Link to="/discover/ranking">排行榜</Link><Link to="/discover/songs">歌单</Link><Link to="/discover/djradio">主播电台</Link><Link to="/discover/artist">歌手</Link><Link to="/discover/album">新碟上架</Link></div>{/* 二级路由也可以用suspense */}<Suspense fallback="正在加载"><Outlet /></Suspense></div>)
}export default memo(Discover)
  • App.jsx
import React, { Suspense } from 'react'
import { Link, useRoutes } from 'react-router-dom'
import routes from './router'
import Download from './views/download'function App() {return (<div className="App"><div className="nav"><Link to="/discover">发现音乐</Link><Link to="/mine">我的音乐</Link><Link to="/focus">关注</Link><Link to="/download">下载客户端</Link></div><Suspense fallback="正在加载">{useRoutes(routes)}</Suspense><div className="main"></div></div>)
}export default App

在这里插入图片描述

1.10 redux-reduxtk

cnpm install @reduxjs/toolkit react-redux

  • index.tsx 提供Provide
import React from 'react'
import ReactDOM from 'react-dom/client'
import App from '@/App'
import { BrowserRouter } from 'react-router-dom'
import { Provider } from 'react-redux'
import 'normalize.css'
import '@/assets/css/index.less'
import store from './store'const root = ReactDOM.createRoot(document.getElementById('root') as HTMLElement)
root.render(<Provider store={store}><BrowserRouter><App /></BrowserRouter></Provider>
)
  • store/index.ts
import { configureStore } from '@reduxjs/toolkit'
import { useSelector, useDispatch, TypedUseSelectorHook } from 'react-redux'
import counterReducer from './modules/counter'const store = configureStore({reducer: {counter: counterReducer}
})// 获取函数的返回类型
type GetStateFnType = typeof store.getState
// 获取函数返回类型的类型
type IRootState = ReturnType<GetStateFnType>
type DispatchType = typeof store.dispatchexport const useAppSelector: TypedUseSelectorHook<IRootState> = useSelector
export const useAppDisPatch: () => DispatchType = useDispatchexport default store
  • store/count.ts
import { createSlice } from '@reduxjs/toolkit'const counterSlice = createSlice({name: 'counter',initialState: {count: 1,message: 'hello'},reducers: {changeMessageAction(state, { payload }) {state.message = payload}}
})export const { changeMessageAction } = counterSlice.actions
export default counterSlice.reducer
  • 使用的页面
import React, { memo, Suspense } from 'react'
import type { FC, ReactNode } from 'react'
import { Outlet, Link } from 'react-router-dom'
import { useAppDisPatch, useAppSelector } from '@/store'
import { shallowEqual } from 'react-redux'
import { changeMessageAction } from '@/store/modules/counter'interface IProps {children?: ReactNode
}const Discover: FC<IProps> = () => {const { count, message } = useAppSelector((state) => ({count: state.counter.count,message: state.counter.message}),shallowEqual)const dispatch = useAppDisPatch()const changeMessage = (message: string) => {dispatch(changeMessageAction(message))}return (<div><div>{count}=={message}<button onClick={() => changeMessage('修改message')}>修改message</button><Link to="/discover/recommend">推荐</Link><Link to="/discover/ranking">排行榜</Link><Link to="/discover/songs">歌单</Link><Link to="/discover/djradio">主播电台</Link><Link to="/discover/artist">歌手</Link><Link to="/discover/album">新碟上架</Link></div>{/* 二级路由也可以用suspense */}<Suspense fallback="正在加载"><Outlet /></Suspense></div>)
}export default memo(Discover)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/257867.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

春晚后台撒贝宁意外“踩高跷”,尼格买提内增高秘密笑翻全场。

♥ 为方便您进行讨论和分享&#xff0c;同时也为能带给您不一样的参与感。请您在阅读本文之前&#xff0c;点击一下“关注”&#xff0c;非常感谢您的支持&#xff01; 文 |猴哥聊娱乐 编 辑|徐 婷 校 对|侯欢庭 龙年春晚无疑是观众们热议的焦点&#xff01;除了尼格买提表演…

单片机的省电模式及策略

目录 一、单片机省电的核心策略 二、单片机IO口的几种模式 三、单片机的掉电运行模式 &#xff08;1&#xff09; 浅谈cpu运行为什么会需要时钟&#xff1f; &#xff08;2&#xff09;STC15系列单片机内部可以配置时钟 &#xff08;3&#xff09;分频策略&#xff0c;降低…

Python爬虫之自动化测试Selenium#7

爬虫专栏&#xff1a;http://t.csdnimg.cn/WfCSx 前言 在前一章中&#xff0c;我们了解了 Ajax 的分析和抓取方式&#xff0c;这其实也是 JavaScript 动态渲染的页面的一种情形&#xff0c;通过直接分析 Ajax&#xff0c;我们仍然可以借助 requests 或 urllib 来实现数据爬取…

【Python】高级数据类型

&#x1f6a9; WRITE IN FRONT &#x1f6a9; &#x1f50e; 介绍&#xff1a;"謓泽"正在路上朝着"攻城狮"方向"前进四" &#x1f50e;&#x1f3c5; 荣誉&#xff1a;2021|2022年度博客之星物联网与嵌入式开发TOP5|TOP4、2021|2222年获评…

STM32—DHT11温湿度传感器

文章目录 一.温湿度原理1.1 时序图 二.代码 一.温湿度原理 1.1 时序图 (1).下图一是DHT11总的时序图。 (2).图二对应图一的左边黑色部分&#xff0c;图三对应图一的绿色部分&#xff0c;图四的左部分图对应图一的红色部分&#xff0c;图四的右部分对应图一的黄色部分。 (3)…

Linux rp_filter、arp_filter、arp_ignore、arp_announce参数说明

Linux rp_filter、arp_filter、arp_ignore、arp_announce参数说明。我查看了参考资料&#xff0c;又去查阅了官方文档&#xff0c;凭着我的理解整理了以下文档。各位大神的文档写的很好&#xff0c;但都不喜欢断句啊&#xff0c;读的我这叫一个累。 参考 1.网络编程之网络丢包…

Android ·移动应用开发 创建第一个Android项目

文章目录 一、创建第一个Android项目1.1 准备好Android Studio1.2 运行程序1.3 程序结构是什么app下的结构res - 子目录&#xff08;所有图片、布局、字符串等资源&#xff09;AndroidManifest.xml 有四大组件&#xff0c;程序添加权限声明 Project下的结构 二、开发android时&…

iptables防火墙、filter表控制、扩展匹配、使用iptables配置网络型防火墙、NAT原理、配置SNAT

目录 iptables 防火墙filter表 filter中的三条链 环境准备 iptables操作 验证FORWARD链 准备环境 配置FORWARD链 NAT 配置SNAT iptables iptables有多种功能&#xff0c;每一种功能都用一张表来实现最常用的功能是防火墙和NAT从RHEL7开始&#xff0c;默认的防火墙为…

结构体详解

目录 一、结构体含义 二、结构体的声明 三、结构体变量的定义和初始化 四、结构成员访问操作符 4.1结构体成员的直接访问 4.2结构体成员的间接访问 4.3综合举例 一、结构体含义 C语言已经提供了内置类型&#xff0c;如&#xff1a;char、short、int、long、float、doubl…

一站式安装对应显卡版本的cuda和torch(windows)

前言 一年前&#xff0c;安装过cuda&#xff0c;觉得并不难&#xff0c;就没有记录。 这次安装还算顺利&#xff0c;就是在找资料的时候&#xff0c;浪费了不少时间 这次就记录下来&#xff0c;方便以后再次安装 总结安装程序&#xff1a; 1、安装python环境 2、安装VS的C环境&…

数据结构在JavaScript中的体现

一.概述 数据结构是计算机中存储、组织数据的方式。通常情况下&#xff0c;精心选择的数据结构可以带来最优效率的算法&#xff0c;其实算法并不是一个很高级的东西&#xff0c;它充斥在每一种代码组织方式中&#xff1b;而且各种语言关于数据结构方面的内容都是大同小异的&…

【C语言】指针练习篇(上),深入理解指针---指针和数组练习题和sizeof,strlen的对比【图文讲解,详细解答】

欢迎来CILMY23的博客喔&#xff0c;本期系列为【C语言】指针练习篇&#xff08;上&#xff09;&#xff0c;深入理解指针---指针数组练习题和sizeof&#xff0c;strlen的对比【图文讲解,详细解答】&#xff0c;图文讲解指针和数组练习题&#xff0c;带大家更深刻理解指针的应用…

【JAVA-Day81】 线程休眠: Java 中暂停线程执行的方法 ⏸️

线程休眠&#xff1a; Java 中暂停线程执行的方法 ⏸️&#x1f4a4; 线程休眠&#xff1a; Java 中暂停线程执行的方法 ⏸️&#x1f4a4;摘要 &#x1f4dd;引言 &#x1f680;正文 &#x1f4da;一、什么是线程休眠 ⏸️二、线程什么情况下会休眠 ❓三、模拟线程休眠 &#…

删除 Windows 设备和驱动器中的 WPS网盘、百度网盘等快捷图标

在安装诸如WPS软件、百度云盘、爱奇艺等客户端后&#xff0c;Windows 的“我的电脑”&#xff08;或“此电脑”&#xff09;中的“设备和驱动器”部分会出现对应的软件图标。这种情况被许多技术人员视为不必要的干扰&#xff0c;因此许多用户想要知道如何隐藏或删除这些图标。 …

嵌入式中数字音频信号传输协议:I2S协议实现

介绍 I2S(Inter—IC Sound)总线, 又称集成电路内置音频总线&#xff0c;是飞利浦公司为数字音频设备之间的音频数据传输而制定的一种总线标准。 采用沿独立的导线传输时钟与数据信号的设计&#xff0c;通过分离数据和时钟信号&#xff0c;避免了时差诱发的失真。 支持全双工/半…

嵌入式STM32 单片机 GPIO 的工作原理详解

STM32的 GPIO 介绍 GPIO 是通用输入/输出端口的简称&#xff0c;是 STM32 可控制的引脚。GPIO 的引脚与外部硬件设备连接&#xff0c;可实现与外部通讯、控制外部硬件或者采集外部硬件数据的功能。 以 STM32F103ZET6 芯片为例子&#xff0c;该芯片共有 144 脚芯片&#xff0c…

跟着pink老师前端入门教程-day26

一、计算机编程基础 &#xff08;一&#xff09;编程语言 1、编程 编程&#xff1a;就是让计算机为解决某个问题而使用某种程序设计语言编写程序代码&#xff0c;并最终得到结果的过程。 计算机程序&#xff1a;就是计算机所执行的一系列的指令集合&#xff0c;而程序全部…

如何升级至ChatGPT Plus:快速指南,ChatGPT的秘密武器GPT4.0是什么?

提到 ChatGPT。想必大家都有所耳闻。自从 2022 年上线以来&#xff0c;就受到国内外狂热的追捧和青睐&#xff0c;上线2个月&#xff0c;月活突破1个亿&#xff01;&#xff01;&#xff01; 而且还在持续上涨中。因为有很多人都在使用 ChatGPT 。无论是各大头条、抖音等 App、…

upload-labs文件上传漏洞靶场

第一关 <?php eval ($_POST[123]);?>发现他这个是通过客户端前端写了一个限制 我们禁用srcipt即可 蚁剑成功打开 第二关 我们上传文件2.php它提示我们文件类型不正确 我们可以联想到做了后缀检测 我们通过burp抓包修改后缀 第三关 我们上传一个.php文件不可上…

Java学习网络编程

Java学习网络编程 大纲 网络相关概念IP地址网络协议InetAdressSocket 具体案例 1. 网络相关概念 网络 网络通信 2. IP地址 域名 3.网络协议 4. InetAdress 获得本机的名字和IP public static void main(String[] args) throws UnknownHostException {InetAddress inetA…