前端路由之VueRouter

177 阅读2分钟

服务端渲染的多页应用(SSR)

在还没有前后端分离的时候,通常是后端负责服务端程序,配合JQuery,来实现整个应用。

  1. 缺点:维护特别麻烦、服务器压力大(整个项目都会部署在自己的服务器上)、没有前后端分离,协作流程不清晰
  2. 优点:SEO效果好,因为是已经完全渲染好的页面;用户看到首屏的耗时比较小。

前端路由(SPA)

特性:1、根据不同的URL渲染不同的内容;2、不刷新页面(我们只需要把客户端代码部署到cdn上,当没
有与服务端数据进行交互的时候,大可不必访问自己的服务器,这就很大的减轻了服务器的压力)

不仅在页面的交互时页面是不刷新的,就连页面跳转的时候也不刷新页面。

hash可实现前端路由

hash具有如下特性:

   1  url中的hash值只是客户端的一种状态,向后端发请求的时候,hash是不会携带的
   2. hash改变页面不会刷新
   3. hash值的改变,会在浏览器的访问历史中增加记录
   4. hash值的更改,通过hashchange事件触发

hash路由基本实现思路如下:

class HashRouter {
  constructor() {
    this.routes = {};
    this.refresh = this.refresh.bind(this)
    window.addEventListener('load', this.refresh)
    window.addEventListener('hashchange', this.refresh)
  }

  route(path, cb) {
    this.routes[path] = cb || function()  {}
  }

  refresh() {
    const path = `/${location.hash.slice(1) || ''}`
    const cb = this.routes[path]
    cb && cb()
  }
}

history路由

hash路由虽然能解决问题,但是带有'#'不太美观, history路由也是一个很不错的选择,但是history路由需要后端配合,使其在访问任何url的时候都返回index.html页面。主要利用的是pushState和popState方法

1. 可以使用Popstate事件来监听url变化
2. pushState和replaceState 并不会触发popState
3. 只有浏览器的前进、后退、history里面的back,forward,go才会触发popState方法。
4. pushState和replaceState方法里面参数相同:
  4.1 state: 对象,与网址相关的信息
  4.2 title:标题, 有浏览器兼容性问题,一般传null
  4.3 网址

history路由基本实现思路如下:

class HistoryRouter {
  constructor() {
    this.routes = {}
    this.bindExecCallbackByPath = this.execCallbackByPath.bind(this)
    this.bindPopState = this.popState.bind(this)
    this.bindPopState()
    this.init(location.pathname)
  }

  init(path) {
    window.history.replaceState({path}, null, path)

    this.bindExecCallbackByPath(path)
  }

  route(path, cb) {
    this.routes[path] = cb
  }

  go(path){
    window.history.pushState({
      path
    }, null, path)
    this.bindExecCallbackByPath(path)
  }

  popState() {
    window.addEventListener('popstate', e => {
      const path = e.state && e.state.path;
      this.bindExecCallbackByPath(path)
    })
  }

  execCallbackByPath(path) {
    // 执行回调函数
    const cb = this.routes[path]
    cb && cb()
  }
}

上面所述就是前端路由的基本原理,vueRouter也是基于这几个api实现的,当然了我这里每个路由对应的是一个change方法,vueRouter中每个路由对应的是一个Component. 关于vueRouter的常见问题 vueRouter在一个长列表中选中一个栏目查看详情,从详情中返回的时候,如何保持停留在原来浏览的地方?

  1. keep-alive
  2. localStorage/sessionStorage + scrollTop + scrollTo
  3. scrollBehavior 需要注意的是 scrollBehavior router-link的时候是不会触发的, 点击浏览器的前进/后退或者调用history api的时候才会出发