SPA理解
- 单页web页面
- 整个应用只有一个完整的页面
- 点击页面中的链接不会刷新页面,只会做页面的局部更新
- 数据都需要通过ajax请求获取并在前端异步展示
路由概念
什么是路由
- 一个路由就是一个key-value映射关系
- key为如今,value可能是function也有可能是component
路由分类
- 后端路由
- value就是function,用来处理客户端提交的请求
- 注册路由:
router.get(path, function(req, res))
- 过程:当node接受到一个请求时,根据请求路径找到匹配路由,调用路由中的函数来处理请求,返回响应数据
- 前端路由
- 浏览器端路由,value就是component,用于展示页面了内容
- 注册路由:
<Router path='/test' component={test}
- 过程:当浏览器的path变为‘/test’时,当前路由组件就会变成Test组件
React-router-dom的理解
- react的一个插件库
- 专门用来实现一个SPA应用
- 基于react的项目基本都会用到此库
相关组件
<BrowserRouter>
用于包裹整个应用
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
<BrowserRouter>
<App />
</BrowserRouter>
);
<HashRouter>
作用和<BrowserRouter>
相同,但是<HashRouter>
修改的是hash值
<Navigate>
- 只要该标签被渲染就会立即修改路径,切换视图
- 其中的
replace
属性用于控制跳转模式(默认push,可改成replace)
import React,{useState} from 'react';
import {Navigate} from 'react-router-dom';
function About(props) {
const [sum, setSum] = useState(1);
return (
<div>
<h3>这是About内容</h3>
{sum === 1 ? <h4>sum的值为{sum}</h4> : <Navigate to="/home" replace={true}/> }
<button onClick={() => setSum(2)}>点我变成2</button>
</div>
);
}
export default About;
<NavLink>
关于<NavLink>
该标签的高亮问题,所谓实现高亮就是在属性上添加active
,但是并不是css框架的高亮都是active
属性或者需要自己自定义高亮,因此需要使用函数进行判断
function computedClassName({isActive}) {
return isActive ? "list-group-item active" : "list-group-item"
}
<NavLink to="/about" className={computedClassName}>About</NavLink>
<Routes/>与<Route/>
- 替换之前版本的
Switch
<Routes/>
与<Route/>
要配合使用,且必须要用<Routes/>
包含<Route/>
<Route/>
相当于一个if语句,如果其路径与当前URL匹配则呈现其对应的组件<Route caseSenstitive>
属性用于指定:匹配是否区分大小写,默认false- 当URL发生变化时,
<Routes/>
会查看其所有子<Route/>
元素以找到最佳匹配并呈现组件 <Route/>
也可以嵌套使用,且可配合useRoutes()
配置”路由表“,但需要通过<Outlet>
组件来渲染其子路由
路由表:
在项目中通常会创建routes
文件夹来存放项目所需的index路由文件
const routes = [
{
path: '/about',
element: <About/>
},
{
path: '/home',
element: <Home/>,
children: [
{
path: 'new',
element: <News/>
},
{
path: 'message',
element: <Messages/>
},
]
},
{
path: '/',
element: <Navigate to='/home'/>
}
];
export default routes;
渲染子路由的时候需要使用<Outlet>
组件来标识渲染的位置,类似VUE
注意的是,在子路由中使用
<NavLink>
组件的过程中,to
属性不需要/
,只需要直接写上子路由URL即可
<div>
<ul className="nav nav-tabs">
<li>
<NavLink to="new" className="list-group-item">News</NavLink>
<NavLink to="message" className="list-group-item">Messages</NavLink>
</li>
</ul>
<Outlet />
</div>
HOOKS
useRoutes()
根据路由表,动态创建Routes
和Route
const element = useRoutes(routes);
<div className="row">
<div className="col-xs-offset2 col-xs-2">
<div className="list-group">
<NavLink to="/about" className={computedClassName}>About</NavLink>
<NavLink to="/home" className="list-group-item">Home</NavLink>
</div>
</div>
<div className="col-xs-6">
<div className="panel">
<div className="panel-body">
{element}
</div>
</div>
</div>
</div>
useNavigate()
返回一个函数来实现编程式导航
const navigate = useNavigate();
const handle = () => {
// 指定具体的路径进行跳转
navigate('home', {
replace: false,
state: {a: 1, b: 2}
})
// 出入数值进行前进后退操作
navigate(-1);
};
useParams()
返回当前匹配路由的param
参数
function ProfilePage() {
let {id} = useParams();
}
function APP() {
return (
<Routes>
<Route path="users/:id" element={<User/>}></Route>
</Routes>
)
}
useSearchParams()
用于读取和修改当前位置的URL中的查询字符串
返回一个包含两个值的数组,分别是当前search函数和修改search函数
const [search, setSearch] = useSearchParams();
const id = search.get('id');
return (
<button onClick={() => setSearch('id=999&name=123')}>
更新
</button>
)
useLocation()
获取当前location信息