当前位置: 首页 > news >正文

React + Vite + TypeScript + React router项目搭建教程

一、创建项目

运行项目

二、目录结构

项目目录:
├─node_modules		//第三方依赖
├─public			//静态资源(不参与打包)
└─src├─assets		//静态资源├─components	//组件├─config		//配置├─http			//请求方法封装├─layout		//页面布局├─pages			//页面├─routes		//路由├─service		//请求├─store			//状态管理└─util			//通用方法└─App.css└─App.tsx└─index.css└─main.tsx└─vite-env.d.ts
├─.eslinttrc.cjs
├─.gitignore		
├─index.html		//项目页面总入口
├─package.json	
├─tsconfig.json		//ts配置文件
├─tsconfig.node.json
├─vite.config.ts	//vite配置文件

三、sass安装

1 安装

npm i sass -D

2 创建全局 scss 文件

3 引入

这里的additionalData改为

additionalData: `@import "./src/assets/styles/index.scss";`

4 修改这4个文件

index.css去掉

main.tsx 中 import './index.css' 去掉

app.css 变成 app.scss,内容只剩下,h1{ color:$red; }

app.tsx 代码如下

import './App.scss'function App() {return (<><h1>Vite + React</h1></>)
}export default App

sass成功,页面如下

四、写一个函数式组件和类组件

import './App.scss'// 函数式组件写法
// import React, { useState } from 'react';
// function Example() {
//   const [count, setCount] = useState(0);
//   return (
//     <div>
//       <p>You clicked {count} times</p>
//       <button onClick={() => setCount(count + 1)}>
//         Click me
//       </button>
//     </div>
//   );
// }// 类组件写法
import React from 'react';
class Example extends React.Component<any, any> {constructor(props: any) {super(props);this.state = {count: 0}}render() {return (<div><p>You clicked {this.state.count} times</p><button onClick={() => this.setState({ count: this.state.count + 1 })}>Click me</button></div>);}
}function App() {return (<><h1>Vite + React</h1><Example></Example></>)
}export default App

五、路由

1 下载

npm install react-router-dom -S

新建3个页面

HashRouter路由(vue中的hash模式)

main.tsx

import React from 'react'
import ReactDOM from 'react-dom/client'
import App from './App'
import { HashRouter as Router } from 'react-router-dom';ReactDOM.createRoot(document.getElementById('root') as HTMLElement).render(<React.StrictMode><Router><App /></Router></React.StrictMode>
)

app.tsx

import { Route, Routes, Link, useNavigate } from "react-router-dom";
import Login from "./pages/login";
import Home from "./pages/home";
import User from "./pages/user";
import './App.scss'function App() {const navigate = useNavigate();return (<div className="App">{/* 指定跳转的组件,to 用来配置路由地址 */}<Link to="/">首页</Link><br /><Link to="/user">用户</Link><br /><button onClick={() => navigate('/login')}> 登录 </button><hr />{/* 路由出口:路由对应的组件会在这里进行渲染 */}<Routes>{/* 指定路由路径和组件的对应关系:path 代表路径,element 代表对应的组件,它们成对出现 */}<Route path='/' element={<Home />}></Route><Route path='/user' element={<User />}></Route><Route path='/login' element={<Login />}></Route></Routes></div>)
}export default App

成功结果如下

BrowserRouter路由(vue中的history模式?)

main.tsx

import React from 'react'
import ReactDOM from 'react-dom/client'
import App from './App.tsx'
import { BrowserRouter as Router } from 'react-router-dom';ReactDOM.createRoot(document.getElementById('root') as HTMLElement).render(<React.StrictMode><Router><App /></Router></React.StrictMode>,
)

app.tsx

import { Route, Routes, Link, useNavigate } from "react-router-dom";
import Login from "./pages/login";
import Home from "./pages/home";
import User from "./pages/user";
import './App.scss'function App() {const navigate = useNavigate();return (<div className="App">{/* 指定跳转的组件,to 用来配置路由地址 */}<Link to="/">首页</Link><br /><Link to="/user">用户</Link><br /><button onClick={() => navigate('/login')}> 登录 </button><hr />{/* 路由出口:路由对应的组件会在这里进行渲染 */}<Routes>{/* 指定路由路径和组件的对应关系:path 代表路径,element 代表对应的组件,它们成对出现 */}<Route path='/' element={<Home />}></Route><Route path='/user' element={<User />}></Route><Route path='/login' element={<Login />}></Route></Routes></div>)
}export default App

嵌套路由

app.tsx

// 嵌套路由
import { Route, Routes, Link, useNavigate } from 'react-router-dom';
import Login from "./pages/login";
import Home from "./pages/home";
import User from "./pages/user";
import './App.scss'
function App() {const navigate = useNavigate();return (<div className="App">{/* 指定跳转的组件,to 用来配置路由地址 */}<Link to="/home">首页</Link><br /><Link to="/home/user">用户</Link><br /><button onClick={() => navigate('/home/login')}> 登录 </button>{/* 路由出口:路由对应的组件会在这里进行渲染 */}<Routes>{/* 指定路由路径和组件的对应关系:path 代表路径,element 代表对应的组件,它们成对出现 */}<Route path='/home' element={<Home />}><Route path='user' element={<User />}></Route><Route path='login' element={<Login />}></Route></Route></Routes></div>)
}
export default App

home.tsx

import { Outlet } from "react-router-dom";
function Home() {return (<div><div>home页面</div><Outlet /></div>);
}export default Home;

页面如下

重定向

import { Navigate } from 'react-router-dom';
<Route path='/' element={<Navigate to="/layout" />}></Route>

useRoutes路由配置

1 app.scss 

h1{color:$red;
}body{padding: 0;margin: 0;width: 100vw;height: 100vh;
}
#root{padding: 0;margin: 0;width: 100vw;height: 100vh;
}

app.tsx

import GetRoutes from "./routes/index";
import './App.scss'function App() {return (<GetRoutes></GetRoutes>)
}
export default App

home.tsx

function Home() {return (<div>home页面</div>);
}
export default Home;

新增文件

routes/index.tsx 代码如下

import { useRoutes, Navigate, RouteObject } from "react-router-dom";import Layout from "../layout/index";
import Login from "../pages/login";
import Home from "../pages/home";
import User from "../pages/user";export const router_item: Array<object> = [{ path: "/", label: "首页", element: <Navigate to="/layout/home" /> },{path: "/layout",label: "控制台",element: <Layout />,children: [{path: "home",label: "首页",element: <Home />},{path: "login",label: "登录页",element: <Login />,},{path: "user",label: "用户页",element: <User />},],},
];function GetRoutes() {const routes: RouteObject[] = useRoutes(router_item);return routes;
}export default GetRoutes;

layout/index.tsx 代码如下

import { Outlet, Link } from "react-router-dom";
function Layout() {return (<><div style={{display: 'flex', width: '100%', height: '100%'}}><div style={{width: '200px', background: '#eee'}}><Link to="/layout/home">home 页</Link><br /><Link to="/layout/login">login 页</Link><br /><Link to="/layout/user">user 页</Link><br /></div><div style={{flex: '1'}}><Outlet /></div></div></>);
}
export default Layout;

页面成功如下

路由懒加载

有些页面比较大,我们可以使用懒加载,来提升页面加载性能,避免页面卡顿;react官网提供了路由懒加载的完整实例:react路由懒加载。懒加载主要借助lazy、suspense组件来实现。

lazy 能够让你在组件第一次被渲染之前延迟加载组件的代码。<Suspense> 允许您显示临时组件(一般是一个loading状态),直到其子项完成加载。

修改 routes/index.tsx 代码如下

import { useRoutes, Navigate, RouteObject } from "react-router-dom";import Layout from "../layout/index";
import Login from "../pages/login";
import Home from "../pages/home";
import User from "../pages/user";import { lazy } from "react";
import lazyLoad from "./lazyLoad";
// 添加一个固定的延迟时间,以便你可以看到加载状态
function delayForDemo(promise: Promise<any>) {return new Promise(resolve => {setTimeout(resolve, 2000);}).then(() => promise);
}export const router_item: Array<object> = [{ path: "/", label: "首页", element: <Navigate to="/layout/home" /> },{path: "/layout",label: "控制台",element: <Layout />,children: [{path: "home",label: "首页",// element: <Home />element: lazyLoad(lazy(() => delayForDemo(import("../pages/home")))) //故意延迟2s,这里是延迟加载},{path: "login",label: "登录页",// element: <Login />,element: lazyLoad(lazy(() => import("../pages/login"))),	//这里是延迟加载},{path: "user",label: "用户页",element: <User />},],},
];function GetRoutes() {const routes: RouteObject[] = useRoutes(router_item);return routes;
}export default GetRoutes;

增加文件

lazyLoad.tsx 代码如下

import { LazyExoticComponent, Suspense } from "react";
import Spinner from "../components/spinner";
/*** 实现路由懒加载* @param Comp 懒加载组件* @returns */
function lazyLoad(Comp: LazyExoticComponent<() => JSX.Element>) {return (<Suspense fallback={<Spinner />}><Comp /></Suspense>);
}export default lazyLoad;

spinner.tsx 代码如下

function Spinner() {return (<>loading...</>);
}export default Spinner;

相关文章:

React + Vite + TypeScript + React router项目搭建教程

一、创建项目 运行项目 二、目录结构 项目目录&#xff1a; ├─node_modules //第三方依赖 ├─public //静态资源&#xff08;不参与打包&#xff09; └─src├─assets //静态资源├─components //组件├─config //配置├─http //请求方法封装├─layout //页面…...

【ShuQiHere】️ 如何启用 SSH 服务

&#x1f6e0;️ 如何启用 SSH 服务 目录 基础概念 &#x1f331;检查是否已安装 SSH 服务 &#x1f50d;在不同操作系统上安装 SSH 服务 &#x1f4bb; LinuxWindows 11macOS 启动和启用 SSH 服务 &#x1f680;配置防火墙以允许 SSH 连接 &#x1f525;配置 SSH 服务&#…...

【自动化测试】APP UI 自动化(安卓)-本地环境搭建

一、软件准备及版本介绍 软件版本JAVA-SDK1.8.0_181 python 3.10.10 Android SDK Tools 下最新版本即可&#xff0c;无特殊要求 PyCharm 2023.3.5&#xff08;下最新版本即可&#xff0c;无特殊要求&#xff09; 二、安装步骤及环境变量配置 2.1 Java安装及配置 1&am…...

java毕业设计之基于Bootstrap的常州地方旅游管理系统的设计与实现(springboot)

项目简介 基于Bootstrap的常州地方旅游管理系统的设计与实现有下功能&#xff1a; 基于Bootstrap的常州地方旅游管理系统的设计与实现的主要使用者分为用户功能模块和管理员功能模块两大部分&#xff0c;用户可查看景点信息、景点资讯等&#xff0c;注册登录后可进行景点订票…...

《机甲崛起》

第一章&#xff1a;觉醒 在遥远的未来&#xff0c;地球的面貌已被人类科技彻底改变。蓝天被高耸的摩天大楼和闪烁的飞行器撕裂&#xff0c;城市的光辉仿佛能照亮整个星球。然而&#xff0c;繁华背后隐藏着深重的危机&#xff1a;生态环境的恶化、资源的匮乏&#xff0c;已成为…...

Windows10:Linux Reader

Linux Reader Access files and folders on Ext, UFS, HFS, ReiserFS, or APFS file systems from Windows DiskInternals 发布的 Linux Reader 是一款能在 Windows 系统环境下读取 Linux 分区文件的免费软件&#xff0c;提供了资源管理器式的浏览模式。它使用只读模式挂载 L…...

一、k8s快速入门之学习Kubernetes组件基础

一、三个容器管理器平台 Apache MESOS 开源的分布式资源管理框架&#xff0c;被推特选为基础平台&#xff0c;2019年推特换位k8s&#xff0c;MESOS最新版可以在MESOS上管理k8sDOCKER SWARM docker总部发行的&#xff0c;实现docker的集群方案&#xff0c;和docker捆版一起&…...

PostgreSQL 到 PostgreSQL 数据迁移同步

简述 PostgreSQL 是一个历史悠久且广泛使用的数据库&#xff0c;不仅具备标准的关系型数据库能力&#xff0c;还具有相当不错的复杂 SQL 执行能力。用户常常会将 PostgreSQL 应用于在线事务型业务&#xff0c;以及部分数据分析工作&#xff0c;所以 PostgreSQL 到 PostgreSQL …...

RestTemplate 常用方法(提供了多种方法来发送 HTTP 请求)

RestTemplate 是 Spring 框架中用于同步客户端 HTTP 请求的一个类&#xff0c;它提供了多种方法来发送 HTTP 请求。以下是一些常用的 RestTemplate 方法及其代码案例&#xff1a; 1.postForObject() 该方法用于发送 POST 请求&#xff0c;并期望返回一个对象。以下是一个使用…...

常量和变量

常量 常量是指在程序中使用的一些具体的数、字符。在程序运行过程中&#xff0c;其值不能被更改。如123,145.88,m,TRUE等。常量&#xff0c;用于记录程序中不可更改的数据。 分类 1、整型常量&#xff0c;表示整数的常量。 表示形式&#xff1a;   1&#xff09;十进制形…...

Go语言的使用

在安装Go和配置镜像时&#xff0c;可以根据操作系统和网络环境来选择适合的步骤。以下是详细的安装步骤和镜像配置&#xff1a; 1. 安装Go 1.1 通过官方下载 访问 Go的官方下载页面 下载适合操作系统的安装包&#xff08;Windows、macOS 或 Linux&#xff09;。安装包下载完…...

详解CRC校验原理以及FPGA实现

文章目录 一、什么是CRC校验&#xff1f;二、实现CRC校验原理以及步骤2.1 用多项式表示二元码数据2.2 选择一个生成多项式作为校验2.3 计算CRC校验码 三、CRC判断数据是否错误的原理以及步骤3.1 将收到的数据与生成多项式求余3.2 数据发生错误再进行CRC校验判断 四、FPGA实现CR…...

企业如何通过架构蓝图实现数字化转型

数字化转型的关键——架构蓝图的力量 在当今的商业世界&#xff0c;数字化转型已经不再是一个选择&#xff0c;而是企业生存与发展不可回避的战略行动。企业希望通过数字化提高效率、增强灵活性&#xff0c;并为客户提供更好的体验。然而&#xff0c;数字化转型不仅仅涉及技术…...

React第十三章(useTransition)

useTransition useTransition 是 React 18 中引入的一个 Hook&#xff0c;用于管理 UI 中的过渡状态&#xff0c;特别是在处理长时间运行的状态更新时。它允许你将某些更新标记为“过渡”状态&#xff0c;这样 React 可以优先处理更重要的更新&#xff0c;比如用户输入&#x…...

IDEA使用Maven Helper查看整个项目的jar冲突

在插件市场安装Maven Helper&#xff0c;安装好后&#xff0c;重启IDEA&#xff1b;双击打开可能存在jar冲突的pom文件&#xff1b;在右侧面板查看冲突,text是引入的依赖明细&#xff0c;点击Dependecy Analyzer选项卡即可查看冲突的jar。...

uniapp项目 存储数据到手机本地

打开manifest.json&#xff0c;在App权限配置中&#xff0c;添加读取和写入的权限 <uses-permission android:name"android.permission.READ_EXTERNAL_STORAGE"/> <uses-permission android:name"android.permission.WRITE_EXTERNAL_STORAGE"/&g…...

景联文科技医疗数据处理平台:强化医疗数据标注与管理,推动医疗数字化新篇章

随着医疗科技快速进步与广泛应用&#xff0c;医疗信息的规模正在迅速扩张&#xff0c;如何有效管理这些医疗数据成为了关键议题。 医疗数据不仅包括传统的纸质病历&#xff0c;还有电子病历、实验室检测结果、医学影像等多样化的数字信息。为确保这些数据能为临床决策、科研分析…...

vue使用高德地图实现轨迹显隐

<template><div><el-button type"primary" click"pathShowOrHide">轨迹显/隐</el-button><div id"container" /></div> </template><script> import AMapLoader from amap/amap-jsapi-loaderex…...

Maven(20) 如何使用Maven进行版本管理?

Maven提供了一套强大的版本管理机制&#xff0c;允许开发者管理项目的版本号&#xff0c;并在不同的版本之间进行升级和降级。以下是如何使用Maven进行版本管理的详细步骤和代码示例&#xff1a; 步骤 1: 定义项目版本 在pom.xml文件中&#xff0c;你需要定义项目的版本号。版…...

AWS RDS MySQL内存使用

1. AWS RDS所拥有的内存&#xff08;实例类型&#xff09;&#xff0c;和数据库能够使用的内存是不同的。RDS实例为操作系统和 RDS 管理进程预留了内存&#xff0c;数据库使用内存大小&#xff0c;小于数据库实例类的硬件规格中所示的值&#xff08;以 GiB 为单位&#xff09;[…...

以太网PHY布局布线指南

1. 简介 对于以太网布局布线遵循以下准则很重要&#xff0c;因为这将有助于减少信号发射&#xff0c;最大程度地减少噪声&#xff0c;确保器件作用&#xff0c;最大程度地减少泄漏并提高信号质量。 2. PHY设计准则 2.1 DRC错误检查 首先检查DRC规则是否设置正确&#xff0c;然…...

更新 Docker 容器中的某一个文件

&#x1f504; 如何更新 Docker 容器中的某一个文件 以下是几种在 Docker 中更新单个文件的常用方法&#xff0c;适用于不同场景。 ✅ 方法一&#xff1a;使用 docker cp 拷贝文件到容器中&#xff08;最简单&#xff09; &#x1f9f0; 命令格式&#xff1a; docker cp <…...

代理服务器-LVS的3种模式与调度算法

作者介绍&#xff1a;简历上没有一个精通的运维工程师。请点击上方的蓝色《运维小路》关注我&#xff0c;下面的思维导图也是预计更新的内容和当前进度(不定时更新)。 我们上一章介绍了Web服务器&#xff0c;其中以Nginx为主&#xff0c;本章我们来讲解几个代理软件&#xff1a…...

PCA笔记

✅ 问题本质&#xff1a;为什么让矩阵 TT 的行列式为 1&#xff1f; 这个问题通常出现在我们对数据做**线性变换&#xff08;旋转/缩放&#xff09;**的时候&#xff0c;比如在 PCA 中把数据从原始坐标系变换到主成分方向时。 &#x1f4cc; 回顾一下背景 在 PCA 中&#xff…...

JavaWeb:前端工程化-Vue

Vue工程化 介绍 什么是Vue? 小白眼里前端开发 前端工程化 环境准备 D:\Program Files\nodejs Vue项目-快速入门 步骤 D:\front\vue 安装依赖 目录结构 code . vscode打开 启动 VScode侧边栏左下角&#xff0c;没有NPM脚本&#xff0c;如何打开&#xff1f;&…...

用 Lazarus IDE 写一个邮件客户端软件,能收发邮件,编写邮件

下面是一个使用Lazarus IDE开发的基本邮件客户端实现方案&#xff0c;包含收发邮件和编写邮件的核心功能。我们将使用Synapse库&#xff08;跨平台的网络通信库&#xff09;来处理邮件协议。 步骤1&#xff1a;安装依赖 安装Synapse库&#xff1a; 下载地址&#xff1a;https:…...

CSS 轮廓(Outline)与边框(Border)的深度解析

在 CSS 中&#xff0c;轮廓&#xff08;outline&#xff09;和边框&#xff08;border&#xff09;是两个用于装饰元素的重要属性&#xff0c;但它们在功能、渲染机制和应用场景上存在显著差异。下面从多个维度进行详细对比&#xff1a; 一、基础定义与语法差异 边框&#xf…...

【Zephyr 系列 15】构建企业级 BLE 模块通用框架:驱动 + 事件 + 状态机 + 低功耗全栈设计

🧠关键词:Zephyr、BLE 模块、架构设计、驱动封装、事件机制、状态机、低功耗、可维护框架 📌面向读者:希望将 BLE 项目从“Demo 工程”升级为“企业可复用框架”的研发人员与技术负责人 📊预计字数:5500+ 字 🧭 前言:从 Demo 到产品化,架构该如何升级? 多数 BLE…...

uniapp Vue2 获取电量的独家方法:绕过官方插件限制

在使用 uniapp 进行跨平台应用开发时&#xff0c;获取设备电量信息是一个常见的需求。然而&#xff0c;uniapp 官方提供的uni.getBatteryInfo方法存在一定的局限性&#xff0c;它不仅需要下载插件&#xff0c;而且目前仅支持 Vue3&#xff0c;这让使用 Vue2 进行开发的开发者陷…...

AI Agent 架构设计:ReAct 与 Self-Ask 模式对比与分析

一、引言 (一) AI Agent 技术发展背景 &#x1f680; AI Agent 的演进是一场从“遵循指令”到“自主决策”的深刻变革。早期&#xff0c;以规则引擎为核心的系统&#xff08;如关键词匹配的客服机器人&#xff09;只能在预设的流程上运行。然而&#xff0c;大语言模型的崛起为…...