日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

React(7)—— SPA应用 - React路由机制 - react-router-dom

發布時間:2023/12/14 编程问答 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 React(7)—— SPA应用 - React路由机制 - react-router-dom 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

文章目錄

  • 一、理解
    • 1. SPA的理解
    • 2. 路由的理解
      • 2.1 什么是路由?
      • 2.2 路由的分類
        • 1. 前端路由
        • 2. 后端路由
    • 3. react-router-dom 的理解
  • 二、react-router-dom相關API
    • 1. 內置組件
    • 2. 其它
  • 三、路由的使用
    • 1. 效果
    • 2. 準備
    • 3. 路由的基本使用
    • 4. 實現
      • index.js
      • App.jsx
    • 5. 路由組件與一般組件的區別
    • 6. NavLink與封裝NavLink
    • 7. Switch的使用
    • 8. 解決多級路徑刷新頁面樣式丟失的問題
    • 9. 路由的嚴格匹配與模糊匹配
    • 10. Redirect的使用 【重定向】
  • 四、嵌套路由使用
    • 1. 最終效果
    • 2. 注意
    • 3. 實現
      • Home/index.jsx
  • 五、向路由組件傳遞參數數據
    • 1. 效果
    • 2. 具體方法
      • 方法1. params參數
        • Message/index.jsx
        • Detail/index.jsx
      • 方法2. search參數
      • 方法3. state參數
        • Message/index.jsx
        • Detail/index.jsx
  • 六、多種路由跳轉方式
    • 1. 編程式路由導航
    • 2. withRouter的使用
  • 七、注意
    • BrowserRouter與HashRouter的區別


一、理解

1. SPA的理解

  • 單頁Web應用(single page web application,SPA)
  • 就是只有一張Web頁面的應用,是加載單個HTML 頁面并在用戶與應用程序交互時動態更新該頁面的Web應用程序。
  • 點擊頁面中的鏈接不會刷新頁面,只會做頁面的局部更新。
  • 數據都需要通過ajax請求獲取, 并在前端異步展現。
  • 2. 路由的理解

    2.1 什么是路由?

  • 一個路由就是一個映射關系(key: value)
  • key為路徑, value可能是function或component
  • 2.2 路由的分類

    1. 前端路由

  • 理解:瀏覽器端路由,value是component,用于展示頁面內容。
  • 注冊路由: < Route path="/test" component={Test} >
  • 工作過程:當瀏覽器的path變為/test時, 當前路由組件就會變為Test組件
  • 2. 后端路由

  • 理解:value是function, 用來處理客戶端提交的請求。
  • 注冊路由:router.get(path, function(req, res))
  • 工作過程:當node接收到一個請求時, 根據請求路徑找到匹配的路由, 調用路由中的函數來處理請求, 返回響應數據
  • 3. react-router-dom 的理解

  • React的一個插件庫。
  • 專門用來實現一個SPA應用。
  • 基于React的項目基本都會用到此庫。
  • 二、react-router-dom相關API

    1. 內置組件

  • <BrowserRouter/ >
  • <HashRouter/ >
  • <Route/ >
  • <Redirect/ >
  • <Link/ >
  • <NavLink/ >
  • <Switch/ >
  • 2. 其它

  • history對象
  • match對象
  • withRouter函數
  • 三、路由的使用

    1. 效果

    2. 準備

  • 下載react-router-dom:
  • npm install react-router-dom
  • 引入bootstrap.css:
  • <link rel="stylesheet" href="/css/bootstrap.css">

    3. 路由的基本使用

  • 明確好界面中的導航區、展示區
  • 導航區的a標簽改為Link標簽
    < Link to="/xxxxx">Demo< /Link >
  • 展示區寫Route標簽進行路徑的匹配
    < Route path='/xxxx' component={Demo}/ >
  • < App/>的最外側包裹了一個< BrowserRouter>或< HashRouter >
  • 4. 實現

    index.js

    這里用一個標簽將整個App包起來,保證使用的是同一個路由器

    //引入react核心庫 import React from 'react' //引入ReactDOM import ReactDOM from 'react-dom' // import {BrowserRouter} from 'react-router-dom' //引入App import App from './App'ReactDOM.render(<BrowserRouter><App/></BrowserRouter>,document.getElementById('root') )

    App.jsx

    import React, { Component } from 'react' import { Link,Route } from 'react-router-dom' import Home from './Home' import About from './About'export default class App extends Component {render() {return (<div><div className="row"><div className="col-xs-offset-2 col-xs-8"><div className="page-header"><h2>React Router Demo</h2></div></div></div><div className="row"><div className="col-xs-2 col-xs-offset-2"><div className="list-group">{/* 原生html中,靠<a>跳轉不同的頁面 */}{/* <a className="list-group-item" href="./about.html">About</a><a className="list-group-item active" href="./home.html">Home</a> */}{/* 在React中靠路由鏈接實現切換組件--編寫路由鏈接 */}<Link className="list-group-item" to="/about">About</Link><Link className="list-group-item" to="/home">Home</Link></div></div><div className="col-xs-6"><div className="panel"><div className="panel-body">{/* 注冊路由 */}<Route path='/about' component={About} /><Route path='/home' component={Home} /></div></div></div></div></div>)} }

    5. 路由組件與一般組件的區別

  • 寫法不同
    一般組件:<Demo/>
    路由組件:<Route path="/demo" component={Demo}/>
  • 存放位置不同
    一般組件:components
    路由組件:pages
  • 接收到的props不同
    一般組件:寫組件標簽時傳遞了什么,就能收到什么
    路由組件:接收到三個固定的屬性
  • history:go: ? go(n)goBack: ? goBack()goForward: ? goForward()push: ? push(path, state)replace: ? replace(path, state) location:pathname: "/about"search: ""state: undefined match:params: {}path: "/about"url: "/about"

    6. NavLink與封裝NavLink

    NavLink可以實現路由鏈接的高亮,通過activeClassName屬性指定樣式名,默認是"active"

    <NavLink activeClassName="demo" className="list-group-item" to="/home">Home</NavLink>

    可以自己封裝一個NavLink【一般組件】

    import React, { Component } from 'react' import {NavLink} from 'react-router-dom'export default class MyNavLink extends Component {render() {// console.log(this.props);return (<NavLik activeClassName="demo" className="list-group-item" {...this.props} />)} }

    標簽體內容是特殊的標簽屬性通過this.props.children可以獲取標簽體內容
    使用

    <MyNavLink to="/about">About</MyNavLink> <MyNavLink to="/home">Home</MyNavLink>

    7. Switch的使用

  • 通常情況下,path和component是一一對應的關系。
  • Switch可以提高路由匹配效率(單一匹配)。
  • <Switch><Route path="/about" component={About}/><Route path="/home" component={Home}/><Route path="/home" component={Test}/> </Switch>

    這樣只要匹配到了第一個就不會再往下匹配了

    8. 解決多級路徑刷新頁面樣式丟失的問題

  • public/index.html 中 引入樣式時不寫./寫/ (常用)【絕對路徑】
  • public/index.html 中 引入樣式時不寫./寫%PUBLIC_URL% (常用)
  • 使用HashRouter
  • 9. 路由的嚴格匹配與模糊匹配

  • 默認使用的是模糊匹配(簡單記:【輸入的路徑】必須包含要【匹配的路徑】,且順序要一致)
  • 開啟嚴格匹配:<Route exact={true} path="/about" component={About}/>
  • 嚴格匹配不要隨便開啟,需要再開,有些時候開啟會導致無法繼續匹配二級路由
  • 10. Redirect的使用 【重定向】

    一般寫在所有路由注冊的最下方,當所有路由都無法匹配時,跳轉到Redirect指定的路由
    具體編碼:

    <Switch><Route path="/about" component={About}/><Route path="/home" component={Home}/><Redirect to="/about"/> </Switch>

    四、嵌套路由使用

    1. 最終效果

    2. 注意

  • 注冊子路由時要寫上父路由的path值
  • 路由的匹配是按照注冊路由的順序進行的
  • 3. 實現

    Home/index.jsx

    import React, { Component } from 'react' import { Route, NavLink,Redirect,Switch } from 'react-router-dom' import News from './News' import Message from './Message'export default class Home extends Component {render() {return (<div><h3>我是Home的內容</h3><div><ul className="nav nav-tabs"><li><NavLink className="list-group-item" to="/home/news">News</NavLink></li><li><NavLink className="list-group-item" to="/home/message">Message</NavLink></li></ul><Switch><Route path='/home/news' component={News} /><Route path='/home/message' component={Message} /><Redirect to='/home/news' /></Switch></div></div>)} }

    五、向路由組件傳遞參數數據

    1. 效果

    2. 具體方法

    方法1. params參數

  • 路由鏈接(攜帶參數):<Link to='/demo/test/tom/18'}>詳情</Link>
  • 注冊路由(聲明接收):<Route path="/demo/test/:name/:age" component={Test}/>
  • 接收參數:this.props.match.params
  • Message/index.jsx

    import React, { Component } from 'react' import { Link, Route } from 'react-router-dom'; import Detail from './Detail';export default class Message extends Component {state = {messageArr: [{ id: '01', title: '消息1' },{ id: '02', title: '消息2' },{ id: '03', title: '消息3' },]}render() {const { messageArr } = this.state;return (<div><ul>{messageArr.map((msgObj) => {return (<li key={msgObj.id}>{/* 向路由組件傳遞params參數 */}<Link to={`/home/message/detail/${msgObj.id}/${msgObj.title}`}>{msgObj.title}</Link></li>)})}</ul><hr />{/* 聲明接收params參數 */}<Route path="/home/message/detail/:id/:title" component={Detail}/></div>)} }

    Detail/index.jsx

    import React, { Component } from 'react'export default class Detail extends Component {state = {detailData : [{ id: '01', content: '你好啊' },{ id: '02', content: '還不錯鴨' },{ id: '03', content: '顯示我吧' }]}render() {console.log(this.props)// 接收params參數const { id, title } = this.props.match.paramsconst findResult= this.state.detailData.find((dataObj) => {return dataObj.id === id})return (<div><ul><li>ID: {id }</li><li>Title: {title }</li><li>Content: { findResult.content}</li></ul></div>)} }

    方法2. search參數

  • 路由鏈接(攜帶參數):<Link to='/demo/test?name=tom&age=18'}>詳情</Link>
  • 注冊路由(無需聲明,正常注冊即可):<Route path="/demo/test" component={Test}/>
  • 接收參數:this.props.location.search
  • 備注:獲取到的search是urlencoded編碼字符串,需要借助querystring解析
  • import qs from 'querystring' let obj = {name:'tom', age:18} console.log(qs.stringify(obj)) // name=tom&age=18 let str = 'carName=Benz&price=199' console.log(qs.parse(str)) // {carName: 'Benz', price: 199}

    方法3. state參數

  • 路由鏈接(攜帶參數):<Link to={{ pathname:'/demo/test', state:{name:'tom',age:18} }}>詳情</Link>
  • 注冊路由(無需聲明,正常注冊即可):<Route path="/demo/test" component={Test}/>
  • 接收參數:this.props.location.state
  • 備注:刷新也可以保留住參數【history對象記錄著在】
  • Message/index.jsx

    export default class Message extends Component {render() {const {messageArr} = this.statereturn (<div><ul>{messageArr.map((msgObj)=>{return (<li key={msgObj.id}>{/* 向路由組件傳遞params參數 */}{/* <Link to={`/home/message/detail/${msgObj.id}/${msgObj.title}`}>{msgObj.title}</Link> */}{/* 向路由組件傳遞search參數 */}{/* <Link to={`/home/message/detail/?id=${msgObj.id}&title=${msgObj.title}`}>{msgObj.title}</Link> */}{/* 向路由組件傳遞state參數 */}<Link to={{pathname:'/home/message/detail',state:{id:msgObj.id,title:msgObj.title}}}>{msgObj.title}</Link></li>)})}</ul><hr/>{/* 聲明接收params參數 */}{/* <Route path="/home/message/detail/:id/:title" component={Detail}/> */}{/* search參數無需聲明接收,正常注冊路由即可 */}{/* <Route path="/home/message/detail" component={Detail}/> */}{/* state參數無需聲明接收,正常注冊路由即可 */}<Route path="/home/message/detail" component={Detail}/></div>)} }

    Detail/index.jsx

    import React, { Component } from 'react' // import qs from 'querystring'export default class Detail extends Component {render() {console.log(this.props);// 接收params參數// const {id,title} = this.props.match.params // 接收search參數// const {search} = this.props.location// const {id,title} = qs.parse(search.slice(1))// 接收state參數const {id,title} = this.props.location.state || {}const findResult = DetailData.find((detailObj)=>{return detailObj.id === id}) || {}return (<ul><li>ID:{id}</li><li>TITLE:{title}</li><li>CONTENT:{findResult.content}</li></ul>)} }

    六、多種路由跳轉方式

    1. 編程式路由導航

    借助this.prosp.history對象上的API對操作路由跳轉、前進、后退

    • this.prosp.history.push(path, [state]) 將新條目推入歷史記錄堆棧
    • this.prosp.history.replace(path, [state]) 替換歷史記錄堆棧上的當前條目
    • this.prosp.history.go() 將歷史堆棧中的指針移動n個條目
    • this.prosp.history.goBack() 等同于 go(-1)
    • this.prosp.history.goForward() 等同于 go(1)

    2. withRouter的使用

    export default withRouter(Header)

    withRouter可以加工一般組件,讓一般組件具備路由組件所特有的API
    withRouter的返回值是一個新組件

    七、注意

    BrowserRouter與HashRouter的區別

  • 底層原理不一樣:
    BrowserRouter使用的是H5的history API,不兼容IE9及以下版本。
    HashRouter使用的是URL的哈希值。
  • path表現形式不一樣
    BrowserRouter的路徑中沒有#,例如:localhost:3000/demo/test
    HashRouter的路徑包含#,例如:localhost:3000/#/demo/test
  • 刷新后對路由state參數的影響
    (1) BrowserRouter沒有任何影響,因為state保存在history對象中。
    (2) HashRouter刷新后會導致路由state參數的丟失!!!
  • 總結

    以上是生活随笔為你收集整理的React(7)—— SPA应用 - React路由机制 - react-router-dom的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。