前端开发发展过程和SPA实现原理介绍

2020-03-19 0 By admin

一、前端路由开发的发展过程

1.1、后端路由阶段

早期的网站开发整个HTML页面都是由服务器来渲染的。服务器直接生成渲染好的HTML页面, 返回给客户端进行展示。
一个网站这么多页面,服务器如何处理呢?
没有页面有自己对应的URL,当URL发送到服务器, 服务器会通过正则对该URL进行匹配, 最后交给一个Controller进行处理。Controller进行各种处理, 最终生成HTML或者数据, 返回给前端。这就完成了一个IO操作(HTTP请求)。这就是后端路由。
后端路由的缺点
整个页面的模块由后端人员来编写和维护的,HTML代码和数据以及对应的逻辑会混在一起, 编写和维护都是非常糟糕的事情。

1.2、前端路由阶段

前后端分离阶段
随着Ajax的出现, 有了前后端分离的开发模式。后端只提供API来返回数据, 前端通过Ajax获取数据, 并且可以通过JavaScript将数据渲染到页面中。
这样做最大的优点就是前后端责任的清晰, 后端专注于数据上, 前端专注于交互和可视化上。并且当移动端(iOS/Android)出现后, 后端不需要进行任何处理, 依然使用之前的一套API。
单页面富应用阶段
其实SPA(single page web application)最主要的特点就是在前后端分离的基础上加了一层前端路由;也就是前端来维护一套路由规则。
前端路由的核心是:改变URL,但是页面不进行整体的刷新。

二、SPA核心:URL改变,页面不刷新的原理

在单页应用中,前端路由根据不同的 url 显示不同的内容。想要知道这是如何做到的,首先得了解浏览器提供的两大 API:
window.location

  1. location.href
  2. location.hash
  3. location.search
  4. location.pathname

window.history

  1. history.pushState()
  2. history.replaceState()
  3. history.go()
  4. history.back()
  5. history.forward()

2.1、window.location 接口

我们先了解 location 对象,location 有很多的属性。我们可以通过改变其属性值修改页面的 url。
我们在单页应用中需要做到的是改变 url 不刷新页面,location 接口提供以下两种方式可以做到:
1、location.href 获取和设置当前的URL。
>location.href = "https://www.baidu.com/#home"
<"https://www.baidu.com/#home"
>location.href
<"https://www.baidu.com/#home"

URL的hash
URL的hash也就是锚点(#), 本质上是改变window.location的href属性。设置URL的hash值,并不会刷新页面。

2、location.hash 直接操作hash
>location.hash="about"
<"about"
>location.href
<"https://www.baidu.com/#about"

location 的另外两个属性,search 会直接刷新页面;pathname 照道理来说只改变 hash 应该是可以的,但实际上浏览器会编码这个属性值,所以无法直接赋带 # 号的值。

2.2、window.history 接口

history 接口是 HTML5 新增的,它有五个方法可以改变 url 而不刷新页面。

  1. history.pushState() 跳转到新的地址。写入到浏览器的浏览历史记录中,可以通过【浏览器的返回】会到此地址。
  2. history.replaceState() 跳转到新的地址。不能通过【浏览器的返回】会到此地址。
  3. history.go() 用数字表示前进和后退。
  4. history.back() 后退到上次访问的地址,等于go(-1)。
  5. history.forward() 前进一步,等于go(1)。

pushState和 replaceState 接收三个参数,一个对象(用作state),一个字符串(用作标题,但是目前都被浏览器忽略),一个字符串(用作URL,是可选的)。

三、如何监听 url 变化事件

现在我们已经知道如何不刷新页面改变页面的 url。虽然页面没刷新,但我们要改变页面显示的内容。这就需要 js 监听 url 的变化从而达到我们的目的。
可以通过监听 hashchange 事件或者 popstate 事件来响应URL的变化。

3.1、hashchange 事件

hashchange 事件能监听 url hash 的改变。无论是通过location接口直接改变hash,还是通过history接口前进和后退,只要改变了hash,都会被此事件监听到。
示例:

window.addEventListener('hashchange', function(e) {
  console.log(e)
})

3.2、popstate 事件

popstate 事件能监听除了 history.pushState() 和 history.replaceState() 外的URL变化。

示例:

window.addEventListener('popstate', function(e) {
  console.log(e)
})

其实history.pushState() 和 history.replaceState() 对 url 改变时,不止不会触发 popstate 事件;当这两个方法只改变 url hash 时也不会触发 hashchange 事件。