前端路由History 和 Hash模式的区别以及Vue项目打包后显示白屏,路由router-view不加载问题


前言

什么是前端路由?前端路由有什么作用呢?前端路由又是如何实现的?常见的路由模式HistoryHash又有什么区别呢?VueRouter又是如何实现的?我们的日常项目又该怎么使用呢?我们再来一次,这一次我们好好来~

一、什么是前端路由?

前端路由是指在单页面应用(SPA,Single Page Application)中,通过前端实现页面跳转和页面内容更新的一种机制。与服务器端路由不同,前端路由不需要重新加载整个页面,而是通过动态加载页面内容来实现页面的切换,从而提高用户体验和应用的响应速度。

前端路由,简单来说,就是在不刷新整个页面的情况下,改变网页的 URL 并展示不同的内容

通常来讲,我们打开浏览器浏览一个网站的时候,点击不同的链接、按钮,页面会跳转到不同的内容,但是页面却没有进行完整的刷新,这就是前端路由在起作用。

二、前端路由的作用

  1. 无刷新页面跳转: 用户在应用中切换页面时,不需要重新加载整个页面,而是通过动态加载页面内容实现。
  2. URL管理: 每个页面的URL都与实际内容相对应,便于用户访问和分享。
  3. 组件化: 每个路由对应一个组件,当路由被激活时,对应的组件会被加载和渲染。
  4. 性能提升: 避免了页面的重新加载,前端路由可以减少服务器请求和网络传输,从而提高应用的性能和响应速度。
  5. 安全性: 通过路由守卫(如权限验证),前端路由可以进行访问校验,防止未授权访问。
  6. 历史管理: 前端路由可以管理浏览器的历史记录,支持前进和后退操作,使得用户在浏览过程中可以像访问传统多页面应用一样使用浏览器的前进和后退功能。
  7. SEO友好: 通过服务器端渲染(SSR)预渲染(Prerendering)技术在服务端生成静态的HTML页面,从而提高搜索引擎的访问度。但是URL 的哈希部分不会被搜索引擎索引。

三、前端路由是如何实现的?

1. 关键步骤

  1. 监听URL 变化: 当用户点击链接或进行其他操作时,前端路由会监听 URL 的变化。
  2. 根据路由规则匹配页面: 前端路由会根据当前的 URL 匹配预先定义好的路由规则,例如:
    /about 对应关于我们页面
    /products 对应产品列表页面
  3. 渲染对应内容: 根据匹配到的路由规则,前端路由会动态地渲染对应的内容,并将渲染结果展示在页面上。

2. 结合Vue框架中的Vue Router内部实现

2.1 使用 history 模式

Vue Router history 模式的内部实现主要依赖于浏览器的 history API,尤其是 history.pushStatehistory.replaceState 方法。

  1. 配置路由规则匹配页面
const router = new VueRouter({
  mode: 'history', // 启用 history 模式
  routes: [
    { path: '/', component: Home },
    { path: '/about', component: About },
    { path: '/contact', component: Contact },
    { path: '/*', component: NotFound } // 404 路由
  ]
});
  1. 修改URL

(1) 点击浏览器的前进或后退按钮
popstate 事件只会在浏览器某些行为下触发,点击浏览器的前进或后退按钮时(或者在 JavaScript 中调用 history.back() 方法)

// 监听 popstate 事件
window.addEventListener('popstate', (event) => {
  router.push(location.pathname);
});

(2) 使用 pushState 和 replaceState 改变 URL

用户点击一个路由链接或通过编程式导航(如 this.$router.push)跳转时,Vue Router 会使用 history.pushStatehistory.replaceState 来改变 URL:

// 编程式导航
this.$router.push('/about');

// 相当于
history.pushState({}, '', '/about');

(3) 直接在地址栏修改URL
这就涉及到另一个问题,也就是在浏览器输入URL会发生什么,这个我们后面再讲!

  1. 根据路由规则匹配页面
    URL 变化时,路由库会根据定义的路由规则找到匹配的页面或组件,一旦匹配成功,Vue Router 会将对应的组件渲染到 <router-view> 组件的位置。这通常涉及到以下步骤:
    • 匹配 URL: 路由库会检查当前 URL 与定义的路由规则,找到匹配的路由。
    • 加载组件: 一旦找到匹配的路由,路由库会加载对应的组件,并将其插入到 DOM 中。
  2. 路由守卫
    路由守卫机制,允许你在路由跳转前后执行一些操作。路由守卫可以访问路由对象,执行权限验证、数据获取等操作:
const router = new VueRouter({
  mode: 'history',
  routes: [
    {
      path: '/about',
      component: About,
      beforeEnter: (to, from, next) => {
        // 执行权限验证
        if (userCanAccess) {
          next();
        } else {
          next('/unauthorized');
        }
      }
    }
  ]
});

2.2 使用 hash模式

利用 URL 的哈希部分(即 # 后面的部分)来进行路由的识别和跳转。这种模式不需要服务器配置,适合简单的单页面应用(SPA)。

  1. URL 哈希部分: URL 的哈希部分(# 后面)通常被浏览器忽略,不会触发页面的重新加载。因此,可以通过改变哈希部分来实现页面内容的动态加载。

  2. 监听哈希变化: Vue Router 监听 URL 哈希的变化,当哈希变化时,触发路由的匹配和组件的渲染。

window.addEventListener('hashchange', () => {
  router.push(window.location.hash);
});
  1. 路由匹配: 根据哈希部分的内容,Vue Router 匹配对应的路由规则,并渲染相应的组件。
import Vue from 'vue';
import VueRouter from 'vue-router';

Vue.use(VueRouter);

const router = new VueRouter({
  mode: 'hash', // 使用 hash 模式
  routes: [
    { path: '/', component: Home },
    { path: '/about', component: About },
    { path: '/contact', component: Contact }
  ]
});

四、HistoryHash的区别

特性history 模式hash 模式
URL 形式正常 URL(http://www.example.com/about)带有 # 号的 URL(http://www.example.com/#/about)
工作原理依赖于浏览器 HTML5 History API利用 URL 中 # 号后的部分来标识不同的页面
服务器配置需要设置 catch-all 路由,将所有的 URL 请求都转发到 index.html,访问URL 时应用入口文件(通常是 index.html)再让前端路由接管后续的路由处理所有的路由处理都在前端完成
SEO友好不利于 SEO(URL 的哈希部分不会被搜索引擎索引)
用户体验更接近传统网页浏览可能存在一些兼容性问题
开发效率需要服务器端配合不需要服务器端配置

五、日常项目使用建议

优先选择 History 模式: 如果你的项目对 SEO 有要求,并且服务器端可以配置 catch-all 路由,建议优先选择 History 模式。
考虑 Hash 模式: 如果你的项目对 SEO 要求不高,或者无法进行服务器端配置,可以使用 Hash 模式。
注意刷新页面问题: 无论选择哪种模式,都要注意处理刷新页面导致的页面跳转问题。可以使用 history.pushState 或者 history.replaceState 方法来控制浏览器历史记录,避免页面跳转。

六、Vue项目打包后显示白屏,路由router-view不加载问题

1. 原因分析

  1. history 模式需要服务器支持进行正确的 URL 重写,而直接打开文件无法提供这种支持。页面不会重新加载,router-view不会被挂在到网页上。

  2. history 模式的路由在是浏览器中没有 #(哈希符号)的情况下使用常规的 URL,例如,http://example.com/user/id。但是当直接在文件系统中打开 index.html 文件时,浏览器无法处理理解文件路径(例如 file:///path/to/index.html/user/id),导致路由无法正确解析和加载。但是hash 模式在 URL 中使用 # 符号来模拟完整的 URL,浏览器不需要服务器端配置即可处理。

  3. 当使用 history 模式时,Vue Router 使用常规的 URL 进行导航,而不是带有 # 的哈希 URL。这意味着如果用户直接在浏览器中输入一个 URL,服务器必须返回 index.html 文件。这就需要服务器进行 URL 重写,确保所有路由都指向 index.html,由 Vue Router 处理客户端路由。

2. 解决方案

改为hash模式即可正常加载。hash 模式使用 URL 的哈希部分 (#) 进行路由,所以不需要服务器支持重写规则。

// src/router/index.js
import { createRouter, createWebHashHistory } from 'vue-router';
import Home from '../views/Home.vue';
import About from '../views/About.vue';

const routes = [
  {
    path: '/',
    name: 'Home',
    component: Home
  },
  {
    path: '/about',
    name: 'About',
    component: About
  }
];

const router = createRouter({
  history: createWebHashHistory(),
  routes
});

export default router;

总结一下

前端路由单页应用程序(SPA)中扮演着关键角色,通过在不重新加载整个页面的情况下更新 URL 并渲染不同的视图,实现平滑的页面导航和状态管理。这种技术不仅提升了用户体验,使应用响应更加迅速,还简化了前端开发流程。前端路由在很多前端框架(如 VueReactAngular)中广泛应用,允许开发者构建功能丰富、动态更新的 Web 应用,实现类似多页应用的导航效果,同时保留单页应用的高效性。前端路由通常使用两种模式:history 模式hash 模式history 模式使用浏览器的 History API 来管理路由,而 hash 模式则通过 URL 的哈希部分(#)来实现路由。这两种模式各有优缺点,根据具体需求选择合适的模式尤为重要。

  • 8
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小小前端--可笑可笑

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值