美文网首页
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