页面跳转

29 阅读1分钟

一、浏览器原生路由跳转方式

1. HTML标签跳转(<a>标签)
  • 用法
    <a href="/target-page" target="_self/_blank/_parent/_top">跳转链接</a>
    
  • 特点
    • 触发完整页面刷新,浏览器记录历史栈;
    • 可通过download属性实现文件下载(如<a href="file.pdf" download>)。
2. window.location API
  • 常用方法
    • location.href = "/new-path":最直接的跳转,等价于<a>标签点击;
    • location.assign("/new-path"):跳转并记录历史,可回退;
    • location.replace("/new-path"):跳转但不记录历史,不可回退(用于登录页跳转);
    • location.reload():刷新当前页面(可传true强制从服务器加载)。
  • 应用场景
    • 跨域跳转(如跳转到第三方网站);
    • 页面重定向(如登录成功后跳转到首页)。
3. history API(HTML5新增)
  • 核心方法
    // 1. 新增历史记录
    history.pushState(state, title, url);
    // state:存储状态数据,可通过history.state获取;
    // url:新的URL(需与当前域名同源)。
    
    // 2. 修改当前历史记录
    history.replaceState(state, title, url);
    
    // 3. 浏览器前进/后退
    history.forward(); // 前进
    history.back();    // 后退
    history.go(-2);    // 回退2步
    
  • 特点
    • 跳转时不刷新页面,实现前端路由(SPA必备);
    • 配合popstate事件监听URL变化(如window.addEventListener('popstate', callback))。

二、前端框架中的路由跳转(Vue/React)

1. Vue Router 跳转方式
  • 编程式导航(JS跳转)

    // 引入router实例(通常为this.$router)
    import { useRouter } from 'vue-router';
    const router = useRouter();
    
    // 1. 普通跳转
    router.push('/home'); // 新增历史记录,可回退
    router.replace('/login'); // 替换当前记录,不可回退
    
    // 2. 带参数跳转
    // 路径参数
    router.push('/user/123'); // URL显示为/user/123
    //  query参数
    router.push({ path: '/search', query: { keyword: 'apple' } }); // URL显示为/search?keyword=apple
    
    // 3. 命名路由跳转
    router.push({ name: 'user', params: { id: 123 } }); // 对应路由配置{ name: 'user', path: '/user/:id' }
    
    // 4. 导航守卫控制跳转
    router.beforeEach((to, from, next) => {
      if (to.meta.requiresAuth) {
        // 权限校验
        next(); // 允许跳转
        // next('/login'); // 重定向到登录页
      }
    });
    
  • 声明式导航(标签跳转)

    <!-- 等价于<a href="/home">,但不会刷新页面 -->
    <router-link to="/home">首页</router-link>
    <router-link :to="{ name: 'user', params: { id: 123 } }">用户详情</router-link>
    
2. React Router 跳转方式
  • 编程式导航(依赖useNavigate钩子)

    import { useNavigate } from 'react-router-dom';
    const navigate = useNavigate();
    
    // 1. 普通跳转
    navigate('/dashboard'); // 新增历史记录
    navigate('/login', { replace: true }); // 替换当前记录
    
    // 2. 带参数跳转
    navigate('/product/123'); // 路径参数
    navigate('/search', { state: { keyword: 'book' } }); // 状态参数(通过location.state获取)
    
    // 3. 条件跳转(如登录校验)
    if (!isLoggedIn) {
      navigate('/login', { replace: true });
    }
    
  • 声明式导航(标签跳转)

    // 等价于<a href="/about">,但由React Router控制
    <Link to="/about">关于我们</Link>
    <Link to={{ pathname: '/product/123', state: { from: 'home' } }}>商品详情</Link>
    

三、路由跳转的性能与场景优化

1. 前端路由(SPA)vs 后端路由(多页面)
对比维度前端路由(如Vue/React Router)后端路由(传统HTML跳转)
跳转体验无页面刷新,体验流畅(仅更新部分DOM)全页面刷新,有白屏时间
首次加载性能需加载JS框架和路由配置,首屏加载可能较慢直接返回HTML,首屏渲染快
SEO支持需额外配置(如SSR),搜索引擎抓取困难原生支持,SEO友好
适用场景交互复杂的应用(如管理系统、电商平台)内容型网站(如新闻、博客)
2. 路由懒加载(性能优化核心)
  • 目的:避免一次性加载所有页面JS,减少首屏加载时间。
  • 实现方式
    // Vue Router 懒加载(ES6动态导入)
    const router = new VueRouter({
      routes: [
        {
          path: '/user',
          // 仅当访问/user时才加载User.vue
          component: () => import('./views/User.vue')
        }
      ]
    });
    
    // React Router 懒加载(配合React.lazy和Suspense)
    import { lazy, Suspense } from 'react';
    const UserPage = lazy(() => import('./pages/UserPage'));
    
    <Suspense fallback={<div>加载中...</div>}>
      <Route path="/user" element={<UserPage />} />
    </Suspense>
    
3. 导航守卫与异常处理
  • 场景
    • 登录校验(如跳转需要权限的页面时重定向到登录页);
    • 防止未保存表单数据时跳转(通过beforeRouteLeave询问用户)。
  • 示例(Vue Router)
    // 组件内守卫
    export default {
      beforeRouteLeave(to, from, next) {
        if (formIsDirty) {
          confirm('确定离开吗?未保存的数据将丢失') ? next() : next(false);
        } else {
          next();
        }
      }
    }
    

四、问题

1. 问:history.pushState和location.href有什么区别?
    • location.href会触发完整页面刷新,而pushState仅修改URL且不刷新页面(前端路由核心原理);
    • pushState可操作历史栈(如新增记录或替换),配合popstate事件能实现无刷新跳转;
    • 注意:pushState修改的URL需与当前域名同源,否则会报错。
2. 问:前端路由中path和hash的区别是什么?
    • URL格式
      • hash模式:URL包含#(如https://example.com/#/home),#后的内容为hash值;
      • path模式(history模式):纯路径(如https://example.com/home),需后端配置支持(防止404)。
    • 底层原理
      • hash变化会触发hashchange事件,浏览器不会将hash发送到服务器;
      • history模式通过pushState修改URL,需后端配置将所有路径重定向到首页(如Nginx配置try_files $uri $uri/ /index.html)。
    • 应用场景
      • hash模式:兼容性好(支持IE8+),无需后端配置;
      • history模式:URL更美观,适合需要SEO的场景(但需后端配合)。
3. 问:如何实现页面跳转后滚动到顶部?
    • Vue Router:在router.js中配置scrollBehavior
      const router = new VueRouter({
        scrollBehavior(to, from, savedPosition) {
          return { top: 0 }; // 每次跳转都滚动到顶部
        }
      });
      
    • React Router:在路由组件中监听location变化并滚动:
      import { useLocation } from 'react-router-dom';
      import { useEffect } from 'react';
      
      useEffect(() => {
        window.scrollTo(0, 0);
      }, [location]);