react中实现导航栏状态与地址绑定
一、项目初始化
1. 安装与运行
构建项目:yarn create react-app my-app
启动:yarn start
当然也可以使用npm:
- 全局安装:
npm install -g create-react-app
- 构建项目:
npx create-react-app my-app
- 启动:
npm start
2.安装路由依赖
在项目中执行:npm install react-router-dom --save
3.在App.js中引入router
由于简单演示,就不单独对router进行封装了。
安装完成后,我们在App.js中引入路由相关组件BrowserRouter
、Route
、Switch
、Redirect
在顶部引入:import { BrowserRouter as Router, Route, Switch, Redirect } from 'react-router-dom'
详细代码如下:
1 |
|
这里用到了antd的Layout
布局组件进行布局
首先我们将我们的视图组件引入进来(import Home from '@/views/home'
),并在Route标签中配置:(以home为例)<Route path="/home" exact component={Home}></Route>
4.编写Header头部导航组件
在components目录下新建Header目录,并在其目录下新建index.js及index.scss文件,这里使用scss进行编写。
安装命令:
1 |
|
为了实现导航栏状态与地址联动,关键是要实现组件初始化时的处理逻辑,也就是组件挂载的时候,即在生命周期函数componentDidMount
中实现。
要实现以下两点:
- 修改当前地址对应导航栏状态
- 监听浏览器前进后退,即监听history对象
关键代码如下:组件完整代码如下:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17componentDidMount = () => {
let moren = this.props.location.pathname
let text = moren.substring(moren.lastIndexOf('/') + 1, moren.length)
// 当访问的目录不在这个数组里时候,当前状态是home,即重定向到home页面
!['home', 'study', 'type', 'label', 'about', 'search'].includes(text) && (text = 'home')
this.setState({
current: text
})
// 监听history变化
history.listen((event) => {
let test = event.pathname
let text = test.substring(test.lastIndexOf('/') + 1, test.length)
this.setState({
current: text
})
})
}
index.js:注意:为了能够拿到1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70import React, { Component } from 'react';
import { Row, Col, Menu } from 'antd';
import { Link, withRouter } from 'react-router-dom'
import { HomeOutlined, FolderOpenOutlined, AppstoreOutlined, PushpinOutlined, UserOutlined, SearchOutlined } from '@ant-design/icons';
import './index.scss'
import { createBrowserHistory } from 'history';
const history = createBrowserHistory() // history模式
class Header extends Component {
constructor(props) {
super(props);
this.state = {
logo: '',
current: 'home'
}
}
handleClick = e => {
this.setState({ current: e.key });
}
componentDidMount = () => {
let moren = this.props.location.pathname
let text = moren.substring(moren.lastIndexOf('/') + 1, moren.length)
!['home', 'study', 'type', 'label', 'about', 'search'].includes(text) && (text = 'home')
this.setState({
current: text
})
history.listen((event) => {
let test = event.pathname
let text = test.substring(test.lastIndexOf('/') + 1, test.length)
this.setState({
current: text
})
})
}
render() {
const { current } = this.state;
return(
<div className="header-wrapper">
<Row>
<Col span={18} push={6} className="right-box">
<Menu onClick={this.handleClick} selectedKeys={[current]} mode="horizontal">
<Menu.Item key="home" icon={<HomeOutlined />}>
<Link to="/home">首页</Link>
</Menu.Item>
<Menu.Item key="study" icon={<FolderOpenOutlined />}>
<Link to="/study">学习</Link>
</Menu.Item>
<Menu.Item key="type" icon={<AppstoreOutlined />}>
<Link to="/type">分类</Link>
</Menu.Item>
<Menu.Item key="label" icon={<PushpinOutlined />}>
<Link to="/label">标签</Link>
</Menu.Item>
<Menu.Item key="about" icon={<UserOutlined />}>
<Link to="/about">关于</Link>
</Menu.Item>
<Menu.Item key="search" icon={<SearchOutlined />}>
搜索
</Menu.Item>
</Menu>
</Col>
<Col span={6} pull={18} className="left-box">
<strong className="logo-name">Deng</strong>
</Col>
</Row>
</div>
)
}
}
export default withRouter(Header)this.props.location.pathname
,需要使用withRouter
处理组件,并把Header组件放在BrowserRouter
标签中。
这样就能够实现导航栏状态与地址绑定了
本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!