关于react.js:react中实现导航栏状态与地址绑定

4次阅读

共计 3903 个字符,预计需要花费 10 分钟才能阅读完成。

一、我的项目初始化

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 中引入路由相干组件 BrowserRouterRouteSwitchRedirect
在顶部引入:import {BrowserRouter as Router, Route, Switch, Redirect} from 'react-router-dom'
具体代码如下:

import React, {Component} from 'react';
import Home from '@/views/home'
import Study from '@/views/study'
import Type from '@/views/type'
import Label from '@/views/label'
import About from '@/views/about'
import {Layout} from 'antd'
import Header from '@/components/Header'
import Persional from '@/components/Persional'
import {BrowserRouter as Router, Route, Switch, Redirect} from 'react-router-dom'
const {Footer, Content, Sider} = Layout;
// 导入子组件
class App extends Component {render() {
    return (
      <div className="App" >
        <Layout>
          <Sider>
            <Persional />
          </Sider>
          <Content>
            <Router>
              <Header />
              <Switch>
                <Route path="/home" exact component={Home}></Route>
                <Route path="/study" component={Study}></Route>
                <Route path="/type" component={Type}></Route>
                <Route path="/label" component={Label}></Route>
                <Route path="/about" component={About}></Route>
                <Redirect from="/*" to="/home"></Redirect>
              </Switch>
              <Footer>Footer</Footer>
            </Router>
          </Content> 
        </Layout>
      </div>
    );
  }
}

export default App;

这里用到了 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 进行编写。
装置命令:

npm install node-sass --save-dev 
npm install sass-loader --save-dev

为了实现导航栏状态与地址联动,要害是要实现组件初始化时的解决逻辑,也就是组件挂载的时候,即在生命周期函数 componentDidMount 中实现。
要实现以下两点:

  • 批改以后地址对应导航栏状态
  • 监听浏览器后退后盾,即监听 history 对象

要害代码如下:

componentDidMount = () => {
    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:

import 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 标签中。
这样以来就可能实现导航栏状态与地址绑定了

正文完
 0