react 路由跳转(编程式导航)
一、项目需求
准备实现一个简易的编程式导航项目,需求如下
- 一级路由:Login 、Layout
- 二级路由:Layout 下有 Avatar、Detail、User
- 实现登录、退出跳转功能
- 实现传参获参:Avatar、Detail、User
二、项目初始化准备
1.创建启动下载
- npx create-react-app react-router
- cd react-router
- yarn start 或 npm start 或 npm run start
- yarn add react-router-dom@5.2.1
2.index.js
import React from 'react'
import ReactDOM from 'react-dom'
import App from './App'
ReactDOM.render(
<React.StrictMode>
<App />
</React.StrictMode>,
document.getElementById('root')
)
3.子路由文件基本内容
src/views/Page/Avatar.js
// 函数组件
const Avatar = () => {
return <div>
<p>我是 Avatar</p>
</div>
}
export default Avatar
src/views/Page/Detail.js
// 类组件
import React from 'react'
class Detail extends React.Component {
render() {
return <div>
<p>我是 Detail </p>
</div>
}
}
export default Detail
src/views/Page/User.js
// 类组件
import React from 'react'
class User extends React.Component {
render() {
return <div>
<p>我是 User </p>
</div>
}
}
export default User
4.补充导航点击样式 index.css
/* 点击出现小手 */
li {
width: 100px;
cursor: pointer;
}
/* 点击导航高亮 */
li:hover {
background-color: pink;
}
三、实现编程式导航跳转
1.App.js
import React from 'react'
// 导入路由 react-router-dom@5.2.1
import { BrowserRouter, Route, Switch, Redirect } from 'react-router-dom'
// 导入登录页
import Login from './views/Login'
// 导入首页
import Layout from './views/Layout'
// ◆BrowserRouter 只能出现一次
class App extends React.Component {
render() {
return <div>
<BrowserRouter>
<Switch>
<Route exact path="/login" component={Login} ></Route>
<Route path="/layout" component={Layout} ></Route>
{/* 重定向 */}
<Redirect exact from="/" to="login"></Redirect>
</Switch>
</BrowserRouter>
</div>
}
}
export default App
2.src/views/Login.js
函数组件实现编程式导航跳转
import React from 'react'
import { Route } from 'react-router-dom'
import Layout from './Layout'
const Login = (props) => {
// 1.登录 去 Layout
const goLayoutHandler = () => {
props.history.push('/layout')
}
return <div>
<p>这是登录页! Login</p>
<button onClick={goLayoutHandler}>登录</button>
<Route path="/layout" component={Layout}></Route>
</div>
};
export default Login
3.src/views/Layout.js
类组件实现编程式导航跳转
import React from 'react'
import { Route, Redirect } from 'react-router-dom'
// 导入 子路由
import Avatar from './Page/Avatar'
import Detail from './Page/Detail'
import User from './Page/User'
import '../index.css'
class Layout extends React.Component {
// ◆1.退出登录
logOutHandler = () => {
this.props.history.push('/login')
}
// ◆2.去 Avatar
goAvatatHandler = () => {
this.props.history.push('/layout/avatar')
}
// ◆3.去 Detail
goDetailHandler = () => {
this.props.history.push('/layout/detail')
}
// ◆4.去 User
goUserHandler = () => {
this.props.history.push('/layout/user')
}
render() {
return <div>
<div>
<p>这是首页! Layout</p>
<button onClick={this.logOutHandler}>退出</button>
</div>
<div >
<ul>
<li onClick={this.goAvatatHandler}>我是 Avatar</li>
<li onClick={this.goDetailHandler} >我是 Detail</li>
<li onClick={this.goUserHandler}>我是 User</li>
</ul>
<div className="box">
<Redirect from="/layout" to="/Layout/avatar"></Redirect>
<Route path="/layout/avatar" component={Avatar}></Route>
<Route path="/layout/detail" component={Detail}></Route>
<Route path="/layout/user" component={User}></Route>
</div>
</div>
</div>
}
}
export default Layout
四、编程式导航传参与获参
第一种:search
1.Layout.js 传参
// 省略其他。。。
// ◆2.去 Avatar
goAvatatHandler = () => {
this.props.history.push('/layout/avatar?name=Lucy&age=18')
}
2.Avatar.js 获参
const Avatar = (props) => {
console.log(props,'Avatar')
console.log(props.location.search)//?name=Lucy&age=18
// ◆法1:浏览器内置的 new URLSearchParams() 方法,获取我们想要的参数
const name = new URLSearchParams(props.location.search).get('name')
const age = new URLSearchParams(props.location.search).get('age')
console.log(name)// Lucy
console.log(age)// 18
// ◆法2:slice()方法,可用于字符串和数组(我还想变成对象的格式)
// 1.把问号去掉
const query = props.location.search.slice(1)
console.log(query, 'query')// name=Lucy&age=18
// 2.切割成数组
const arr = query.split('&')
console.log(arr, 'res')// 'name=Lucy', 'age=18'] 'res'
// 3.再循环切割获取对象
let obj = {}
arr.forEach(item => {
const arr2 = item.split(['='])
console.log(arr2, 'arr2')// ['name','Lucy'] ['age','18']
obj[arr2[0]] = arr2[1]
})
console.log(obj, 'obj')// {name: 'Lucy', age: '18'}
// ◆法3:把 法2 封装成函数(也可以单独抽离成一个 js 文件)
function paramsQuery(url) {
// 1.把问号去掉
const query = url.slice(1)
// 2.切割成数组
const arr = query.split('&')
// 3.再循环切割获取对象
let newObj = {}
arr.forEach(item => {
const arr2 = item.split(['='])
newObj[arr2[0]] = arr2[1]
})
// const {name,age}=obj
// 4.返回对象
return newObj
}
// 5.调用获取结果
const res = paramsQuery(props.location.search)
console.log(res, '123')
// ◆ 页面使用
return <div>
<p>我是 Avatar</p>
<p>我的名字是{name},我的年龄是:{age}</p>
<p>我的名字是{obj.name},我的年龄是:{obj.age}</p>
<p>我的名字是{res.name},我的年龄是:{res.age}</p>
</div>
}
export default Avatar
3.页面效果
第二种:params(附search)
1.Layout.js 传参
// 省略其他。。。
// ◆3.去 Detail
goDetailHandler = () => {
this.props.history.push('/layout/detail/2/Rose?age=20')
}
<Route path="/layout/detail/:id/:name" component={Detail}></Route>
2.Detail.js 获参
import React from 'react'
class Detail extends React.Component {
// 1.定义变量接收传递过来的 params 参数和 search 参数
state = {
id: this.props.match.params.id,
name: this.props.match.params.name,
friend: new URLSearchParams(this.props.location.search).get('friend')
}
// 2.显示渲染在页面
render() {
console.log(this.props, 'Detail')
return <div>
<p>我是 Detail </p>
<p>我的 id 是:{this.state.id} ,我的名字的:{this.state.name}</p>
<p>我的朋友是:{this.state.friend}</p>
</div>
}
}
export default Detail
3.页面效果
第三种:query
1.Layout.js 传参
// ◆4.去 User
goUserHandler = () => {
this.props.history.push({pathname:'/layout/user',query:{name:'Jack'}})
}
2.User.js 获参
import React from 'react'
class User extends React.Component {
state={
name:this.props.location.query.name
}
render() {
return <div>
<p>我是 User </p>
<p>我的名字是:{this.state.name}</p>
</div>
}
}
export default User
3.页面效果
第四种:state(同 query)
1.Layout.js 传参
// ◆4.去 User
goUserHandler = () => {
// this.props.history.push('/layout/user')
// this.props.history.push({pathname:'/layout/user',query:{name:'Jack'}})
this.props.history.push({pathname:'/layout/user',state:{ids:3}})
}
2.User.js 获参
import React from 'react'
class User extends React.Component {
state={
ids:this.props.location.state.ids
}
render() {
return <div>
<p>我是 User </p>
<p>我的 ids 是:{this.state.ids}</p>
</div>
}
}
export default User
3.页面效果
转载自:https://juejin.cn/post/7076327985753620517