react-router路由之routerRender方法(v5 v6)

安裝路由

$ npm  i react-router-dom

安裝 react-router-dom 的即已附帶 react-router 核心包

普通版

直接使用使用 Route 組件完成類似于 vue 的 router-view + routes 的布局

函數(shù)版

通過類 routes 配置文件和相關(guān)封裝函數(shù)完成便捷性路由布局

v5版本下的渲染

 // 函數(shù)版  
import React from 'react'
import { Route, Switch} from 'react-router-dom'

const renderRoutes = (routes) => {
  if (!routes) {
    return null
  }
  return (
    <Switch>
      {
        routes.map((route) => {
          console.log(route)
          return (
            <Route
              key={route.path}
              path={route.path}
              exact={route.exact}
              render={(props) => {
                 return (
                   route.render
                     ? route.render({...props,route})
                     : <route.component {...props} route={route} />
                 )
              }}
            />
          )
        })
      }
    </Switch>
  )
}

export default renderRoutes
import {
  DashboardOutlined,
  BankOutlined,
} from '@ant-design/icons'
import Login from '../views/login'
import Dashboard from '../views/dashboard'
import FrameLayout from '../layout/frame-layout'
import Hospital from '../views/hospital'
import Doctor from '../views/hospital/doctor'
import Department from '../views/hospital/department'
import Introduction from '../views/hospital/introduction'

const routes = [
  {
    path: '/login',
    component: Login,
    exact: true,
  },
  {
    path: '/',
    component: FrameLayout,
    children: [
      {
        path: '/dashboard',
        component: Dashboard,
        meta: {
          title: '首頁',
          icon: DashboardOutlined,
        },
      },
      {
        path: '/hospital',
        component: Hospital,
        meta: {
          title: '醫(yī)院信息',
          icon: BankOutlined,
        },
        children: [
          {
            path: '/hospital/doctor',
            component: Doctor,
            meta: {
              title: '醫(yī)生管理',
            },
          },
          {
            path: '/hospital/department',
            component: Department,
            meta: {
              title: '科室管理',
            },
          },
          {
            path: '/hospital/introduction',
            component: Introduction,
            meta: {
              title: '醫(yī)院介紹',
            },
          },
        ],
      },
    ],
  },
]

export default routes

v5版本下的渲染

// v6版本下的渲染, 需要多渲染一次,考慮到循環(huán)嵌套子路由的問題,寫了個函數(shù)再渲染
import React from 'react'
import { Route, Routes } from 'react-router-dom'

const renderRoutes = (routes) => {
  if (!routes) {
    return null
  }
  return (
    <Routes>
      {
        routes.map((route) => (
          <Route
            key={route.path}
            path={route.path}
            exact={route.exact}
            element={<route.component child={route.children} ></route.component>}
            // v5
            // render={(props) => (
            //   route.render
            //     ? route.render({...props, route})
            //     : <route.component {...props} route={route} />
            // )}
          >
            {
              route.children ? childRouterRender(route.children) : null
            }
          </Route>
        ))
      }
    </Routes>
  )
}

const childRouterRender = (children) => (
  children.map((child) => (
    <Route
      key={child.path}
      path={child.path}
      exact={child.exact}
      element={<child.component />}
    >
      {
        child.children ? childRouterRender(child.children) : null
      }
    </Route>
  ))
)

export default renderRoutes
// v6 版routes文件
// react
import React from 'react'
// 導(dǎo)入組件
import Layout from '../components/layout'
// 登陸
import Login from '../views/login/login'
// 首頁
import Home from '../views/home/home'
// 倉庫管理
import Inventory from '../views/inventory/inventory'
import InventoryList from '../views/inventory/inventoryList'
import InventoryPost from '../views/inventory/inventoryPost'
import InventoryNews from '../views/inventory/inventoryNews'

// 導(dǎo)入圖標(biāo)
import { UserOutlined, HomeFilled, HddFilled, ShopFilled, SettingFilled } from '@ant-design/icons';

const routes = [
  {
    path: '/login',
    component: Login,
    exact: true,
  },
  {
    path: '/*',
    component: Layout,
    children: [
      {
        to: 'home',
        path: 'home',
        component: Home,
        exact: true,
        meta: {
          title: '首頁',
          icon: HomeFilled,
        },
      },
      {
        path: 'inventory/*',
        to: 'inventory/*',
        component: Inventory,
        exact: true,
        meta: {
          title: '貨存管理',
          icon: HddFilled,
        },
        children: [
          {
            path: 'inventoryList',
            to: 'inventory/inventoryList',
            component: InventoryList,
            exact: true,
            meta: {
              title: '貨存列表',
            },
          },
          {
            path: 'inventoryPost',
            to: 'inventory/inventoryPost',
            component: InventoryPost,
            exact: true,
            meta: {
              title: '新品進庫',
            },
          },
          {
            path: 'inventoryNews',
            to: 'inventory/inventoryNews',
            component: InventoryNews,
            exact: true,
            meta: {
              title: '貨存通知',
            },
          },
        ],
      },
    ],
  },
]

export default routes

總結(jié):

  • 封裝 routerRender 的方法大體上差不多,但是 react-router v6版本的結(jié)構(gòu)不一樣,首先路由跳轉(zhuǎn)的路徑和 route 組件里的 path 完全不一樣,如果說為了快速開發(fā),請記得將兩者區(qū)分開。
  • 其次只要是有子路由的一律都要在末尾加上 /*
  • V6 沒有 render 和 component 的組件屬性,僅使用 element ,目前還不清楚是在 routes 文件里將其寫成 <element /> 形式,還是在函數(shù)里處理,因為如果要傳參的話。不過參考了很多文章,都是直接在 routes 文件里直接寫成組件形式了,所以我這個僅供參考使用方法。
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容