标签: router

  • React-Router6:从入门到实战最佳指南

    大家好,我是CoderBin。前段时间学了 react-router5 后才知道出了6,经典白学…,所以,本文将总结 react-router6 的常用操作,以理论+代码+注释的形式教同学们入门 react 路由,看完本篇文章相信你能够独立完成路由的相关案例。对于已经会的人来说就当是复习巩固吧,如果本文有不对、疑惑的地方,欢迎在评论区留言指正,概述:想了解更多详细知识,可前往
    React-Router6官网、,1. React Router 以三个不同的包发布到 npm 上,它们分别为:,2. 与React Router 5.x 版本相比,改变了什么?,or,App.jsx,index.js,总结:以上使用到了 Link、Routes、Route、BrowserRouter 等组件,后面会详细解释,作用:只要
    <Navigate>组件被渲染,就会修改路径,切换视图。,<Route path='/' element={<Navigate to='/home '/>}></Route>,App.jsx,说明:路由映射表其实是一个数组,里面使用对象来表示每一个路径与组件之间的对应关系(如果是子路由需要使用
    <Outlet> 路由占位符展示组件),src/routes/index.js 新建一个js文件编写路由映射表并导出,App.jsx,直接在路由映射表中使用
    children 选项实现嵌套路由,routes.js,然后在 Home 组件中,设置路由占位符,Home.jsx,步骤:,Message.jsx 传递参数的组件,routes.js 路由映射表,Detail.jsx 接收参数的组件,步骤:,Detail.jsx 接收参数的组件,步骤:,Message.jsx 传递参数的组件,Detail.jsx 接收参数的组件,使用
    useNavigate() hooks 可以实现路由的编程式导航,Message.jsx,作用:如果组件在
    <Router> 的上下文中呈现,则
    useInRouterContext 钩子返回 true,否则返回 false。,本次的分享就到这里,如果本章内容对你有所帮助的话可以
    点赞+收藏。文章有不对的地方欢迎指出,有任何疑问都可以在评论区留言。希望大家都能够有所收获,大家一起探讨、进步!,直接在路由映射表中使用
    children 选项实现嵌套路由,react-router: 路由的核心库,提供了很多的:组件、钩子。,react-router-dom: 包含react-router所有内容,并添加一些专门用于 DOM 的组件,例如
    <BrowserRouter>等。,

    前言

    大家好,我是CoderBin。前段时间学了 react-router5 后才知道出了6,经典白学…

    所以,本文将总结 react-router6 的常用操作,以理论+代码+注释的形式教同学们入门 react 路由,看完本篇文章相信你能够独立完成路由的相关案例。对于已经会的人来说就当是复习巩固吧

    如果本文有不对、疑惑的地方,欢迎在评论区留言指正

    一、概述及说明

    概述:想了解更多详细知识,可前往 React-Router6官网

    引用:在客户端路由的十年历程中,React Router v6 采用了以前版本及其姊妹项目 Reach Router 的最佳功能,这是我们迄今为止最小、功能最强大的软件包。

    1. React Router 以三个不同的包发布到 npm 上,它们分别为:

    1. react-router: 路由的核心库,提供了很多的:组件、钩子。
    2. react-router-dom: 包含react-router所有内容,并添加一些专门用于 DOM 的组件,例如 <BrowserRouter>等。
    3. react-router-native: 包括react-router所有内容,并添加一些专门用于ReactNative的API,例如:<NativeRouter>等。

    2. 与React Router 5.x 版本相比,改变了什么?

    1. 内置组件的变化:移除<Switch/> ,新增 <Routes/>等。

    2. 语法的变化:component={About} 变为 element={<About/>}等。

    3. 新增多个hook:useParamsuseNavigateuseMatch等。

    4. 官方明确推荐函数式组件了!!!

    二、安装

    yarn add react-router-dom@6
    

    or

    npm install react-router-dom@6
    

    三、路由的基本使用

    1. 路由的使用步骤

    • 在组件中导入对应路由链接组件,并设置路由链接
    • 在组件中导入 Route 渲染组件,注册路由
    • 在 index.js 中导入路由组件,在 <App> 的最外侧包裹一个 <BrowserRouter><HashRouter>
      • <BrowserRouter> 表示 history 模式的路由
      • <HashRouter> 表示 Hash 模式的路由

    2. 代码示例

    App.jsx

    import React from 'react'
    // 导入 React 内置组件
    import { Link, Routes, Route } from 'react-router-dom'
    import Home from './pages/Home'
    import About from './pages/About'
    
    export default function App() {
      return (
        <div>
              {/* 设置路由链接 */}
              {/* className 接收一个函数,可以改变激活的类名 */}
              <Link className='list-group-item' to="/about">About</Link>
              <Link className='list-group-item' to="/home">Home</Link>
    
              {/* 注册路由 */}
              {/* 必须用 Routes 组件进行包裹*/}
              {/* Route 组件的 element 属性值为对应的组件*/}
              {/* caseSensitive 严格区分大小写*/}
              <Routes>
                  <Route path="/about" caseSensitive element={<About/>}></Route>
                  <Route path="/home" element={<Home />}></Route>
              </Routes>
         </div>
      )
    }
    

    index.js

    import { createRoot } from "react-dom/client";
    import App from './App'
    // 这里使用的是 history 模式的路由
    import {BrowserRouter} from 'react-router-dom'
    
    // 注意:这里使用的 React18 的写法
    const root = createRoot(document.getElementById('root'))
    root.render(
      <BrowserRouter>
        <App/>
      </BrowserRouter>
    )
    

    总结:以上使用到了 Link、Routes、Route、BrowserRouter 等组件,后面会详细解释

    四、路由重定向

    作用:只要<Navigate>组件被渲染,就会修改路径,切换视图。

    <Route path='/' element={<Navigate to='/home '/>}></Route>

    App.jsx

    import React from 'react'
    import { Link, Routes, Route } from 'react-router-dom'
    import Home from './pages/Home'
    import About from './pages/About'
    
    export default function App() {
      return (
        <div>
              {/* 设置路由链接 */}
              <Link className='list-group-item' to="/about">About</Link>
              <Link className='list-group-item' to="/home">Home</Link>
    
              {/* 注册路由 */}
              <Routes>
                  <Route path="/about" caseSensitive element={<About/>}></Route>
                  <Route path="/home" element={<Home />}></Route>
                  {/* Navigate 组件,页面一渲染就显示对应组件,可实现重定向效果 */}
                  <Route path='/' element={<Navigate to='/about '/>}></Route>
              </Routes>
         </div>
      )
    }
    

    五、NavLink 高亮

    import React from 'react'
    import { NavLink, Routes, Route } from 'react-router-dom'
    import Home from './pages/Home'
    import About from './pages/About'
    
    export default function App() {
      return (
        <div>
              {/* 设置路由链接 */}
              <NavLink to="/about">About</NavLink>
              <NavLink to="/home">Home</NavLink>
    
              {/* 注册路由 */}
              <Routes>
                  <Route path="/about" caseSensitive element={<About/>}></Route>
                  <Route path="/home" element={<Home />}></Route>
              </Routes>
         </div>
      )
    }
    

    六、路由映射表

    说明:路由映射表其实是一个数组,里面使用对象来表示每一个路径与组件之间的对应关系(如果是子路由需要使用<Outlet> 路由占位符展示组件)

    src/routes/index.js 新建一个js文件编写路由映射表并导出

    import { Navigate } from 'react-router-dom'
    import About from '../pages/About'
    import Home from '../pages/Home'
    
    // 路由映射表
    const routes =  [
      {
        path: '/home',
        element: <Home />,
      },
      {
        path: '/about',
        element: <About/>
      },
      // 路由重定向
      {
        path: '/',
        element: <Navigate to='/home'/>
      }
    ]
    
    export default routes
    

    App.jsx

    import React from 'react'
    import { NavLink, useRoutes } from 'react-router-dom'
    // 导入编写好的路由映射表
    import routes from './routes'
    
    export default function App() {
      return (
        <div>
    		<div className="list-group">
                {/* 设置路由链接 */}
                <NavLink className='list-group-item' to="/about">About</NavLink>
                <NavLink className='list-group-item' to="/home">Home</NavLink>
              </div>
              <div className="panel-body">
                  {/* 注册路由 */}
                  {/* 调用 useRoutes() hooks,嵌入路由映射表 */}
                  {useRoutes(routes)}
              </div>
         </div>
      )
    }
    

    七、嵌套路由

    直接在路由映射表中使用 children 选项实现嵌套路由

    routes.js

    import { Navigate } from 'react-router-dom'
    import About from '../pages/About'
    import Home from '../pages/Home'
    import Message from '../pages/Home/Message'
    import News from '../pages/Home/News'
    
    // 路由映射表
    const routes =  [
      {
        path: '/home',
        element: <Home />,
        // children 选项,用于实现嵌套路由
        // 注意:子路由只需要写路径名称,不需要 "/" 
        children: [
          {path: 'news', element: <News/>},
          {path: 'message', element: <Message/>}
        ]
      },
      {
        path: '/about',
        element: <About/>
      },
      // 路由重定向
      {
        path: '/',
        element: <Navigate to='/home'/>
      }
    ]
    
    export default routes
    

    然后在 Home 组件中,设置路由占位符

    Home.jsx

    import React from 'react'
    import { NavLink, Outlet } from 'react-router-dom'
    
    export default function Home() {
      return (
        <div>
          <h3>我是 Home 组件的内容</h3>
          <div>
            <ul className="nav nav-tabs">
            <li>
                {/* 设置路由链接 */}
                {/* to 属性值的路径有三种写法 */}
                <NavLink className='list-group-item' to='/home/news'>新闻</NavLink>
                {/* <NavLink className='list-group-item' to='./news'>新闻</NavLink> */}
                {/* <NavLink className='list-group-item' to='news'>新闻</NavLink> */}
              </li>
              <li>
                <NavLink className='list-group-item' to='/home/message'>消息</NavLink>
              </li>
            </ul>
            {/* Outlet 路由占位符,表示"路由映射表"中匹配的组件将在此处展示 */}
            <Outlet/>
          </div>
        </div>   
      )
    }
    

    八、路由的参数传递

    1. 向路由组件传递 params 参数

    步骤:

    1. 传递 params 参数,在路径后面用 / 进行拼接
    2. 在路由表中定义接收路由参数
    3. 对应组件使用 useParams() hooks 接收参数

    Message.jsx 传递参数的组件

    import React, { useState } from 'react'
    import { Link, Outlet } from 'react-router-dom'
    
    export default function Message() {
        const [message] = useState([
        {id: 1, title: 'message1', content: '努力学习'},
        {id: 2, title: 'message2', content: '学习React'},
        {id: 3, title: 'message3', content: '前端工程师'},
      ])
      return (
        <div>
          <ul>
            {
              message.map(m => {
                return (
                  <li key={m.id}>
                    {/* 1. 传递 params 参数,在路径后面用 / 进行拼接 */}
                    <Link to={`detail/${m.id}/${m.title}/${m.content}`}>{m.title}</Link>
                  </li>
                )
              })
            }
          </ul>
          <hr />
          {/* 2. 在路由表中定义接收路由参数 path: 'detail/:id/:title/:content' */}
          {/* 3. 路由占位符 */}
          <Outlet/>
        </div>
      )
    }
    
    

    routes.js 路由映射表

    import { Navigate } from 'react-router-dom'
    import About from '../pages/About'
    import Home from '../pages/Home'
    import Message from '../pages/Home/Message'
    import News from '../pages/Home/News'
    import Detail from '../pages/Home/Message/Detail'
    
    // 路由映射表
    const routes =  [
      {
        path: '/home',
        element: <Home />,
        children: [
          {path: 'news', element: <News/>},
          {
            path: 'message',
            element: <Message />,
            children: [
              // 声明接收参数
              {path: 'detail/:id/:title/:content', element: <Detail/>}
            ]
          },
          {path: '/home', element: <Navigate to='news'/>}
        ]
      },
      {
        path: '/about',
        element: <About/>
      },
      {
        path: '/',
        element: <Navigate to='/home'/>
      }
    ]
    
    export default routes
    

    Detail.jsx 接收参数的组件

    import React from 'react'
    import { useMatch, useParams } from 'react-router-dom'
    
    export default function Detail() {
      // 1. 调用 useParams() hooks,获取传递过来的 params 参数,返回一个参数对象,可以通过解构得出数据
      const { id, title, content } = useParams()
    
      // 2. 调用 useMatch() hooks,传入完成路径,也可以获取到 params 参数,但是不常用
      const data = useMatch('/home/message/detail/:id/:title/:content')
      console.log(data);
      return (
        <div>
          <ul>
            <li>消息编号:{ id }</li>
            <li>消息标题:{ title }</li>
            <li>消息内容:{content}</li>
          </ul>
        </div>
      )
    }
    

    2. 向路由组件传递 search 参数

    步骤

    1. 传递 params 参数,在路径后面用 / 进行拼接
    2. 对应组件使用 useSearchParams() hooks 接收参数 Message.jsx 传递参数的组件
    import React, { useState } from 'react'
    import { Link, Outlet } from 'react-router-dom'
    
    export default function Message() {
        const [message] = useState([
        {id: 1, title: 'message1', content: '努力学习'},
        {id: 2, title: 'message2', content: '学习React'},
        {id: 3, title: 'message3', content: '前端工程师'},
      ])
      return (
        <div>
          <ul>
            {
              message.map(m => {
                return (
                  <li key={m.id}>
                    {/* 1. 传递 search 参数,在路径后面用 ? 进行拼接 */}
                    <Link to={`detail?id=${m.id}&title=${m.title}&content=${m.content}`}>{m.title}</Link>
                  </li>
                )
              })
            }
          </ul>
          <hr />
          {/* 2. 不需要在路由表中定义接收路由参数 */}
          {/* 3. 路由占位符 */}
          <Outlet/>
        </div>
      )
    }
    

    Detail.jsx 接收参数的组件

    import React from 'react'
    import { useLocation, useSearchParams } from 'react-router-dom'
    
    export default function Detail() {
      // 1. 调用 useSearchParams() hooks,获取传递过来的 search 参数
      // 通过数组解构的方法,获取 search(URLSearchParams) 对象
      const [search, setSearch] = useSearchParams()
    
      // 通过 get('search') 方法,获取 search 参数
      const id = search.get('id')
      const title = search.get('title')
      const content = search.get('content')
    
      // 使用 useLocation() hooks,得到一个location对象,也可以获取 search参数,但是比较麻烦,不常用
      const location = useLocation()
      console.log('location',location);
    
      return (
        <div>
          <ul>
            {/* 调用 setSearch() 方法,可以改变传递过来的 search */}
            <button onClick={()=>setSearch('id=004&title=测试&content=测试')}>点击更新收到的search参数</button>
            <li>消息编号:{ id }</li>
            <li>消息标题:{ title }</li>
            <li>消息内容:{content}</li>
          </ul>
        </div>
      )
    }
    
    

    3. 向路由组件传递 state 参数

    步骤

    1. 传递 params 参数,在路径后面用 / 进行拼接
    2. 对应组件使用 useLocation() hooks 接收参数

    Message.jsx 传递参数的组件

    import React, { useState } from 'react'
    import { Link, Outlet } from 'react-router-dom'
    
    export default function Message() {
        const [message] = useState([
        {id: 1, title: 'message1', content: '努力学习'},
        {id: 2, title: 'message2', content: '学习React'},
        {id: 3, title: 'message3', content: '前端工程师'},
      ])
      return (
        <div>
          <ul>
            {
              message.map(m => {
                return (
                  <li key={m.id}>
                    {/* 1. 传递 state 参数,添加 state 属性,值为一个对象 */}
                    <Link to='detail' state={{id:m.id, title:m.title, content:m.content}}>{m.title}</Link>
                  </li>
                )
              })
            }
          </ul>
          <hr />
          {/* 2. 不需要在路由表中定义接收路由参数 */}
          {/* 3. 路由占位符 */}
          <Outlet/>
        </div>
      )
    }
    

    Detail.jsx 接收参数的组件

    import React from 'react'
    import { useLocation } from 'react-router-dom'
    
    export default function Detail() {
      // 调用 useLocation() hooks,通过解构得到一个 state 对象,里面可以拿到传递过来的参数
      // 这里通过连续解构赋值,直接取到参数
      const { state: { id, title, content } } = useLocation()
    
      return (
        <div>
          <ul>
            <li>消息编号:{id}</li>
            <li>消息标题:{title}</li>
            <li>消息内容:{content}</li>
          </ul>
        </div>
      )
    }
    

    九、路由的编程式导航

    使用 useNavigate() hooks 可以实现路由的编程式导航

    Message.jsx

    import React, { useState } from 'react'
    import { Link, Outlet, useNavigate } from 'react-router-dom'
    
    export default function Message() {
    
      const [message] = useState([
        {id: 1, title: 'message1', content: '努力学习'},
        {id: 2, title: 'message2', content: '学习React'},
        {id: 3, title: 'message3', content: '前端工程师'},
      ])
      
      // 调用 useNavigate() hooks 可以实现编程式导航
      // 接收两个参数:目标路径, 配置对象
      // 配置对象:仅支持 replace 和 state 属性,replace表示跳转的模式,state表示传递的state参数
      const navigate = useNavigate()
    
      function showDetail(m) {
        navigate('detail', {
          replace: true,
          state: {
            id: m.id,
            title: m.title,
            content: m.content
          }
        })
      }
    
      return (
        <div>
          <ul>
            {
              message.map(m => {
                return (
                  <li key={m.id}>
                    {/* 设置路由链接 */}
                    <Link to='detail' state={{id:m.id, title:m.title, content:m.content}}>{m.title}</Link>
                    {/* 编程式导航 */}
                    <button onClick={() => showDetail(m)}>查看详情</button>
                  </li>
                )
              })
            }
          </ul>
          <hr />
          {/* 路由占位符 */}
          <Outlet/>
        </div>
      )
    }
    

    十、组件总结

    1. <BrowserRouter>

    1. 说明:<BrowserRouter>用于包裹整个应用。

    2. 示例代码:

     import { createRoot } from "react-dom/client";
     import App from './App'
     import {BrowserRouter} from 'react-router-dom'
    
     const root = createRoot(document.getElementById('root'))
     root.render(
       <BrowserRouter>
         <App/>
       </BrowserRouter>
     )
    

    2. <HashRouter>

    1. 说明:作用与<BrowserRouter>一样,但<HashRouter>修改的是地址栏的hash值。
    2. 备注:6.x版本中<HashRouter><BrowserRouter> 的用法与 5.x 相同。

    3. <Routes/> 与 <Route/>

    1. v6版本中移出了先前的<Switch>,引入了新的替代者:<Routes>

    2. <Routes><Route>要配合使用,且必须要用<Routes>包裹<Route>

    3. <Route> 相当于一个 if 语句,如果其路径与当前 URL 匹配,则呈现其对应的组件。

    4. <Route caseSensitive> 属性用于指定:匹配时是否区分大小写(默认为 false)。

    5. 当URL发生变化时,<Routes>都会查看其所有子<Route> 元素以找到最佳匹配并呈现组件 。

    6. <Route> 也可以嵌套使用,且可配合useRoutes()配置 “路由表” ,但需要通过 <Outlet> 组件来渲染其子路由。

    7. 示例代码:

     <Routes>
         /*path属性用于定义路径,element属性用于定义当前路径所对应的组件*/
         <Route path="/login" element={<Login />}></Route>
     
     	/*用于定义嵌套路由,home是一级路由,对应的路径/home*/
         <Route path="home" element={<Home />}>
            /*test1 和 test2 是二级路由,对应的路径是/home/test1 或 /home/test2*/
           <Route path="test1" element={<Test/>}></Route>
           <Route path="test2" element={<Test2/>}></Route>
     	</Route>
     	
     	//Route也可以不写element属性, 这时就是用于展示嵌套的路由 .所对应的路径是/users/xxx
         <Route path="users">
            <Route path="xxx" element={<Demo />} />
         </Route>
     </Routes>
    

    4. <Link>

    1. 作用: 修改URL,且不发送网络请求(路由链接)。

    2. 注意: 外侧需要用<BrowserRouter><HashRouter>包裹。

    3. 示例代码:

     import { Link } from "react-router-dom";
     
     function Test() {
       return (
         <div>
         	<Link to="/路径">按钮</Link>
         </div>
       );
     }
    

    5. <NavLink>

    1. 作用: 与<Link>组件类似,且可实现导航的“高亮”效果。

    2. 示例代码:

     // 注意: NavLink默认类名是active,下面是指定自定义的class
     
     //自定义样式
     <NavLink
         to="login"
         className={({ isActive }) => {
             console.log('home', isActive)
             return isActive ? 'base one' : 'base'
         }}
     >login</NavLink>
     
     /*
     	默认情况下,当Home的子组件匹配成功,Home的导航也会高亮,
     	当NavLink上添加了end属性后,若Home的子组件匹配成功,则Home的导航没有高亮效果。
     */
     <NavLink to="home" end >home</NavLink>
    

    6. <Navigate>

    1. 作用:只要<Navigate>组件被渲染,就会修改路径,切换视图。

    2. replace属性用于控制跳转模式(push 或 replace,默认是push)。

    3. 示例代码:

     import React,{useState} from 'react'
     import {Navigate} from 'react-router-dom'
     
     export default function Home() {
     	const [sum,setSum] = useState(1)
     	return (
     		<div>
     			<h3>我是Home的内容</h3>
     			{/* 根据sum的值决定是否切换视图 */}
     			{sum === 1 ? <h4>sum的值为{sum}</h4> : <Navigate to="/about" replace={true}/>}
     			<button onClick={()=>setSum(2)}>点我将sum变为2</button>
     		</div>
     	)
     }
    

    7. <Outlet>

    1. <Route>产生嵌套时,渲染其对应的后续子路由。

    2. 示例代码:

     //根据路由表生成对应的路由规则
     const element = useRoutes([
       {
         path:'/about',
         element:<About/>
       },
       {
         path:'/home',
         element:<Home/>,
         children:[
           {
             path:'news',
             element:<News/>
           },
           {
             path:'message',
             element:<Message/>,
           }
         ]
       }
     ])
     
     //Home.js
     import React from 'react'
     import {NavLink,Outlet} from 'react-router-dom'
     
     export default function Home() {
     	return (
     		<div>
     			<h2>Home组件内容</h2>
     			<div>
     				<ul className="nav nav-tabs">
     					<li>
     						<NavLink className="list-group-item" to="news">News</NavLink>
     					</li>
     					<li>
     						<NavLink className="list-group-item" to="message">Message</NavLink>
     					</li>
     				</ul>
     				{/* 指定路由组件呈现的位置 */}
     				<Outlet />
     			</div>
     		</div>
     	)
     }
     
    

    十一、Hooks 总结

    1. useRoutes()

    1. 作用:根据路由表,动态创建<Routes><Route>

    2. 示例代码:

     //路由表配置:src/routes/index.js
     import About from '../pages/About'
     import Home from '../pages/Home'
     import {Navigate} from 'react-router-dom'
     
     export default [
     	{
     		path:'/about',
     		element:<About/>
     	},
     	{
     		path:'/home',
     		element:<Home/>
     	},
     	{
     		path:'/',
     		element:<Navigate to="/about"/>
     	}
     ]
     
     //App.jsx
     import React from 'react'
     import {NavLink,useRoutes} from 'react-router-dom'
     import routes from './routes'
     
     export default function App() {
     	//根据路由表生成对应的路由规则
     	const element = useRoutes(routes)
     	return (
     		<div>
     			......
           {/* 注册路由 */}
           {element}
     		  ......
     		</div>
     	)
     }
     
    

    2. useNavigate()

    1. 作用:返回一个函数用来实现编程式导航。

    2. 示例代码:

     import React from 'react'
     import {useNavigate} from 'react-router-dom'
     
     export default function Demo() {
       const navigate = useNavigate()
       const handle = () => {
         //第一种使用方式:指定具体的路径
         navigate('/login', {
           replace: false,
           state: {a:1, b:2}
         }) 
         //第二种使用方式:传入数值进行前进或后退,类似于5.x中的 history.go()方法
         navigate(-1)
       }
       
       return (
         <div>
           <button onClick={handle}>按钮</button>
         </div>
       )
     }
    

    3. useParams()

    1. 作用:回当前匹配路由的params参数,类似于5.x中的match.params

    2. 示例代码:

     import React from 'react';
     import { Routes, Route, useParams } from 'react-router-dom';
     import User from './pages/User.jsx'
     
     function ProfilePage() {
       // 获取URL中携带过来的params参数
       let { id } = useParams();
     }
     
     function App() {
       return (
         <Routes>
           <Route path="users/:id" element={<User />}/>
         </Routes>
       );
     }
    

    4. useSearchParams()

    1. 作用:用于读取和修改当前位置的 URL 中的查询字符串。

    2. 返回一个包含两个值的数组,内容分别为:当前的seaech参数、更新search的函数。

    3. 示例代码:

     import React from 'react'
     import {useSearchParams} from 'react-router-dom'
     
     export default function Detail() {
     	const [search,setSearch] = useSearchParams()
     	const id = search.get('id')
     	const title = search.get('title')
     	const content = search.get('content')
     	return (
     		<ul>
     			<li>
     				<button onClick={()=>setSearch('id=008&title=哈哈&content=嘻嘻')}>点我更新一下收到的search参数</button>
     			</li>
     			<li>消息编号:{id}</li>
     			<li>消息标题:{title}</li>
     			<li>消息内容:{content}</li>
     		</ul>
     	)
     }
     
    

    5. useLocation()

    1. 作用:获取当前 location 信息,对标5.x中的路由组件的location属性。

    2. 示例代码:

     import React from 'react'
     import {useLocation} from 'react-router-dom'
     
     export default function Detail() {
     	const x = useLocation()
     	console.log('@',x)
       // x就是location对象: 
     	/*
     		{
           hash: "",
           key: "ah9nv6sz",
           pathname: "/login",
           search: "?name=zs&age=18",
           state: {a: 1, b: 2}
         }
     	*/
     	return (
     		<ul>
     			<li>消息编号:{id}</li>
     			<li>消息标题:{title}</li>
     			<li>消息内容:{content}</li>
     		</ul>
     	)
     }
     
       
     
     
    

    6. useMatch()

    1. 作用:返回当前匹配信息,对标5.x中的路由组件的match属性。

    2. 示例代码:

     <Route path="/login/:page/:pageSize" element={<Login />}/>
     <NavLink to="/login/1/10">登录</NavLink>
     
     export default function Login() {
       const match = useMatch('/login/:x/:y')
       console.log(match) //输出match对象
       //match对象内容如下:
       /*
       	{
           params: {x: '1', y: '10'}
           pathname: "/LoGin/1/10"  
           pathnameBase: "/LoGin/1/10"
           pattern: {
           	path: '/login/:x/:y', 
           	caseSensitive: false, 
           	end: false
           }
         }
       */
       return (
       	<div>
           Login
         </div>
       )
     }
    

    7. useInRouterContext()

    作用:如果组件在 <Router> 的上下文中呈现,则 useInRouterContext 钩子返回 true,否则返回 false。

    import React from 'react'
    import { useInRouterContext } from 'react-router-dom'
    
    export default function About() {
      // 使用 useInRouterContext() hooks 检查当前组件是否处于路由的上下文环境
      console.log('是否处于路由的上下文环境?', useInRouterContext());
      return (
        <div>
          <h3>我是 About 组件的内容</h3>
        </div>
      )
    }
    

    8. useNavigationType()

    1. 作用:返回当前的导航类型(用户是如何来到当前页面的)。
    2. 返回值:POPPUSHREPLACE
    3. 备注:POP是指在浏览器中直接打开了这个路由组件(刷新页面)。
    import React from 'react'
    import { useNavigationType } from 'react-router-dom'
    
    export default function About() {
      // 调用 useNavigationType() hooks,可以获取当前路由是以那种跳转模式跳转过来的(PUSH、REPLACE)
      console.log(useNavigationType());
      return (
        <div>
          <h3>我是 About 组件的内容</h3>
        </div>
      )
    }
    
    

    9. useOutlet()

    1. 作用:用来呈现当前组件中渲染的嵌套路由。

    2. 示例代码:

    const result = useOutlet()
    console.log(result)
    // 如果嵌套路由没有挂载,则result为null
    // 如果嵌套路由已经挂载,则展示嵌套的路由对象
    

    10.useResolvedPath()

    1. 作用:给定一个 URL值,解析其中的:path、search、hash值。
    import React from 'react'
    import { useResolvedPath } from 'react-router-dom'
    
    export default function News() {
      // 调用 useResolvedPath() hooks,传入 URL 会帮我们解析其中的:path、search、hash值
      console.log(useResolvedPath('/user?id=001&name=coderbin&age=18'));
      return (
        <div>
          <ul>
            <li>news001</li>
            <li>news002</li>
            <li>news003</li>
          </ul>
        </div>
      )
    }
    

    每文一句:学而不思则罔,思而不学则殆。

    本次的分享就到这里,如果本章内容对你有所帮助的话可以点赞+收藏。文章有不对的地方欢迎指出,有任何疑问都可以在评论区留言。希望大家都能够有所收获,大家一起探讨、进步!

  • 从 Vue2 到 Vue3 ,你必须要掌握的路由差异和使用场景!

    从 Vue2 到 Vue3 ,你必须要掌握的路由差异和使用场景!

    ,很多兄弟在使用 Vue3 了,但对 Vue3 的路由却了解的非常少。甚至只知道基本的跳转和参数获取,这样做一些稍微复杂的功能肯定不够用的。最近就把 Vue3 的路由(Vue-Router4)的版本差异和使用场景整理了一下分享给大家。会的兄弟可以复习一下,不会的兄弟抓紧学起来哦!,Vue3 中不再使用 new Router() 创建 router ,而是调用 createRouter 方法:,路由模式 mode 配置改为 history ,属性值调整为:,基础路径 base 被作为 createWebHistory 的第一个参数进行传递(其他路由模式也是一样):,使用组件跳转,方式还是和 Vue2 一样:,当然,最常见的还是编程式导航,这时候需要引入 useRouter 方法:,注意:参数 params 不能和 path 一起使用。RouterLink 组件 to 属性与 router.push() 接受的参数相同,两者的规则也完全相同。,全局前置守卫通常用来做权限控制,使用 router.beforeEach 即可添加:,每个守卫方法接收两个参数:,可以返回的值如下:,在之前的 Vue Router 版本中,也是可以使用第三个参数 next 的。目前,它仍然是被支持的,这意味着你可以向任何导航守卫传递第三个参数。在这种情况下,要确保 next 在导航守卫中只被调用一次。,全局解析守卫,router.beforeResolve 用法和 router.beforeEach 类似。它是在导航被确认之前,所有组件内守卫和异步路由组件被解析之后被调用。下面这个例子,确保用户可以访问自定义 meta 属性:,router.beforeResolve 是获取数据或执行任何其他操作(进入所有页面后都执行的操作)的理想位置。,和守卫不同的是,全局后置钩子不接受 next 函数,也不能跳转到其他的路由地址:,但它可以接收 failure 作为第三个参数:,router.afterEach 对于访问分析、更改页面标题、声明页面等辅助功能都很有帮助。,我们可以直接在路由配置上定义 beforeEnter 守卫:,beforeEnter 守卫只在进入路由时触发,不会在 paramsquery 或 hash 改变时触发。例如,从 /users/2 进入到 /users/3 或者从 /users/2#info 进入到 /users/2#projects 不会触发。,我们也可以将一个函数数组传递给 beforeEnter,这在为不同的路由重用守卫时很有用:,当然,你也可以通过使用路由的 meta 属性和 全局导航守卫 来实现以上功能。,使用声明式 API ,你可以为组件添加以下守卫:,beforeRouteEnter 守卫不能访问 this,因为此时组件还没有被创建。你可以通过传一个回调给 next 来访问组件实例。在导航被确认的时候执行回调,并且把组件实例作为回调方法的参数:,注意:beforeRouteEnter 是支持 next 传递回调函数的唯一守卫。,beforeRouteUpdate 在当前路由改变,但是该组件被复用时调用。比如,对于一个带有动态参数的路径 /users/:id,在 /users/1 和 /users/2 之间跳转的时候被调用。因为这种情况发生的时候,组件已经挂载好了,导航守卫可以访问组件实例 this。,beforeRouteLeave 通常用来预防用户在还未保存修改前突然离开。该守卫可以通过返回 false 来取消导航。,使用组合式 API,你可以为组件添加 onBeforeRouteUpdate 、onBeforeRouteLeave 导航守卫:,注意:由于 setup 函数调用时机的问题,使用组合式 API 不存在 onBeforeRouteEnter。,当我们获取路由参数时,通常在模板中使用 $route ,在逻辑中调用 useRoute() 方法,如:,以上方法比较麻烦,而且与路由紧密耦合,不利于组件封装。我们可以在创建路由时通过 props 配置来解除这种行为:,此时 route.params 将直接被设置为组件的 props,这样组件就和路由参数解耦了:,当 props 设置为 true 时,route.params 将被设置为组件的 props。,对于有命名视图的路由,你必须为每个命名视图定义 props 配置:,当 props 是一个对象时,它会将此对象设置为组件 props 。当 props 是静态的时候很有用。,我们也可以创建一个返回 props 的函数。这允许你将参数转换为其他类型:,如 /user?userId=123 参数会被转为 { id: ‘123’ } 作为 props 传给 User 组件。,我们可以通过 vue-router 自定义路由切换时页面如何滚动。比如,当跳转到新路由时,页面滚动到某个位置;切换路由时页面回到之前的滚动位置。,当创建路由实例时,我们只需要提供一个 scrollBehavior 方法:,scrollBehavior 函数接收 to from 路由对象。第三个参数 savedPosition,只有当这是一个 popstate 导航时才可用(点击浏览器的后退/前进按钮,或者调用 router.go() 方法)。,该函数可以返回一个 ScrollToOptions 位置对象:,也可以通过 el 传递一个 CSS 选择器或一个 DOM 元素。在这种情况下,top 和 left 将被视为该元素的相对偏移量。,还可以模拟 “滚动到锚点” :,返回 savedPosition,在按下浏览器 后退/前进 按钮,或者调用 router.go() 方法时,页面会回到之前的滚动位置:,提示:如果返回一个 falsy 的值,或者是一个空对象,则不会发生滚动。我们还可以在返回的对象中添加 behavior: ‘smooth’ ,让滚动更加丝滑。,有时候,我们不希望立即执行滚动行为。例如,当页面做了过渡动效,我们希望过渡结束后再执行滚动。要做到这一点,我们可以返回一个 Promise :,如果想要在路由组件上使用转场,对导航进行动画处理,我可以使用 v-slot 结合 Animete.css 来实现:,上面的用法会对所有的路由使用相同的过渡。如果你想让每个路由的组件有不同的过渡,可以将 元信息 和动态的 enter-active-class 结合在一起,放在<transition> 上:,定义以上路由,当从 /user/123 切换到 /user/456 时是没有任何过渡效果的。这时候我们可以添加一个 key 属性来强制进行过渡,key 值只要不同就行了。说白了就是让 Dom 不要被复用,和 v-for 的 key 属性原理刚好相反。,当我们做用户权限的时候,添加路由非常有用。可以使用 router.addRoute() 来添加一个路由:,注意:跟之前版本不同的是,路由只能一个一个添加,不能批量添加。,以下几个方法都可以删除路由:,1、通过使用 router.removeRoute() 按名称删除路由:,2、通过添加一个名称相同的路由,替换掉之前的路由:,3、通过调用 router.addRoute() 返回的回调函数:,当路由没有名称时,这种方法非常有用。,要将嵌套路由添加到现有的路由中,可以将路由的 name 作为第一个参数传递给 router.addRoute() ,这和通过 children 添加的效果一样:,这相当于:,今天把 Vue-Router4 的主要功能跟大家过了一遍,大部分来自官网,也有一些来自自己的实践心得。希望对你的开发工作有所帮助。当然这并不是 Vue-Router4 的所有内容,比如还有路由匹配、重定向和别名等等,大家可以自行在官网查看。后面我会分享更多 Vue3 相关的干货,欢迎大家关注我,关注我的专栏。

  • 思科模拟器路由器配置命令

    思科模拟器是一个功能齐全的网络模拟仿真程序,它有很多特色的作用,可以合理的作用到学习培训CCNA课程内容的网络新手。今日就来为各位共享思科模拟器路由器配置命令,有须要的朋友一起看看吧

    思科模拟器路由器配置命令:

    1、无线路由器动态口令设置:

    router>enable 进到权利模式

    router#config terminal 进到全局性配备模式

    router(config)#hostname 设置网络交换机的IP地址

    router(config)#enable secret xxx 设置权利数据加密动态口令

    router(config)#enable password xxb 设置权利非密动态口令

    router(config)#line console 0 进到控制台口

    router(config-line)#line vty 0 4 进入虚似终端设备

    router(config-line)#login 规定动态口令认证

    router(config-line)#password xx 设置登录动态口令xx

    router(config)#(Ctrl z) 返回权利模式

    router#exit 返回命令

    2、路由器配置:

    router(config)#int s0/0 进到Serail插口

    router(config-if)#no shutdown 激话现阶段插口

    router(config-if)#clock rate 64000 设置同步时钟

    router(config-if)#ip address 设置IP地址

    router(config-if)#ip address second 设置第二个IP

    router(config-if)#int f0/0.1 进到子插口

    router(config-subif.1)#ip address 设置子接口IP

    router(config-subif.1)#encapsulation dot1q 关联vlan无线中继协议书

    router(config)#config-register 0x2142 绕过配备文件

    router(config)#config-register 0x2102 正常的应用配备文件

    router#reload 重新正确引导

    3、无线路由器文件操作:

    router#copy running-config startup-config 保存配备

    router#copy running-config tftp 保存配置到tftp

    router#copy startup-config tftp 开机配备存进tftp

    router#copy tftp flash: 下传文件到flash

    router#copy tftp startup-config 下载配备文件

    ROM状态:

    Ctrl Break 进到ROM监管状态

    rommon>confreg 0x2142 绕过配备文件

    rommon>confreg 0x2102 恢复配置文件

    rommon>reset 重新正确引导

    rommon>copy xmodem: flash: 从console传送文件

    rommon>IP_ADDRESS=10.65.1.2 设置无线路由器IP

    rommon>IP_SUBNET_MASK=255.255.0.0 设置路由器子网掩码

    rommon>TFTP_SERVER=10.65.1.1 特定TFTP服务器IP

    rommon>TFTP_FILE=c2600.bin 指定下载的文件

    rommon>tftpdnld 从tftp下载

    rommon>dir flash: 查看闪存芯片内容

    rommon>boot 正确引导IOS

    4、静态路由:

    ip route 命令格式

    router(config)#ip route 2.0.0.0 255.0.0.0 1.1.1.2 静态路由举例说明

    router(config)#ip route 0.0.0.0 0.0.0.0 1.1.1.2 默认路由器举例说明

    5、动态路由:

    router(config)#ip routing 启动路由器分享

    router(config)#router rip 启动RIPospf协议。

    router(config-router)#network 设置公布路由器

    router(config-router)#negihbor 点到点帧中继用。

    6、帧中继命令:

    router(config)#frame-relay switching 也就能帧中继互换

    router(config-s0)#encapsulation frame-relay 也就能帧中继

    router(config-s0)#fram-relay lmi-type cisco 设置管理种类

    router(config-s0)#frame-relay intf-type DCE 设置为DCE

    router(config-s0)#frame-relay dlci 16

    router(config-s0)#frame-relay local-dlci 20 设置虚电源电路号

    router(config-s0)#frame-relay interface-dlci 16

    router(config)#log-adjacency-changes 纪录临接转变

    router(config)#int s0/0.1 point-to-point 设置子插口点到点

    router#show frame pvc 显示永久虚电源电路

    router#show frame map 显示投射

    7、基本浏览控制目录:

    router(config)#access-list permit|deny

    例1:

    router(config)#access-list 1 deny host 10.65.1.1

    router(config)#access-list 1 permit any

    router(config)#int f0/0

    router(config-if)#ip access-group 4 in

    例2:

    router(config)#access-list 4 permit 10.8.1.1

    router(config)#access-list 4 deny 10.8.1.0 0.0.0.255

    router(config)#access-list 4 permit 10.8.0.0 0.0.255.255

    router(config)#access-list 4 deny 10.0.0.0 0.255.255.255

    router(config)#access-list 4 permit any

    router(config)#int f0/1

    router(config-if)#ip access-group 4 in

    扩展浏览控制目录:

    access-list permit|deny icmp [type]

    access-list permit|deny tcp [port]

    例1:

    router(config)#access-list 101 deny icmp any 10.64.0.2 0.0.0.0 echo

    router(config)#access-list 101 permit ip any any

    router(config)#int s0/0

    router(config-if)#ip access-group 101 in

    例2:

    router(config)#access-list 102 deny tcp any 10.65.0.2 0.0.0.0 eq 80

    router(config)#access-list 102 permit ip any any

    router(config)#interface s0/1

    router(config-if)#ip access-group 102 out

    删除浏览控制例表:

    router(config)#no access-list 102

    router(config-if)#no ip access-group 101 in

    无线路由器的nat配备

    Router(config-if)#ip nat inside 现阶段插口特定为内部结构插口

    Router(config-if)#ip nat outside 现阶段插口特定为外界插口

    Router(config)#ip nat inside source static [p] <私有化IP><公网IP> [port]

    Router(config)#ip nat inside source static 10.65.1.2 60.1.1.1

    Router(config)#ip nat inside source static tcp 10.65.1.3 80 60.1.1.1 80

    Router(config)#ip nat pool p1 60.1.1.1 60.1.1.20 255.255.255.0

    Router(config)#ip nat inside source list 1 pool p1

    Router(config)#ip nat inside destination list 2 pool p2

    Router(config)#ip nat inside source list 2 interface s0/0 overload

    Router(config)#ip nat pool p2 10.65.1.2 10.65.1.4 255.255.255.0 type rotary

    Router#show ip nat translation

    rotary 主要参数是轮番的意思,地址池中的IP轮流与NAT分派的地址配对。

    overload主要参数用以PAT 将内部结构IP投射到一个公网IP不一样的接口上。

    外界网关ip协议书配备

    routerA(config)#router bgp 100

    routerA(config-router)#network 19.0.0.0

    routerA(config-router)#neighbor 8.1.1.2 remote-as 200

    配置PPP认证:

    RouterA(config)#username password

    RouterA(config)#int s0

    RouterA(config-if)#ppp authentication {chap|pap}

    8、无线路由器子插口封装形式为8021Q (填补)

    Encapsulation dot1q 2 封装形式设置为 802.1Q,2是子接口号标志,这儿是示范性,可以随便设置。

    延伸阅读:思科模拟器命令全集