Vue是如何实现单页应用的

  • new Router({})配置 mode 参数,mode值可选hash或者History

  • hash模式

    • hash(#)URL的锚点,同时每一次改变#后的部分,都会在浏览器的访问历史中增加一个记录,使用”后退”按钮,就可以回到上一个位置;但不会对服务端请求数据。
    • 使用hashchange()监听hash值变化,使用window.location.href重新赋值。
      • 用法实例
      // 对hash值变化进行监听
      window.onhashchange = function(e) {
        // 实现页面显示隐藏
        switch(e) {
          case e === 'index':
            window.location.href = 'index.html';
            break;
          ...
          default:
            console.log(`Sorry, we are out of ${e}.`);
        }
      }
      
  • History模式

    • 使用 HTML5 History 中提供的一种功能,能在不刷新页面的情况下修改URL, 使用History.pushState()实现URL跳转无需刷新。
      • pushState新建历史记录 和replaceState修改历史记录 两个API以及浏览器的 popState事件监听 历史栈的改变,只要历史栈有信息发生改变,就会触发该事件。这种模式同样也是不会向后端发起请求的。
      • 用法实例
      // History变化事件监听
      window.onpopstate = function(e) {
        alert(2);
      }
      
      // 状态对象
      let stateObj = {
          foo: "bar",
      };
      
      /*
      * @description pushState - 新建历史记录 replaceState - 修改历史记录
      * @params stateObj {Object} 状态对象state是一个JavaScript对象
      * @params title {String} 标题
      * @params URL {String} URL地址 新URL必须与当前URL同源
      */
      history.pushState(stateObj, "page 2", "bar.html");
      
      history.replaceState(stateObj, "page 3", "bar2.html");
      
      • window.history.forward() == window.history.go(1); -- 前进。
      • window.history.back() == window.history.go(-1); -- 后退。
    • 但当用户直接在用户栏输入地址并带有参数时
      • Hash模式:xxx.com/#/id=5 请求地址为 xxx.com,没有问题。

      • History模式: xxx.com/id=5 请求地址为 xxx.com/id=5,如果后端没有对应的路由处理,就会返回404错误。

      • 前端解决办法: 在路由拦截(router.beforEach(async(to, from, next)=>{}))里判断,如果没有匹配的路由,跳转默认的index.html页面。

        • 有个问题不再返回 404 页面,所以后端处理比较好。
      • 后端解决办法:

        • 在服务端增加一个覆盖所有情况的候选资源:如果 URL 匹配不到任何静态资源,则应该返回同一个 index.html 页面,这个页面就是你 app 依赖的页面。
        • 给个警告,因为这么做以后,你的服务器就不再返回 404 错误页面,因为对于所有错误路径都会返回 index.html 文件。为了避免这种情况,你应该在 Vue 应用里面覆盖所有的路由情况,然后再给出一个 404 页面。或者,如果你使用 Node.js 服务器,你可以用服务端路由匹配到来的 URL,并在没有匹配到路由的时候返回 404,以实现回退。
posted @ 2022-04-21 13:54  lutwelve  阅读(264)  评论(0编辑  收藏  举报