美文网首页
React Router 5.x - 给vue开发者

React Router 5.x - 给vue开发者

作者: 我叫Aliya但是被占用了 | 来源:发表于2021-03-18 11:21 被阅读0次

    react语法 - 给vue开发者
    Dva - react状态管理 - 给vuex开发者
    Redux - 给vue开发者

    最新版本是 5.x,网上很多文档都是老版本的,已经不再适用(包括这个这个)。官方 API(英文的。。。)PrivateRoute 用法

    npm install react-router-dom --save

    import { BrowserRouter as Router, Route, Switch } from "react-router-dom";
    
    ReactDOM.render(
      <Router>
        <Switch>
          <Route path="/" exact component={App} />
          <Route path="/use" component={AppUsexxx} />
          <Route path="/other" component={Other} />
          <Route component={404} />
        </Switch>
      </Router>,
      document.getElementById("root")
    );
    

    借助插件react-router-config可以实现VUE式的路由定义

    import { renderRoutes } from 'react-router-config';
    
    const Child = ({ route }) => ( // 接收 route 参数
      <div>
        <h2>Child</h2>
        {/* vue router-view */}
        {renderRoutes(route.routes, { someProp: "these extra props are optional" })}
      </div>
    );
    
    const routes = [
      {
        component: Root,
        routes: [
          { path: '/', exact: true, component: Home },
          {
            path: '/child/:id',
            component: Child,
            routes: [{ path: '/child/:id/grand-child', component: GrandChild }],
          },
        ],
      },
    ];
    
    ReactDOM.render(
      <BrowserRouter>
        {renderRoutes(routes)}
      </BrowserRouter>,
      document.getElementById('root')
    );
    

    路由嵌套

    // Other.tsx
    import React from "react";
    import { Route, Switch, useRouteMatch } from "react-router-dom";
    import Message from "./Message";
    
    const Other: React.FC = (props: any) => {
      let match = useRouteMatch();
      return (
        <div>
          <h1>啥嘻嘻</h1>
          {/* 路由嵌套 */}
          <Switch>
            <Route path={`${match.path}/msg/:id`}>
              <Message></Message>
            </Route>
          </Switch>
        </div>
      );
    };
    
    export default Other;
    

    在根部定义所有路由

    ReactDOM.render(
      <Router>
        <Switch>
            <Route path="/" exact component={App} />
            <Route path="/use" component={AppUsexxx} />
            <Route
              path="/other"
              component={() => (
                <Other>
                  <Route path="/other/msg/:id" component={Message} />
                </Other>
              )}
            ></Route>
          <Route component={404} />
        </Switch>
      </Router>,
      document.getElementById("root")
    );
    
    const Other: React.FC = (props: any) => {
      return (
        <div>
          <h1>啥嘻嘻</h1>
          {props.children}
      );
    };
    

    很不方便。

    vue-router 与 react-router 对照表

    vue-router react-router
    根部 new Vue({ route }) 注入 ReactDOM.render 方法 html 外层加入 Router 等标签
    借助react-router-config可实现VUE式配置路由文件
    mode <BrowserRouter>和<HashRouter>
    base basename
    路由配置 <Route>和<Switch>可以用在任何位置,路由嵌套写在具体组件里
    router-link 标签 Link、NavLink
    router-view 标签 props.children 或直接写要使用的组件<br />orreact-router-config renderRoutes(route.routes, {...someprops})
    this.$route.params.id useParams().id
    this.$router.push、replace() useHistory().push、replace()、Redirect 标签
    路由守卫 没有,需要自己写。

    .

    • Switch 的作用:仅渲染匹配的第一个。不使用它时会渲染所有的匹配项(eg: /use 会渲染 /和/use 两个组件)

    • 路由对象(link 的 to、push 的参数):

      {
        "pathname": "/path",
        "search": "?name=val",
        "hash": "#the-hash",
        "state": { "fromDashboard": true }
      }
      

    代码拆分 例子,及路由嵌套的另一种实现

    cnpm install @loadable/component --save-dev
    // .d.ts 声明文件,非必须
    npm i --save-dev @types/loadable__component
    

    添加代码拆分,并封装 router,可以像配置 vue 一样配置路由

    import { BrowserRouter as Router, Route, Switch } from "react-router-dom";
    import loadable from "@loadable/component";
    
    export type RouteType = {
      path?: string,
      component: string,
      exact?: boolean,
      children?: RouteType[],
    };
    
    const CreateRoute = (route: RouteType, fatherPath: string = "") => {
      const Comp = loadable(() => import(`../pages${route.component}`));
      const path = route.path ? `${fatherPath}${route.path}` : undefined;
      return (
        <Route
          path={path}
          exact={route.exact || false}
          component={() => (
            <Comp>
              {route.children &&
                route.children.length &&
                route.children.map((item) => CreateRoute(item, path || fatherPath))}
            </Comp>
          )}
        ></Route>
      );
    };
    
    const CreateRouter = (config: RouteType[]) => {
      return (
        <Router>
          <Switch>{config.map((item) => CreateRoute(item))}</Switch>
        </Router>
      );
    };
    
    export default CreateRouter;
    

    使用

    import CreateRouter from "./router/router"; // 上面那段代码
    
    const routers = [
      {
        path: "/",
        component: "/App",
        exact: true,
      },
      {
        path: "/use",
        component: "/AppUsexxx",
      },
      {
        path: "/other",
        component: "/Other",
        children: [
          {
            path: "/msg/:id",
            component: "/Message",
          },
        ],
      },
    ];
    
    ReactDOM.render(
      <Provider store={store}>{CreateRouter(routers)}</Provider>,
      document.getElementById("root")
    );
    

    路由守卫 例子

    • 利用高阶函数封装组件,在 HOC 内部做权限判断,不满足条件 useHistory().replace 掉
    function withAuth(Comp, isLogin) {
      // ...并返回另一个组件...
      return class extends React.Component {
        render() {
          if (isLogin) {
            return <Comp data={this.state...} />;
          } else {
            return <Redirect to="/login" />;
          }
        }
      };
    }
    
    // or ? (这段代码没有验证过)
    function RouteGuard({ children }) {
      if (isLogin) return children
      return <Redirect to="/login" />;
    }
    
    ReactDOM.render(
      <BrowserRouter>
        <Router basename={'/'}>
          <RouteGuard>{renderRoutes(routes)}</RouteGuard>
        </Router>
      </BrowserRouter>,
      document.getElementById('root')
    );
    
    • 封装一个自定义 Route 组件
    class PrivateRoute extends Component {
      render() {
        const { path, component } = this.props;
        if (isLogin) {
          return <Route path={path} component={component} />;
        }
        return <Redirect to={"/login"} />;
      }
    }
    
    // <Route path="/other" component={Other} />
    <PrivateRoute path="/other" component={Other} />;
    

    相关文章

      网友评论

          本文标题:React Router 5.x - 给vue开发者

          本文链接:https://www.haomeiwen.com/subject/kjuucltx.html