React-6 React Router知识

  • 阿里云国际版折扣https://www.yundadi.com

  • 阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6

    目录

    一、介绍

    1、作用路由是根据不同的url地址展示不同的页面或者内容

    2、安装

    二、使用

    1、导入

    2、定义路由

    3、重定向

    4、嵌套路由

    5、路由跳转

    6、路由传参

    7、路由拦截

    8、路由模式

    9、withRouter

    10、反向代理

    11、css   modul

    一、介绍

    1、作用路由是根据不同的url地址展示不同的页面或者内容

    2、安装

    (1)官网安装http://reacttraining.com/react-router/web/guides/quick-start

    (2)终端安装

    npm install react-router-dom@5

    二、使用

    1、导入

    //引入
    import   {HashRouter,  Router}  from  'react-router-dom'

    2、定义路由

    render(){
         return  (
           <div>
              <HashRouter>
                   <Router path="/home"  component={Home}  />
                   <Router path="/second"  component={Second}  />
                   <Router path="/mine"  component={Mine}  />
              </HashRouter>
           </div>
         )
    }

    建议将路由单独封装在一个js文件中

    注意一级路由与多级路由 

    3、重定向

    作用如果我们不想让用户访问某个路由或者该路由不在我们书写的路由中我们可以让组件跳转到我们指定的路由

    {/模糊匹配   重定向*/}
    {/*<Redirect   from="/"  to="/home"   exact   />*/}
    {/*exact   精确地*/}
    <Redirect  path="*"   component={Test}  />

    4、嵌套路由

    (1)父组件

    <Route  path="/home"  component={Home}>

    (2)子组件Home直接使用Route

    <Route  path="/home/page1"  component={Page1} />
    <Route  path="/home/page2"  component={Page2} />
    <Redirect  from='/home'  to='home/page1' />

    5、路由跳转

    (1)声明式路由

    <NavLink  to="/home"  activeClassHome="ok">home</NavLink>
    <NavLink  to="/second"  activeClassHome="ok">second</NavLink>
    <NavLink  to="/mine"  activeClassHome="ok">mine</NavLink>

    (2)编程式路由

       <1>this.props.history.push(路由)

       <2> props.history.push(路由)

    import  {useHistory}  from  'react-router-dom'
    
    const  history = useHistory()
    history.push(路由)

    6、路由传参

    (1)使用params参数

    const index = () => {
     const arr = [
          {id:'001',title:'one'},
          {id:'002',title:'two'},
          {id:'003',title:'three'},
        ]
      return (
        <div>
          <ul>
            {
              arr.map((msg) => (
                <li key={msg.id}>
                  {/* 向路由组件传递params参数 */}
                  <Link to={`/home/message/detail/${msg.id}/${msg.title}`}>{msg.title}</Link>
                </li>
              ))
            }
          </ul>
          <hr />
          {/* 声明接收params参数 */}
          <Route path='/home/message/detail/:id/:title' component={Detail} />
        </div>
      )
    }
     
     
    const index = (props) => {
        const data = [
            {id:'001',text:'第一名'},
            {id:'002',text:'第二名'},
            {id:'003',text:'第三名'},
        ]
        //接收params参数
        const {id, title} = props.match.params
        const SearchResult = data.find((dataobj) => {
            return dataobj.id === id;
        })
      return (
        <div>
            <ul>
                <li>id:{id}</li>
                <li>title:{title}</li>
                <li>nm:{SearchResult.text}</li>
            </ul>
     
        </div>
      )
    }

       <1>传递params参数

    <Link  to='/demo/test/001/aa'>展示</Link>

       <2>声明接收params参数

    <Route  path='/demo/test/:id/:title'   component='{Test}' />

       <3>接收params参数

    const   {id, title} = props.match.params

    (2)使用search参数

    const index = () => {
     const arr = [
          {id:'001',title:'one'},
          {id:'002',title:'two'},
          {id:'003',title:'three'},
        ]
      return (
        <div>
          <ul>
            {
              arr.map((msg) => (
                <li key={msg.id}>
                  {/* 向路由组件传递search参数 */}
                  <Link to={`/home/message/detail/?id=${msg.id}&title=${msg.title}`}> {msg.title}</Link>
                </li>
              ))
            }
          </ul>
          <hr />
          <Route path='/home/message/detail' component={Detail} />
        </div>
      )
    }
     
     
    const index = (props) => {
        const detaildata = [
            {id:'001',text:'第一名'},
            {id:'002',text:'第二名'},
            {id:'003',text:'第三名'},
        ]
        //接收search参数
        const {search} = props.location
        const querystring = require('querystringify')
        const obj = querystring.parse(search.slice(1)) 
        const {id, title} = obj   
     
        const SearchResult = detaildata.find((dataobj) => {
            return dataobj.id === id;
        })
      return (
        <div>
          <ul>
            <li>id:{id}</li>
            <li>title:{title}</li>
            <li>nm:{SearchResult.text}</li>
          </ul>
        </div>
      )
    }

       <1>传递参数

    <Link  to='/demo/test?id=001&title=aa'>展示</Link>

       <2>不用声明接收

    <Route  path='/demo/test'  component='{Test}' />

       <3>接收search参数接收到的数据为字符串形式需要转换成对象

    (3)使用state参数

       <1>传递state参数

    <Link  to={{pathname:'/home/message/detail', state:{id:'001',title:'aa'}}}>展示</Link>

       <2>不用声明接收

    <Route  path='/demo/test/'  component='{Test}' />

       <3>接收state参数

    const  {id, title} = props.location.state

    注意 刷新后对路由state参数的影响

    <1>BrowserRouter没有任何影响因为state保存在history对象中。

    <2>HashRouter刷新后会导致路由state参数的丢失

    7、路由拦截

    (1)使用Prompt组件来完成

       <1>参数whenboolean型

             作用true弹窗false顺利跳转。

       <2>参数messagefunction或者字符串

             作用函数返回true就顺利跳转false停止跳转字符串就弹窗字符串并停止跳转。

    注意当when值为true并且message是函数返回值为false时才会拦截路由并且不会弹出默认弹出框。

    import {  Dialog } from '@alifd/meet-react';
    import React, { useEffect, useState} from 'react';
    import { Prompt, useHistory } from 'react-router';
    
    import style from './index.module.scss';
    
    export default function TestPage() {
      const history = useHistory();
      const [notAllowJump, setNotAllowJump] = useState(true);
    
      /**
       * 路由拦截
       * @param {*} location string
       * @returns boolean
       */
      function handleRouter() {
        const list = field.getValue('list');
        const equal = xxxxx(); // 判断两次值是不是一样 
        if (equal) {
        // 两次值一样用户没改动数据直接放行
          return true;
        }
        Dialog.show({
          centered: true,
          content: '是否保存当前修改数据',
          onOk() {
          	// 用户需要提交提交后要放行先将when置为false再提交操作
            setNotAllowJump(false);
            xxxxxSubmit(); // 继续提交
          },
          async onCancel() {
          	// 用户不提交直接放弃修改返回上一页。将when置为false再返回注意setNotAllowJump操作是异步的。
            await setNotAllowJump(false);
            history.goBack();
          },
        });
        // 用户有修改返回false拦截跳转同时屏蔽掉默认弹出框
        return false;
      }
    
      return (
        <div className={style['test-page']}>
          <Prompt when={notAllowJump} message={handleRouter} />
          <footer>
            我是页面内容
          </footer>
        </div>
      );
    }
    

    (2)使用history.block拦截

       <1>当返回值为true路由会跳转不会弹出默认框。

       <2>当返回值为false路由不会跳转不会弹出默认框。

       <3>当返回值为string路由不会跳转会弹出默认框。

    注意当block返回值是false时候能够拦截路由跳转并且不会弹出默认提示框。

    import { useHistory } from 'react-router';
    import {  Dialog } from '@alifd/meet-react';
    import React, { useEffect, useState} from 'react';
    
    import style from './index.module.scss';
    
    export default function TestPage() {
      const history = useHistory();
      
      useEffect(() => {
        history.block(() => {
          Dialog.show({
            centered: true,
            content: '是否保存当前修改数据',
            onOk() {
              history.block(() => true); // 放开拦截提交操作成功后在提交函数内跳出去
              xxxxxSubmit();
            },
            async onCancel() {
              history.block(() => true);
              history.goBack();
            },
          });
          // 开启路由拦截同时阻止默认弹出框
          return false;
        });
      }, [history]);
    
      return (
        <div className={style['test-page']}>
          <footer>
            我是页面内容
          </footer>
        </div>
      );
    }
    
    

    8、路由模式

    (1)HashRouter哈希路由

       <1>根据URL地址中的哈希值来确定显示的组件http://localhost:3000/#/first

       <2>hash的变化不会导致页面刷新兼容性较好。

    (2)BrowserRouter浏览器路由

       <1>使用 H5 的 history.pushState API 实现 http://localhost:3000/first

       <2>推荐使用浏览器路由。

    9、withRouter

    (1)作用可以让一般组件没有通过component渲染的组件获取到history属性

    (2)使用方法

       <1>在需要使用history属性的组件中引入withRouter原理高阶组件

    import {withRouter} from 'react-router-dom'

       <2>默认导出

    export default withRouter(组件名称)

    10、反向代理

    (1)解决跨域问题

    (2)参考链接Proxying API Requests in Development | Create React App

    (3)开始使用

       <1>安装插件nmp install http-proxy-middleware   --save

    const {createProxyMiddleware} = require('http-proxy-middleware')
        module.exports = function (app) {
            app.use(
                 '/api',
                 createProxyMiddleware({
                     target:'目标URL',
                     changeOrigin: true
                }
            )
        )
            }

       <2>在src文件夹下创建setupProxy.js文件

       <3>重新启动app

    11、css   module

    (1)spa应用在任意js引入css代码都有相当于在head标签内引入如果是多组件或者多人开发如何避免冲突

    (2)我们建议每一个组件都可以放入一个同名文件夹中这样js与css在一起

    (3)css命名时写成 eg.   A.module.css

       <1>这样这个css样式只对A起作用

       <2>注意 不要单独写  标签名选择器

  • 阿里云国际版折扣https://www.yundadi.com

  • 阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6