知识点
- 编写底部导航栏
- 创建图标公用组件
- 路由控制底部导航栏的显隐
编写底部导航栏
我们先观察我们今天要实现的底部导航长啥样,如下所示:
我们在上一章的代码基础上添加导航栏组件,在 src 目录下新建 components 目录,专门用于放置一些公用组件,我们再在 components 目录下新建 NavBar 目录,用于编写底部导航栏,代码如下所示: ```javascript import React, { useState } from ‘react’; import PropTypes from ‘prop-types’ import { TabBar } from ‘zarm’; import { useHistory } from ‘react-router-dom’; import s from ‘./style.module.less’;
const NavBar = ({ showNav }) => { const [activeKey, setActiveKey] = useState(‘/‘); const history = useHistory()
const changeTab = (path) => { setActiveKey(path) history.push(path) }
return (
NavBar.propTypes = { showNav: PropTypes.bool }
export default NavBar;
跳转到对应的组件,'/'、'/data'、'/user' 这三个路由对应的三个组件我们还未编写,这里我们在 container 目录下新建这三个页面组件,作为占位。```javascript// Home/index.jsximport React from 'react'const Home = () => {return <div>首页</div>}export default Home// Data/index.jsximport React from 'react'const Data = () => {return <div>数据</div>}export default Data// User/index.jsximport React from 'react'const User = () => {return <div>个人中心</div>}export default User
前往 router/index.js 添加路由配置,如果不添加这个配置,调用 history.push 这个方法,就无法匹配到对应的页面组件,代码如下:
// router/index.jsimport Home from '@/container/Home'import Data from '@/container/Data'import User from '@/container/User'const routes = [{path: "/",component: Home},{path: "/data",component: Data},{path: "/user",component: User}];export default routes
最后,将导航栏组件引入 App.jsx 入口页面,如下所示:
// App.jsx...import NavBar from '@/components/NavBar';...function App() {return <Router><ConfigProvider primaryColor={'#007fff'}><Switch>{routes.map(route => <Route exact key={route.path} path={route.path}><route.component /></Route>)}</Switch></ConfigProvider><NavBar showNav={true} /></Router>}
添加底部导航图标
我们将图标写成公共组件,这样便于后面各个页面方便引入,我们新建 components/CustomIcon/index.jsx,添加如下代码:
import { Icon } from 'zarm';export default Icon.createFromIconfont('//at.alicdn.com/t/font_2236655_w1mpqp7n1ni.js');
上述代码,我们引入 Icon,执行它的自定义图标方法 createFromIconfont,它接收一个参数,为 iconfont 生产的静态脚本路径,你可以自己去 官网 配置,也可以直接用我提供的:
接着我们将其引入到代码中使用,打开 components/NavBar/index.jsx ,添加如下属性:
import CustomIcon from '../CustomIcon';...<TabBar.ItemitemKey="/"title="账单"icon={<CustomIcon type="zhangdan" />}/><TabBar.ItemitemKey="/data"title="统计"icon={<CustomIcon type="tongji" />}/><TabBar.ItemitemKey="/user"title="我的"icon={<CustomIcon type="wode" />}/>
底部导航栏的显示隐藏
我们在之前引入 NavBar 的代码中,将 showNav 属性写死为 true。此时,我们需要将其盘活,打开 App.jsx,添加如下代码:
import React, { useEffect, useState } from 'react'import {BrowserRouter as Router,Switch,Route,useLocation} from "react-router-dom"import NavBar from '@/components/NavBar';import { ConfigProvider } from 'zarm'import routes from '@/router'function App() {const location = useLocation() // 拿到 location 实例const { pathname } = location // 获取当前路径const needNav = ['/', '/data', '/user'] // 需要底部导航栏的路径const [showNav, setShowNav] = useState(false) // 是否展示 NavuseEffect(() => {setShowNav(needNav.includes(pathname))}, [pathname]) // [] 内的参数若是变化,便会执行上述回调函数=return <Router><ConfigProvider primaryColor={'#007fff'}><Switch>{routes.map(route => <Route exact key={route.path} path={route.path}><route.component /></Route>)}</Switch></ConfigProvider><NavBar showNav={true} /></Router>}export default App
执行 useLocation 时,报错 location of undefined。这是因为想要在函数组件内执行 useLocation,该组件必须被 Router 高阶组件包裹,我们做如下改动,将 App.jsx 的 Router 组件,前移到 main.jsx 内,如下:
最后,别忘记把组件属性修改成动态变量:
<NavBar showNav={showNav} />
总结
导航栏可以用在很多地方,映射到 PC 网页就是左侧侧边导航,道理都是相通的。移动端放在下面控制,PC 端放在左边或者右边控制罢了。所以再次强调不要学完了一个知识点,就思维定势地认为只能用在某一个需求上,能做到融会贯通,才是判断一个好程序员的标准。
