zoukankan      html  css  js  c++  java
  • React进阶篇(1) -- react-router4模块化

    本篇内容:

    • 单一的路由无嵌套
    • 多层嵌套路由
    • 获取路径中的参数
    • 按需加载

    单一的路由无嵌套

    routers.js

    import Home from 'components/Home';
    import News from 'components/News';
    import User from 'components/User';
    import My from 'components/My';
    
    let routes=[
        {
            path:'/',
            component:Home ,
            exact:true
        },
        {
            path:'/news',
            component:News ,
        },
        {
            path:'/user',
            component:User 
        },
        {
            path:'/my',
            component:My 
        },
    ]
    export default routes;
    

    App.jsx

    import React, { Component } from 'react';
    import { HashRouter as Router, Switch, Route } from "react-router-dom";
    import routes from '../routers/index';
    class App extends Component {
      render() {
        return (
            <Router>
                <div>
                    <Switch>
                        //主要逻辑在这里
                        {
                            routes.map((item, i) => {
                                if(item.exact){
                                    return <Route exact path={item.path} component={item.component}  key={i}/>
                                }else{
                                    return <Route path={item.path} component={item.component}  key={i}/>
                                }
                            }) 
                        }
                    </Switch> 
                </div>
            </Router>
        );
      }
    }
    

    多层嵌套路由

    let routes=[
        {
            path:'/hear',
            component:Hear,
            exact:true,
            description:"听",
            subs:[
                {
                    path:'/hear/',
                    component:HearIndex,
                    description:"听-首页" 
                },
                {
                    path:'/hear/book',
                    component:HearBook,
                    description:"听-课文" 
                },
            ]
        },
        {
            path:'/speak',
            component:Speak,
            exact:true,
            description:"说",
            subs:[
                {
                    path:'/speak/',
                    component:CN,
                    description:"说-汉语" 
                },
                {
                    path:'/speak/english',
                    component:English,
                    description:"说-英语" 
                },
            ]
        },
        {
            path:'/read',
            component:Read,
            exact:true,
            description:"读",
            subs:[
                {
                    path:'/read/',
                    component:ReadBook,
                    description:"读-课文" 
                },
                {
                    path:'/read/newspaper',
                    component:ReadNews,
                    description:"读-报纸" 
                },
            ]
        },
        {
            path:'/writ',
            component:Writ,
            exact:true,
            description:"写"
        }
    ]
    export default routes;
    

    App.jsx

    {
        routes.map((item, i) => {
            if (item.exact) {
                //官方固定格式
                return <Route exact path={item.path} key={i} render={ props => (<item.component {...props} routes={item.subs}/>) />
            }
            else {
                return <Route path={item.path} key={i} render={ props => (<item.component {...props}  routes={item.subs}/>)} />
            }
        })
    }
    
    

    //step 2,在对应的组件中再次遍历

    {
        this.props.routes.map((item, i) => {
            return <Route exact path={item.path}
            component= {item.component}
            key={i}/>
        })
    }
    

    跳转

    this.props.history.push(`/about/type/${id}`)
    this.props.history.replace(...)
    

    注意:

    不能在子组件中直接获取,需要从父级传入之后用props获取;

    跳转时,如果还有事件未结束,则容易报错!

    如:

    <LoginCom TIMEID={TIMEID} {...this.props}/>
    

    获取路径参数

    获取对应的params

    this.props.match.params.id
    

    获取?后面对应的值

    const getQueryString = (str,name) => {
        let result = str.match(new RegExp("[?&]" + name + "=([^&]+)", "i"));
        if (result == null || result.length < 1) {
            return "";
        }
        return decodeURI(result[1], "utf-8");
    }
    

    如:http://localhost:3000/#/textbook/bishun?val=看

    console.log(getQueryString(this.props.location.search,'val'));
    

    按需加载

    感觉这种方式最简单:

    基于 webpack, babel-plugin-syntax-dynamic-import, 和 react-loadable;

    主要是利用了react-loadable这个高级组件,他是专门用来异步加载(也可以预加载)组件的。

    cnpm i -S react-loadable @babel/plugin-syntax-dynamic-import
    

    .babelrc

    {
       “ presets ”:[ “ @ babel / react ” ],
       “ plugins ”:[ “ @ babel / plugin-syntax-dynamic-import ” ]
    }
    

    routers.js变化

    import Loadable from 'react-loadable';
    import DelayLoading from './DelayLoading';
    
    const Home= Loadable({loader: () => import('../components/Home'), loading : DelayLoading,delay:3000})
    const Login= Loadable({loader: () => import('../components/Login'), loading : DelayLoading,delay:3000})
    

    打包文件情况对比:

    首屏加载情况对比:

    参考文档:

    https://reacttraining.com/react-router/web/example/route-config

    https://github.com/ReactTraining/react-router/blob/master/packages/react-router-dom/docs/guides/code-splitting.md

    https://github.com/jamiebuilds/react-loadable

    可参考其他文章:https://www.cnblogs.com/alan2kat/p/7754846.html

  • 相关阅读:
    ASP.NET Web API 中 特性路由(Attribute Routing) 的重名问题
    在 ASP.NET Web API 中,使用 命名空间(namespace) 来作为路由的参数
    【转】使用create_project.py创建cocos2d项目时出错
    WCF使用net.tcp绑定时的注意事项
    WCF:如何将net.tcp协议寄宿到IIS
    关于WCF服务的调试跟踪
    Windows Store Apps 开发转载
    如何让弹出窗口和页面产生联动?
    关于C# wpf DataGrid单元格双击设置单元格内容
    在WPF的DataGrid中对行添加单击事件
  • 原文地址:https://www.cnblogs.com/adoctors/p/10181242.html
Copyright © 2011-2022 走看看