React-router

2022-05-18  本文已影响0人  张_何

路由的发展阶段

后端路由阶段
前后端分离阶段
单页面富应用(SPA)阶段

前端路由的原理

URL 的 hash
<body>
  <div id="app">
    <a href="#/home">首页</a> 
    <a href="#/about">关于</a>
    <div class="router-view"> 初始内容 </div>
  </div>
  
  <script>
    // 获取router-view的DOM
    const routerViewEl = document.getElementsByClassName("router-view")[0];

    // 监听URL的改变. location 是一个全局变量
    window.addEventListener("hashchange", () => {
      switch (location.hash) {
        case "#/home":
          routerViewEl.innerHTML = "改成首页";
          break;
        case "#/about":
          routerViewEl.innerHTML = "改成关于";
          break;
        default:
          routerViewEl.innerHTML = "";
      }
    })
  </script>
</body>

默认我们的 url 是http://127.0.0.1:5500/监听hash的该改变.html; 当我们点击首页的时候,就会改成http://127.0.0.1:5500/监听hash的该改变.html#/home, 同时router-view div 中的内容也会改变;

HTML5 的 history
<body>
  <div id="app">
    <a href="/home">首页</a>
    <a href="/about">关于</a>
    <div class="router-view"></div>
  </div>

  <script>
    // 1.获取router-view的DOM
    const routerViewEl = document.getElementsByClassName("router-view")[0];
    // 获取所有的a元素, 自己来监听a元素的改变
    const aEls = document.getElementsByTagName("a");
    for (let el of aEls) {
      el.addEventListener("click", e => {
        e.preventDefault();
        const href = el.getAttribute("href");
        history.pushState({}, "", href);
        urlChange();
      })
    }

    // 执行返回操作时, 依然来到urlChange
    window.addEventListener('popstate',urlChange);
    // 监听URL的改变
    function urlChange() {
      switch (location.pathname) { // 这里的 pathname 就是点击的 a 标签的 href 值
        case "/home":
          routerViewEl.innerHTML = "改成首页";
          break;
        case "/about":
          routerViewEl.innerHTML = "改成关于";
          break;
        default:
          routerViewEl.innerHTML = "";
      }
    }
  </script>
</body>

React-router

基本使用

BrowserRouter、HashRouter
Link 和 NavLink
a.active { // 设置活跃时的样式
  color: red;
  font-size: 30px;
}
a.link-active {
  color: yellow;
  font-size: 40px;
}
<NavLink exact to="/">首页</NavLink>
<NavLink to="/about" activeClassName="link-active">关于</NavLink>
Route
        <HashRouter>
          <Link to="/">首页</Link>
          <Link to="/about">关于</Link>
          <Link to="/profile">我的</Link>
          <Route exact path="/" component={Home}/>
          <Route exact path="/about" component={About}/>
          <Route exact path="/profile" component={Profile}/>
        </HashRouter>
 <HashRouter>
          <Link to="/">首页</Link>
          <Link to="/about">关于</Link>
          <Link to="/profile">我的</Link>
          <div> 哈哈哈 </div>
          <Route exact path="/" component={Home}/>
          <Route exact path="/about" component={About}/>
          <Route exact path="/profile" component={Profile}/>
          <div> 呵呵呵 </div>
</HashRouter>
Switch
<Switch>
  <Route exact path="/" component={Home} />
  <Route path="/about" component={About} />
  <Route path="/:id" component={User} />
  <Route component={NoMatch} />
</Switch>
Redirect
  render() {
    return this.state.isLogin ? (
      <div>
        <h2>User</h2>
        <h2>用户名: ****</h2>
      </div>
    ): <Redirect to="/login" />
  }
路由的嵌套
class App extends PureComponent {
  render() {
    return (
      <div>
        <HashRouter>
          <Link to="/">首页</Link>
          <Link to="/about">关于</Link>
          <Link to="/profile">我的</Link>
          <Route exact path="/" component={Home}/>
          <Route exact path="/about" component={About}/>
          <Route exact path="/profile" component={Profile}/>
        </HashRouter>
      <div>
     )
   }
}

export default class About extends PureComponent {
  render() {
    return (
      <div>
        {/* 这里默认展示企业历史*/}
        <NavLink exact to="/about" >企业历史</NavLink>
       {/*子路由的路径需要写全*/}
        <NavLink exact to="/about/culture" >企业文化</NavLink>
        <NavLink exact to="/about/contact" >联系我们</NavLink>
        <Switch>
          {/* 如果不加 exact 进行精准匹配,那么所有子路由的都能匹配到/about, 这样的话就只能展示AboutHisotry组件了*/}
          <Route exact path="/about" component={AboutHisotry}/>
          <Route path="/about/culture" component={AboutCulture}/>
          <Route path="/about/contact" component={AboutContact}/>
        </Switch> 
      </div>
    )
  }
}
手动路由跳转
class About extends PureComponent {
  render() {
    return (
      <div>
        <NavLink exact to="/about" >企业历史</NavLink>
        <NavLink exact to="/about/culture" >企业文化</NavLink>
        <NavLink exact to="/about/contact" >联系我们</NavLink>
        <button onClick={e => this.jumpToJoin()}>加入我们</button>

        <Switch>
          <Route exact path="/about" component={AboutHisotry}/>
          <Route path="/about/culture" component={AboutCulture}/>
          <Route path="/about/contact" component={AboutContact}/>
          <Route path="/about/join" component={AboutJoin}/>
        </Switch> 
      </div>
    )
  }

  jumpToJoin() {
    this.props.history.push("/about/join");
  }
}
参数传递
动态路由
{/* 设置路由匹配路径*/}
<Route exact path="/detail/:id" component={About}/>
{/* 传递参数 id*/}
<NavLink to={`/detail/${id}`} a>详情</NavLink>
{/* 取出传递的 id*/}
const id = this.props.match.params.id;
search 传递参数
Link 中使用 to 传递对象
<Route path="/detail" component={Detail} />

<NavLink to={{
      pathname: "/detail",
      state: {name:"zhangsan", age=18} 
}}> 详情3</NavLink>

const name = this.props.location.state.name; //取出传递的 name 值

pathname: A string representing the path to link to.
search: A string representation of query parameters.
hash: A hash to put in the URL, e.g. #a-hash.
state: State to persist to the location.

react-router-config 库

安装
使用
import Home from '../pages/home';
import About, { AboutHisotry, AboutCulture, AboutContact, AboutJoin } from '../pages/about';
import Profile from '../pages/profile';

const routes = [
  {
    path: "/",
    exact: true,
    component: Home
  },
  {
    path: "/about",
    component: About,
    routes: [
      {
        path: "/about",
        exact: true,
        component: AboutHisotry
      },
      {
        path: "/about/culture",
        component: AboutCulture
      },
      {
        path: "/about/contact",
        component: AboutContact
      },
    ]
  },
  {
    path: "/profile",
    component: Profile
  },
]
export default routes;
import React, { PureComponent } from 'react';
import { renderRoutes } from 'react-router-config';
import routes from './router'; // 如果是 index.js 可以省略,默认导入的就是 index.js
class App extends PureComponent {
  render() {
    return (
      <div>
        <NavLink exact to="/" >首页</NavLink>
        <NavLink to="/about" >关于</NavLink>
        <NavLink to="/profile" >我的</NavLink>
        {/* 使用renderRoutes 渲染 routes*/}
        {renderRoutes(routes)}
      </div>
    )
  }
}

export default withRouter(App);
import React, { PureComponent } from 'react'
import { NavLink } from 'react-router-dom';
import { renderRoutes } from 'react-router-config';

export function AboutHisotry(props) {
  return <h2>企业成立于2000年, 拥有悠久的历史文化</h2>
}

export function AboutCulture(props) {
  return <h2>创新/发展/共赢</h2>
}

export function AboutContact(props) {
  return <h2>联系电话: 020-68888888</h2>
}

export default class About extends PureComponent {
  render() {
    return (
      <div>
        <NavLink exact to="/about" >企业历史</NavLink>
        <NavLink exact to="/about/culture" >企业文化</NavLink>
        <NavLink exact to="/about/contact" >联系我们</NavLink>

        {renderRoutes(this.props.route.routes)}
      </div>
    )
  }
}
上一篇 下一篇

猜你喜欢

热点阅读