前端路由(history+hash)

更新日期: 2020-02-28阅读: 2k标签: 路由

在传统网站开发中,我们一般使用比如asp、php、jsp等技术进行开发,开发完成后统一部署在服务器上,我们访问时,会在浏览器中发送带有'.asp','.php','.jsp'等后缀路径的url请求,服务器会根据对应的路由映射表,找到我们请求的页面并渲染成html,然后把HTML页面直接返回给浏览器展示,这就是所谓的服务器端渲染SSR(Server Side Render)。

然而随着前端页面复杂性的提高以及前端技术的兴起(尤其是Ajax技术的兴起),行业内越来越推崇前后端分离的开发模式。使服务器端不在关注HTML页面的渲染,而是只专注于逻辑的开发,通过api提供数据;前端只专注于UI的开发,把从服务器请求的数据生成dom插入到页面中去。从服务器请求数据,然后由客户端通过前端技术生成展示页面的方式就是客户端渲染CSR(Client Side Render)。

客户端渲染使前后端进行了分离,各自只关注属于自己的部分,并且使用户体验也得到了提升,用户交互不用每次都刷新页面。基于这些优点,单页应用(SPA(Single Page Web Application))的开发模型备受青睐。可以做到动态重写当前页面来与用户交互,而不需要重新加载整个页面。然而要实现单页应用,做到交互和跳转都不需要刷新的体验,需要解决一个重要问题,就是路由问题。所以就有了前端路由,其实前端路由是相对于服务器端路由的称谓,由前端控制维护url和UI之间的映射关系,url更改后引起ui更新,而无需刷新页面。

下面就让我们通过两种方式实现前端路由:

实现前端路由的整体思路:首先维护一张包含path和对应的页面内容的路由映射表,当监听到路由发生变化后,从路由映射表中筛选出对应的路由信息,并把路由信息中对应的内容页面渲染添加到html页面展示。开始之前先了解下两种方式的基本知识。


1.window.history

Window.history是一个只读属性,用来获取包含操作浏览器会话历史History 对象。
主要方法:
back()
前往上一页, 用户可点击浏览器左上角的返回按钮模拟此方法. 等价于 history.go(-1)
forward()
在浏览器历史记录里前往下一页,用户可点击浏览器左上角的前进按钮模拟此方法. 等价于 history.go(1)
go()
通过当前页面的相对位置从浏览器历史记录( 会话记录 )加载页面
pushState()
按指定的名称和URL(如果提供该参数)将数据push进会话历史栈,数据被DOM进行不透明处理;你可以指定任何可以被序列化的javascript对象。
replaceState()
按指定的数据,名称和URL(如果提供该参数),更新历史栈上最新的入口。这个数据被DOM 进行了不透明处理。你可以指定任何可以被序列化的javascript对象。


2.location.hash

hash 属性是一个可读可写的字符串,该字符串是 URL 的锚部分(从 # 号开始的部分)。

实现代码如下:

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>window.history路由</title>
</head>

<body>
  <div>
    <div id="routerLink">
      <div>
        <button onclick="historyChange('home')">首页(history)/button>
          <button onclick="historyChange('about')">关于(history)</button>
      </div>
      <div>
        <button onclick="hashChange('home')">首页(hash)</button>
        <button onclick="hashChange('about')">关于(hash)</button>
      </div>
    </div>
    <div>
      <div id="routerView">

      </div>
    </div>
  </div>
  <!-- 2.创建子视图模板 -->
  <template id="home">
    <div>hello,我是首页</div>
  </template>
  <template id="about">
    <div>hello,我是关于</div>
  </template>
  <script>
    //1.首先创建路由表
    const routerTable = [
      {
        path: 'home',
        component: '#home'
      },
      {
        path: 'about',
        component: '#about'
      }
    ]

    //*********** 方式一:window.history **************
    //3.(window.history)监听路由更改,根据新路由path加载对应的内容
    function historyChange(path) {
      render({ path: path })
    }
    //添加popstate状态监听
    window.addEventListener('popstate', function (e) {
      if (e) {
        render({ path: e.state, isPush: false })
      }
    })

    //************** 方式二:location.hash ***************
    function hashChange(path) {
      render({ path: path, mode: 'hash' })
    }
    //添加hashchange监听
    window.addEventListener('hashchange', function () {
      let path = location.hash
      //path移除开始的#
      render({ path: path.substring(1, path.length - 2), mode: 'hash' })
    })

    //**************公共方法*******************
    //渲染方法
    function render(data) {
      //默认值,mode默认为history,isPush=true,isReplace=false,path=home
      data = Object.assign({ mode: 'history', isPush: true, isReplace: false, path: 'home' }, data)
      if (data.path) {
        //查询路由信息
        const route = routerTable.find(p => p.path == data.path);
        if (route) {
          if (data.mode == 'history') {
            if (data.isPush) {
              //更改url---后退、前进不更改
              if (data.isReplace) {
                window.history.replaceState(data.path, '', data.path)
              } else {
                window.history.pushState(data.path, '', data.path)
              }
            }
          } else if (data.mode == 'hash') {
            location.hash = data.path
          }
          //更新html
          document.querySelector("#routerView").innerHTML = document.querySelector(route.component).innerHTML
        }
      }
    }
  </script>
</body>
</html>

PS:需要用http的方式运行页面,要不然pushState是无法使用的,会报:cannot be created in a document with origin 'null'的错误。
不过如果你电脑上已经安装了vscode,可以下载Live Server插件,来运行html文件。

链接: https://www.fly63.com/article/detial/8781

vue路由history模式_如何去除vue项目中的#

在使用vue-cli搭建的环境中,浏览器上URL地址中是存在#的,这是由于vue-router 默认 hash 模式,不难发现#的出现真的很丑陋。官网给出了如何使用history模式mode: history

vue路由传参主要的3种方式

vue中路由传参主要的3种方式:query方式(push时使用path来匹配)、params模式(push时使用name来匹配)、location预声明参数模式(push使用path来匹配,但是它跟params模式不同)

vue动态加载路由_实现vue动态加载路由器设置

我们的通用的后台管理系统中,我们会根据权限的粗细不同,会对每个角色每个权限每个资源进行控制。同样的我们也需要实现一个这样的功能。 这篇文章我将主要讲vue端的实现,关于后台接口我就不会涉及,当我接触的时候我们的后台接口是springcloud实现。

两种前端路由的实现方式

前后端分离开发模式,后端会把路由控制丢在前端,这几天再开发单页面小的项目,手动撸了个路由。前端路由实现有两种方法。HTML5 History API包括2个方法:history.pushState()和history.replaceState(),和1个事件:window.onpopstate。hash + location.onhashchange

vue动态路由_vue-router通过接口请求动态生成路由的实现

在后台管理系统中,一般都会采用权限管理。路由菜单数据都会保存到数据库中,在vue-router 2.2版本新增了一个router.addRoutes(routes)方法,即可用它来实现动态路由了

HTML5 History 模式

vue-router 默认 hash 模式 —— 使用 URL 的 hash 来模拟一个完整的 URL,于是当 URL 改变时,页面不会重新加载。如果不想要很丑的 hash,我们可以用路由的 history 模式,这种模式充分利用 history.pushState API 来完成 URL 跳转而无须重新加载页面。

vue router 路由鉴权(非动态路由)

原本想用动态路由的思路去做,按权限加载对应路由表,但是由于权限可以交叉(比如一个人可以同时是主题管理员和数据服务管理员),导致权限路由表还是得去做判断组合。于是放弃了这个思路,索性就在beforeEach里直接判断了。

vue中路由按需加载的几种方式

使用vue-cli构建项目后,我们会在Router文件夹下面的index.js里面引入相关的路由组件,webpack在打包的时候会把整个路由打包成一个js文件,如果页面一多,会导致这个文件非常大,加载缓慢

vue-router 中参数传递(params,query)

query和params的区别,query相当于get请求,在页面跳转的时候,可以在地址栏看到请求参数,然而params则相当于post请求,参数不会在地址栏中显示。

Node.js的路由

当服务端接收到HTTP请求时,可以通过onRequest() 获取到url, pathname,query,及paramParams参数;为了解析这些数据需要使用url和querystring模块

点击更多...

内容以共享、参考、研究为目的,不存在任何商业目的。其版权属原作者所有,如有侵权或违规,请与小编联系!情况属实本人将予以删除!