moke's blog

vuePress-theme-reco moke    2017 - 2020
moke's blog

Choose mode

  • dark
  • auto
  • light
分类
  • 算法
  • 博客
  • HTTP
  • 数据结构
  • 前端
  • 文档
  • JS 基础
  • Node
标签
博客
前端
  • 知识体系
  • 前端资料
  • JavaScript 专题
  • JavaScript 基础
  • JavaScript 进阶
算法
  • 算法专题
  • 数据结构
TimeLine
GitHub (opens new window)
author-avatar

moke

56

Article

17

Tag

分类
  • 算法
  • 博客
  • HTTP
  • 数据结构
  • 前端
  • 文档
  • JS 基础
  • Node
标签
博客
前端
  • 知识体系
  • 前端资料
  • JavaScript 专题
  • JavaScript 基础
  • JavaScript 进阶
算法
  • 算法专题
  • 数据结构
TimeLine
GitHub (opens new window)
  • JavaScript 专题
  • 手动实现 call、apply、bind
  • 手动实现 JSONP
  • 手动实现 Promise
  • EventEmitter
  • 防抖与节流
  • 深浅拷贝
  • Instanceof
  • New
  • 继承相关
  • 前端路由
  • Curry
  • 工具函数

前端路由

vuePress-theme-reco moke    2017 - 2020

前端路由

moke 2019-04-18 23:41:17 JavaScript

# hash 路由

https://mubu.com/doc/1iFLzJZrdK (opens new window)

/**
 * https://mubu.com/doc/1iFLzJZrdK
 *
 * @class HashRouter
 */
export class HashRouter {
  constructor() {
    // 用于存储不同 hash 值对应的回调函数
    this.router = {}

    window.addEventListener('hashchange', this.load.bind(this), false)
  }

  // 用于注册每个视图
  register(hash, callback = () => {}) {
    this.router[hash] = callback
  }

  // 用于注册首页
  registerIndex(callback = () => {}) {
    this.router['index'] = callback
  }

  // 用于处理视图未找到的情况
  registerNotFound(callback = () => {}) {
    this.router['404'] = callback
  }

  registerError(callback = () => {}) {
    this.router['error'] = callback
  }

  load() {
    const hash = window.location.hash.slice(1)
    let handler = !hash ? this.router.index : this.router[hash]

    if (!hash) {
      handler = this.router.index
    } else if (!this.router.hasOwnProperty(hash)) {
      handler = this.router['404'] || (() => {})
    } else {
      handler = this.router[hash]
    }

    handler.call(this)
  }
}

# history 路由

class HistoryRouter {
  constructor() {
    this.router = {}
    this.listenPopState()
    this.listenLink()
  }

  listenPopState() {
    window.addEventListener('popstate', e => {
      const state = e.state || {}
      const path = state.path || ''

      this.dealPathHandler(path)
    })
  }

  listenLink() {
    window.addEventListener('click', e => {
      const dom = e.target

      if (dom.tagName.toUpperCase() === 'A' && dom.getAttribute('href')) {
        e.preventDefault()
      }
    })
  }

  load() {
    const path = window.location.pathname
    this.dealPathHandler(path)
  }

  register(path, callback = () => {}) {
    this.router[path] = callback
  }

  registerIndex(callback = () => {}) {
    this.router['/'] = callback
  }

  registerNotFound(callback = () => {}) {
    this.router['404'] = callback
  }

  registerError(callback = () => {}) {
    this.router['error'] = callback
  }

  assign(path) {
    window.history.pushState({ path }, null, path)
    this.dealPathHandler(path)
  }

  replace(path) {
    window.history.replaceState({ path }, null, path)
    this.dealPathHandler(path)
  }

  // 通用处理 path 调用回调函数
  dealPathHandler(path) {
    let handler

    if (!this.router.hasOwnProperty(path)) {
      handler = this.router['404'] || (() => {})
    } else {
      handler = this.router[path]
    }

    try {
      handler.call(this)
    } catch (e) {
      console
        .error(e)(this.router['error'] || (() => {}))
        .call(this, e)
    }
  }
}
在 GitHub 上编辑此页 (opens new window)
最后更新时间: 12/10/2019, 2:00:35 PM