1. 程式人生 > >React Router 4.0 ---- 嵌套路由和動態路由

React Router 4.0 ---- 嵌套路由和動態路由

屬性 效果 進一步 column direction 導航欄 ace wid class

  嵌套路由,從廣義上來說,分為兩種情況:一種是每個路由到的組件都有共有的內容,這時把共有的內容抽離成一個組件,變化的內容也是一個組件,兩種組件組合嵌套,形成一個新的組件。另一種是子路由,路由到的組件內部還有路由。

  對於共有的內容,典型的代表就是網頁的側邊欄,假設側邊欄在左邊,我們點擊其中的按鈕時,右側的內容會變化,但不管右側的內容怎麽變化,左側的側邊欄始終存在。這個側邊欄就是共有內容,如下圖所示

技術分享圖片

  這個共有內容要怎麽處理? 首先想到的就是把這個功能提取出來,寫成一個組件,然後再把這個組件依次應用到其它路由組件,如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>
)

  這時效果就達到了,左側的側邊欄始終存在。

React Router 4.0 ---- 嵌套路由和動態路由