React Router 4.0 ---- 嵌套路由和动态路由

  嵌套路由,从广义上来说,分为两种情况:一种是每个路由到的组件都有共有的内容,这时把共有的内容抽离成一个组件,变化的内容也是一个组件,两种组件组合嵌套,形成一个新的组件。另一种是子路由,路由到的组件内部还有路由。

  对于共有的内容,典型的代表就是网页的侧边栏,假设侧边栏在左边,我们点击其中的按钮时,右侧的内容会变化,但不管右侧的内容怎么变化,左侧的侧边栏始终存在。这个侧边栏就是共有内容,如下图所示

  这个共有内容要怎么处理? 首先想到的就是把这个功能提取出来,写成一个组件,然后再把这个组件依次应用到其它路由组件,如about, products 等。导航栏肯定是一个导航,不过这里我们要使用navLink 组件,因为从图片中可以看到它有高亮显示,我们要设计一个高亮显示的样式。新建一个menus.js 文件,来写这个导航组件

import React from 'react'
// 引入NavLink 组件
import { NavLink } from "react-router-dom";
import './menus.css'

// 高亮的样式,表示我们在哪个导航下
const selectedStyle = {
  backgroundColor: 'white',
  color: 'slategray'
}

// navLink, activeStyle 点击高亮显示当前标签。
export const MainMenu = () => (
  <nav className='main-menu'>
    <NavLink to='/'>首页</NavLink>
    <NavLink to='/about' activeStyle = {selectedStyle}>关于我们</NavLink>
    <NavLink to='/events' activeStyle = {selectedStyle}>企业事件</NavLink>
    <NavLink to='/products' activeStyle = {selectedStyle}>公司产品</NavLink>
    <NavLink to='/contact' activeStyle = {selectedStyle}>联系我们</NavLink>
  </nav>
)

  可以看到导航的高亮样式可以在NavLink 组件中直接设置,这也是Link 和NavLink的区别。这里还写了一点样式,在menus.css 文件中。

/* 页面左侧主要导航 */
.main-menu {
  display: flex;
  flex-direction: column;
  height: 100%;
  width: 20%;
  min-width: 20%;
  background-color: slategray;
  color: ghostwhite;
}

.main-menu  a {
  color: ghostwhite;
  text-align: center;
  padding: 1em;
  font-size: 1.5em;
}

  按照上面的说法,我们把这个组件应用到其它组件中,在pages.js中引入该组件,并修改Events,Products, 

Contact和 About 组件中,引入的组件命名为MainMenu
// 企业事件内容
export const Events = () => (
    <div>
      <MainMenu></MainMenu>
      <section className="events">
        <h1>企业大事件</h1>
      </section>
    </div>
)

// 公司产品 
export const Products = () => (
  <div>
    <MainMenu></MainMenu>
    <section className="products">
      <h1>公司产品:主要经营 手机、电脑</h1>
    </section>
  </div>
)

// 联系我们
export const Contact = () => (
  <div>
    <MainMenu></MainMenu>
    <section className="contact">
      <h1>联系我们</h1>
      <p>公司电话:0755 - 12345678</p>
    </section>
  </div>
)

  这时你会发现,相同的代码复制了4遍,还可以接受,毕竟只有一个共有组件。但如果about, home 这些组件有好多共有的部分,我们这样一遍一遍的复制就有点麻烦了。所以还要对page.js文件这些组件相同的内容进行进一步的抽取。抽取的形式应该是

<div>
    <MainMenu></MainMenu>
    // 变化的部分
  </div>

  现在最主要的部分就是这些变化的部分要怎么处理,想到了其实也很简单,因为React 有一个children 属性, 直接把这些变化的部分写成props.childern 就可以了。这时你会发现,这个抽取的组件像一个布局模板, 比如单页面应用时的页眉和页脚这些共有的部分,也可以放到这个模版中。新建一个template.js 文件

import React from 'react'
import { MainMenu } from "./menus";

export const Template = (props) => (
  <div className = 'page'>
    <MainMenu></MainMenu>
    {props.children}
  </div>
)

  上面的代码中加了一个样式类page, 在pages.css 中添加一个 page样式,

.page {
  display: flex;
  justify-content: space-between;
  height: 100%;
  margin-top: 20px;
}

  现在再在pages.js中的相应组件中应用Template组件

import { Template } from "./template";// 企业事件内容
export const Events = () => (
  <Template>
    <section className="events">
      <h1>企业大事件</h1>
    </section>
  </Template>

)

// 公司产品 
export const Products = () => (
  <Template>
    <section className="products">
      <h1>公司产品:主要经营 手机、电脑</h1>
    </section>
  </Template>
)

// 联系我们
export const Contact = () => (
  <Template>
    <section className="contact">
      <h1>联系我们</h1>
      <p>公司电话:0755 - 12345678</p>
    </section>
  </Template>
)

  这时效果就达到了,左侧的侧边栏始终存在。

猜你喜欢

转载自www.cnblogs.com/SamWeb/p/8932931.html