1.Link和NavLink的区别
NavLink比Link多了一个class=“active”, 可以在App.css为他们设置样式
function App() {
return (
<Router>
<div className="App">
<ul>
<li>
{/*1️⃣ Link
<Link exact to="/">首页</Link> */}
{/* 2️⃣ NavLink*/}
<NavLink exact to="/">首页</NavLink>
</li>
<li>
<NavLink to="/list?t=ttt">列表</NavLink>
</li>
<li>
<NavLink to="/people/oooo">People</NavLink>
</li>
</ul>
<hr />
<div className="content">
<Switch>
{/* 如果不加exact的话 每个页面都会有/那么每个页面都会有Home页这个内容 */}
<Route path="/" exact component={Home}></Route>
{/* <Route path="/list" component={List}></Route>
<Route path="/people" component={People}></Route>
*/}
{/* 因为希望list、people这两个页面是在登陆之后才可以访问的,所以可以加上私有路由 也就是将Route改成PrivateRoute */}
<PrivateRoute path="/list" component={List}></PrivateRoute>
<PrivateRoute path="/people/:o" component={People}></PrivateRoute>
<Route path="/about" render={() => <About />}></Route>
<Route path="/login" render={() => <Login />}></Route>
</Switch>
</div>
</div>
</Router>
);
}
2.params传参和链接传参
function App() {
return (
<Router>
<div className="App">
<ul>
<li>
{/* <Link exact to="/">首页</Link> */}
<NavLink exact to="/">首页</NavLink>
</li>
<li>
{/* 1️⃣ path="/list" */}
<NavLink to="/list?t=ttt">列表</NavLink>
</li>
<li>
{/* 2️⃣ path="/list" */}
<NavLink to="/people/oooo">People</NavLink>
</li>
</ul>
<hr />
<div className="content">
<Switch>
{/* 如果不加exact的话 每个页面都会有/那么每个页面都会有Home页这个内容 */}
<Route path="/" exact component={Home}></Route>
{/* <Route path="/list" component={List}></Route>
<Route path="/people" component={People}></Route>
*/}
{/* 因为希望list、people这两个页面是在登陆之后才可以访问的,所以可以加上私有路由 也就是将Route改成PrivateRoute */}
{/* 1️⃣ path="/list" */}
<PrivateRoute path="/list" component={List}></PrivateRoute>
{/* 2️⃣ path="/list" */}
<PrivateRoute path="/people/:o" component={People}></PrivateRoute>
<Route path="/about" render={() => <About />}></Route>
<Route path="/login" render={() => <Login />}></Route>
</Switch>
</div>
</div>
</Router>
);
}
接收参数
// 1️⃣ <NavLink to="/list?t=ttt">列表</NavLink>
console.log(props);
// 路由组件中会包含
// history
// location
// match
// 此处可以使用new URLSearchParams获取当前查询条件
// 使用模块qs也能获取查询条件
const params = new URLSearchParams(props.location.search);
console.log(params.get("t"));
// 2️⃣ <PrivateRoute path="/people/:o" component={People}></PrivateRoute>
// 以下两种写法一样
console.log(props.match.params); // {o: "oooo"}
console.log(useParams()); // {o: "oooo"}
3.Link跳转 和 编程式跳转props.history.push
import React from "react";
// import { BrowserRouter as Router, Route, Link } from "react-router-dom"; 不建议使用浏览器历史记录路由BrowserRouter
import {
HashRouter as Router,
Route,
// Link,
// withRouter,
NavLink,
// BrowserRouter,
Switch,
} from "react-router-dom";
import "./App.css";
import People from "./pages/People";
import { Button } from "antd";
import List from "./pages/List";
import About from "./pages/About";
import Login from "./pages/Login";
import PrivateRoute from "./pages/PrivateRoute";
const Home = (props) => {
const { history } = props;
return (
<div>
<h1>我是首页</h1>
{/* 1️⃣ props.history.push('/xx') */}
<Button onClick={() => history.push("/list")}>列表页</Button>
<Button onClick={() => history.push("/about")}>关于我们</Button>
</div>
);
};
/* const About = (props) => {
console.log(props);
return <h1>有什么有什么要联系我们的吗,欢迎您哦</h1>;
};
const AboutPage = withRouter(About); */
function App() {
return (
<Router>
<div className="App">
<ul>
<li>
{/* 2️⃣ <Link to='/xx' > */}
{/* <Link exact to="/">首页</Link> */}
<NavLink exact to="/">
首页
</NavLink>
</li>
<li>
<NavLink to="/list?t=ttt">列表</NavLink>
</li>
<li>
<NavLink to="/people/oooo">People</NavLink>
</li>
</ul>
<hr />
<div className="content">
<Switch>
{/* 如果不加exact的话 每个页面都会有/那么每个页面都会有Home页这个内容 */}
<Route path="/" exact component={Home}></Route>
{/* <Route path="/list" component={List}></Route>
<Route path="/people" component={People}></Route>
*/}
{/* 因为希望list、people这两个页面是在登陆之后才可以访问的,所以可以加上私有路由 也就是将Route改成PrivateRoute */}
<PrivateRoute path="/list" component={List}></PrivateRoute>
<PrivateRoute path="/people/:o" component={People}></PrivateRoute>
<Route path="/about" render={() => <About />}></Route>
<Route path="/login" render={() => <Login />}></Route>
</Switch>
</div>
</div>
</Router>
);
}
export default App;
4.withRouter
用到PrivateRoute和render路由形式的 都需要用到withRouter
// 此处为高阶组件
// 其实就是js中的高阶函数
// withRouter是一个函数,接收一个组件作为参数,为组件添加一些路由属性信息
const AboutPage = withRouter(About);
5.用私有路由PrivateRoute需要加Switch
<div className="container">
{/* 1️⃣Switch 只会匹配一个路由内容 ,PrivateRoute就可以用了,如果不加Switch,所有的就会都走一遍而产生冲突导致报错*/}
<Switch>
<Route path="/login" render={() => <Login />} />
{/* exact 表示完全匹配 */}
<Route path="/" exact component={Home} />
<PrivateRoute path="/list">
<List />
</PrivateRoute>
<PrivateRoute path="/p/:o">
<People />
</PrivateRoute>
{/* render方式渲染组件,没有直接使用component指定组件
这时候在路由对应的组件中没有history和location等路由的属性信息
*/}
<Route path="/about" render={() => <About />} />
</Switch>
</div>
6.需要给主的Link和Route添加exact,用来完全匹配
如果不加exact的话 每个页面都会有/那么每个页面都会有Home页这个内容
function App() {
return (
<Router>
<div className="App">
<ul>
<li>
<NavLink exact to="/" isActive={() => true}>
首页
</NavLink>
</li>
<li>
<NavLink to="/list?t=cart">列表</NavLink>
</li>
<li>
<NavLink to="/p/oooo">People</NavLink>
</li>
</ul>
<hr />
{/* Route是一个组件 */}
<div className="container">
{/* Switch 只会匹配一个路由内容 ,PrivateRoute就可以用了,如果不加Switch,所有的就会都走一遍而产生冲突导致报错*/}
<Switch>
<Route path="/login" render={() => <Login />} />
{/* exact 表示完全匹配 */}
{/* 如果不加exact的话 每个页面都会有/那么每个页面都会有Home页这个内容 */}
<Route path="/" exact component={Home} />
{/* 因为希望list、people这两个页面是在登陆之后才可以访问的,所以可以加上私有路由 也就是将Route改成PrivateRoute */}
<PrivateRoute path="/list">
<List />
</PrivateRoute>
<PrivateRoute path="/p/:o">
<People />
</PrivateRoute>
{/* render方式渲染组件,没有直接使用component指定组件
这时候在路由对应的组件中没有history和location等路由的属性信息
*/}
<Route path="/about" render={() => <About />} />
</Switch>
</div>
</div>
</Router>
);
}