vue-router 和 react-router

726 阅读1分钟

react-router 设计上和 vue-router 一样

三种模式

memory history

不修改 url ,路由地址在内存中,但页面刷新会重新回到首页

browser history

  • 使用history.pushState来改 url
  • 使用window.onpopstate监听url,
  • 需要后端nginx配合返回index.html

hash history

使用 url hash 变化记录路由地址

// hash路由 --> http://127.0.0.1:8881/hash.html?a=100&b=20#/aaa/bbb
location.protocol // 'http:'
location.hostname // '127.0.0.1'
location.host // '127.0.0.1:8881'
location.port // '8881'
location.pathname // '/hash.html'
location.search // '?a=100&b=20'
location.hash // '#/aaa/bbb'

路由懒加载

vue

export default new Router({
  routes: [
    {
      path: '/',
      redirect:'/goods'  //重定向
    },
    {
      path: '/goods',
      name: 'goods',
      component: ()=>import('@/pages/goods') // <<=======================================
    },
    {
      path: '/ratings',
      name: 'ratings',
      component: ()=>import('@/pages/ratings') // <<======================================= 
    },
    {
      path: '/seller',
      name: 'seller',
      component: ()=>import('@/pages/seller') // <<=======================================
    },
  ]
})

react-router 6
Suspense: 懒加载完成前现实的类容

import "./styles.css";
import { BrowserRouter } from "react-router-dom";
import { Navigate, Route, Routes } from "react-router";
import { Link } from "react-router-dom";
import { lazy, Suspense } from "react";

function LazyComponent(path: string) {
  const C = lazy(() => import(path));
  return (
    <Suspense fallback={<div>loading...</div>}>
      <C />
    </Suspense>
  );
}

const Home = LazyComponent("./home");
const Detail = LazyComponent("./detail");

export default function App() {
  return (
    <BrowserRouter>
      <Link to="/home">-home-</Link>
      <Link to="/detail">-detail-</Link>

      <Routes>
        <Route path="/home" element={Home} />
        <Route path="/detail" element={Detail} />
        <Route path="*" element={<Navigate to="/home" replace={true} />} />
      </Routes>
    </BrowserRouter>
  );
}

路由守卫

登录验证

import Router from 'vue-router'

const router = new Router({
    routers: [
        {path: '/', name: 'home', component: Home}
        ...
        ...
    ]
})

router.beforeEach((to, from, next) => {
  const isLogin = localStorage.eleToken ? true : false;
  if (to.path == "/login" || to.path == "/register") {
    next();
  } else {
    isLogin ? next() : next("/login");
  }
})

// 所有的页面跳转之后
router.afterEach((to, from, next) => {

})

局部守卫

在路由配置文件使用

import Home from '../views/Home'

export default [
    {
        path: '/',
        alias: '/home',
        name: 'home',
        component: Home,
        // 参数1 : to表示要跳转到的路由
        // 参数2 : from表示要离开的路由
        // 参数3 : next
        beforeEnter: (to, from, next) => {
            if(from.path==="login") alert('这是从登录页来的')
            next() // 注意: 在你的所有逻辑处理完以后一定要调用 next 函数, 否则页面是不会成功跳转的
        }
    },
    ...
    ...
]

组件内使用

    export default {
        data: () => ({

        }),
        methods: {

        },
        // 这是路由的钩子函数
        // 注意 : 这里面不要用this, 因为这时组件还没有被实例化
        beforeRouteEnter(to, from, next) {
            alert(from.path)
            next()
        },
        // 注意 : 这里可以使用this
        beforeRouteLeave(to, from, next) {
            const will_leave = confirm('你确定要离开吗?')
            if(will_leave) next()
            else next(false)
        },
        // 当路由发生变化, 组件被复时触发
        // 例如 : 详情页面之间的跳转('detail/123' ==> 'detail/456')
        // 注意 : 这里可以使用this
        beforeRouteUpdate(to, from, next) {

        },
    }