react中的路由使用

1、分析路由自己实现需要满足的是:
(1)改变URL,但是页面不要进行强制刷新(a标签会进行页面的自动刷新)
(2)自己来监听URL的改变,并且改变之后自己改变页面的内容
2、监听hash来实现
hase的特点是再url后加上#
在这里插入图片描述
设置a标签如下:

  <div id="app">
    <a href="#/home">首页</a>
    <a href="#/about">关于</a>

    <div class="router-view"></div>
  </div>

js代码监听url如下:通过location.hash来获取url#所带的值。

    // 获取router-view的DOM
    const routerViewEl = document.getElementsByClassName("router-view")[0];

    // 监听URL的改变
    window.addEventListener("hashchange", () => {
      switch (location.hash) {
        case "#/home":
          routerViewEl.innerHTML = "首页";
          break;
        case "#/about":
          routerViewEl.innerHTML = "关于";
          break;
        default:
          routerViewEl.innerHTML = "";
      }
    })

3、监听history来实现
给a标签绑定点击事件,并且在其中阻止默认行为。每一次点击就获取a标签的href属性,再将src属性放到history之中,再用location.pathname监听url的改变。将监听到url的部分封装一个函数,放入到a点击事件之中,可以在a标签的每一次进行点击的时候都调用监听函数。需要注意的是,进行点击之后,返回之后div内的内容不会改变,所以要添加一个监听函数当返回时也调用监听函数。

<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) {
        case "/home":
          routerViewEl.innerHTML = "首页";
          break;
        case "/about":
          routerViewEl.innerHTML = "关于";
          break;
        default:
          routerViewEl.innerHTML = "";
      }
    }

  </script>

</body>

4、router具体运用
(1)安装:

npm install react-router-dom

(2)
监听hash来实现=>对应BrowserRouter
监听history来实现=>对应HashRouter
Link:对应a标签,Route匹配Link展示组件。

        <BrowserRouter>
          <Link to="/">FIRST</Link>
          <Link to="/about">about</Link>
          <Link to="/home">home</Link>


          <Route path="/" component={Profile}/>
          <Route path="/about" component={About}/>
          <Route path="/home" component={Home}/>
        </BrowserRouter>

(3)模糊匹配:
点击Link的时候去匹配Route,to="/about"被模糊匹配所以path="/“也会被匹配到。也就是点击to=”/about"、to="/home"都会显示 path="/"匹配的组件。要实现精准匹配如下:加上exact

<Route exact path="/" component={Profile}/>

(4)NavLink
NavLink相比Link可以有activeStyle属性来设置选中时的css样式

<NavLink to="/about" activeStyle={{color: "red", fontSize: "30px"}}>

也可以自己定义NavLink的选中样式名,在css之中指定选中的样式

<NavLink exact to="/" activeClassName="link-active">首页</NavLink>

NavLink的样式也会存在模糊匹配
在这里插入图片描述

所以需要在NavLink中加入exact

(4)排他操作
Link匹配Rout的过程是匹配到合适的不会停止,会将所有能匹配的都显示出来。如下:
如果点击to="/about"的Link,匹配到的会有About和User,Route之中不写path时任何Link都可以匹配,算是一个兜底的存在。但是如果前面已经有匹配但是不会停止还会一直匹配,所以也会匹配大User.要进行排他的匹配可以使用到Switch

        <NavLink exact to="/" activeClassName="link-active">首页</NavLink>
        <NavLink to="/about" activeClassName="link-active">关于</NavLink>
        <NavLink to="/profile" activeClassName="link-active">我的</NavLink>
        <NavLink to="/abc" activeClassName="link-active">abc</NavLink>
        <Switch>
          <Route exact path="/" component={Home} />
          <Route path="/about" component={About} />
          <Route path="/profile" component={Profile} />
          <Route component={User} />
        </Switch>

(5)Redirect使用
前面的Link都需要交互点击才能跳转,Redirect可以自动进行跳转,使用场景是用户页面需要先判断是否已经登录,如果没有登录则就跳转到相关的loading的组件
user组件:

import React, { PureComponent } from 'react'
import { Redirect } from 'react-router-dom';

export default class User extends PureComponent {
  constructor(props) {
    super(props);

    this.state = {
      isLogin: true
    }
  }

  render() {
    return this.state.isLogin ? (
      <div>
        <h2>User</h2>
        <h2>用户名: coderwhy</h2>
      </div>
    ): <Redirect to="/login"/>
  }
}

user父组件app.js之中包括所有的Route

        <NavLink exact to="/" activeClassName="link-active">首页</NavLink>
        <NavLink to="/about" activeClassName="link-active">关于</NavLink>
        <NavLink to="/profile" activeClassName="link-active">我的</NavLink>
        <NavLink to="/abc" activeClassName="link-active">abc</NavLink>
        <NavLink to="/user" activeClassName="link-active">用户</NavLink>


        <Switch>
          <Route exact path="/" component={Home} />
          <Route path="/about" component={About} />
          <Route path="/profile" component={Profile} />
          <Route path="/user" component={User} />
          <Route path="/login" component={Login} />
          <Route component={NoMatch} />
        </Switch>

(6)路由的嵌套:
在about之中再嵌套路由,让路径是这种格式/about/culture。嵌套的路由需要写在这个组件里而不是写在父组件内。而且由于Switch只匹配一次,所以Rout path="/about"需要是exact。并且NavLink也需要设置exact,因为模糊匹配/about,都可以匹配上。

        <NavLink exact to="/about" activeClassName="about-active">企业历史</NavLink>
        <NavLink exact to="/about/culture" activeClassName="about-active">企业文化</NavLink>
        <NavLink exact to="/about/contact" activeClassName="about-active">联系我们</NavLink>

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

(7)手动实现跳转
上面的Link都是a标签,如果是图片点击或者按钮点击进行跳转就没办法运用Link,Rout是检测的URL的变化,可以自己实现一个点击函数在其中修改url就可以进行跳转。
下面这个Route操作对About组件有进行相关的操作,就例如传递封装过的history

<Route path="/about" component={About} />

再About之中可以手动实现跳转(props传递了history)

import React, { PureComponent } from 'react'
import {  Route } from 'react-router-dom';

export default class About extends PureComponent {
  render() {
    return (
      <div>
        <button onClick={e => this.jumpToJoin()}>加入我们</button>
          <Route exact path="/about" component={AboutHisotry}/>
          <Route path="/about/join" component={AboutJoin}/>

      </div>
    )
  }

  jumpToJoin() {
    // console.log(this.props.history);
    // console.log(this.props.location);
    // console.log(this.props.match);
    this.props.history.push("/about/join");
  }
}

需要注意的是需要Route之中处理的组件才有传入封装的history,如果在App.js使用手动跳转就没有这个history。此时需要使用到react-router-dom之中的withRouter高阶组件。

export default withRouter(App);

(8)路由传参
①通过url进行传参:

<NavLink to={`/detail2?name=why&age=18`} activeClassName="link-active">详情2</NavLink>

②更推荐如下传:

        const info = {name: "why", age: 18, height: 1.88};
        <NavLink to={{
                  pathname: "/detail3",
                  search: "name=abc",
                  state: info
                 }} 
                activeClassName="link-active">
          详情3
        </NavLink>

(9)react-router-config的使用
在前面需要有大段的Route来进行路由组件映射,使用react-router-config可以更加简便。

yarn add react-router-config

创建一个router文件夹下面只创建一个index.js文件编写如下:

import Home from '../pages/home';
import About, { AboutHisotry, AboutCulture, AboutContact, AboutJoin } from '../pages/about';
import Profile from '../pages/profile';
import User from '../pages/user';

const routes = [
  {
    path: "/",
    exact: true,
    component: Home
  },
  {
    path: "/about",
    component: About
  },
  {
    path: "/profile",
    component: Profile
  },
  {
    path: "/user",
    component: User
  }
]

export default routes;

原本在组件之中写Route的地方改为如下:

{renderRoutes(routes)}

但是如果是About之下的二级路由在index.js之中这样如下表示:

import Home from '../pages/home';
import About, { AboutHisotry, AboutCulture, AboutContact, AboutJoin } from '../pages/about';
import Profile from '../pages/profile';
import User from '../pages/user';

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: "/about/join",
        component: AboutJoin
      },
    ]
  },
  {
    path: "/profile",
    component: Profile
  },
  {
    path: "/user",
    component: User
  }
]

export default routes;

需要注意的是二级路由的Rout处如下表示:
下方的this.props.route是index.js文件之中的如下对象

  {
    path: "/about",
    component: About,
    routes: [
      {
        path: "/about",
        exact: true,
        component: AboutHisotry
      },
      {
        path: "/about/culture",
        component: AboutCulture
      },
      {
        path: "/about/contact",
        component: AboutContact
      },
      {
        path: "/about/join",
        component: AboutJoin
      },
    ]
  },

所以如下就可以获取到二级路由信息

renderRoutes(this.props.route.routes)
  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
React Native 常用的路由库有 React Navigation 和 React Native Router Flux。 React Navigation 提供了多种路由类型,如 Stack Navigator、Tab Navigator、Drawer Navigator 等,可以根据不同的业务场景选择合适的路由类型。以下是一个使用 Stack Navigator 的示例: 1. 安装依赖: ``` npm install @react-navigation/native @react-navigation/stack ``` 2. 在 App.js 文件引入依赖: ```jsx import { NavigationContainer } from '@react-navigation/native'; import { createStackNavigator } from '@react-navigation/stack'; ``` 3. 创建一个 Stack Navigator: ```jsx const Stack = createStackNavigator(); function App() { return ( <NavigationContainer> <Stack.Navigator> <Stack.Screen name="Home" component={HomeScreen} options={{ title: 'Home' }} /> <Stack.Screen name="Details" component={DetailsScreen} options={{ title: 'Details' }} /> </Stack.Navigator> </NavigationContainer> ); } ``` 4. 在组件使用路由: ```jsx import { useNavigation } from '@react-navigation/native'; function HomeScreen() { const navigation = useNavigation(); return ( <Button title="Go to Details" onPress={() => navigation.navigate('Details')} /> ); } ``` 在上面的示例,当点击按钮时,会跳转到名为 "Details" 的页面。可以在 options 设置页面标题等属性。 React Native Router Flux 的使用方式与 React Navigation 类似,都是创建路由,然后在组件使用。不同的是,React Native Router Flux 采用了类似于 React Router路由配置方式,需要在顶层组件进行配置。具体使用方式可以查看官方文档。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值