前端路由的简单实现

概念

路由这个概念首先出现在后台。传统MVC架构的web开发,由后台设置路由规则,当用户发送请求时,后台根据设定的路由规则将数据渲染到模板中,并将模板返回给用户。因此,用户每进行一次请求就要刷新一次页面,十分影响交互体验。

ajax 的出现则有效解决了这一问题。ajax (asynchronous javascript and xml),浏览器提供的一种技术方案,采用异步加载数据的方式以实现页面局部刷新,极大提升了用户体验。

而异步交互体验的更高版本就是 SPA——单页应用,不仅页面交互无刷新,甚至页面跳转之间也可以无刷新。为了实现 SPA,因此便有了 前端路由 的概念。

实现

Angular,React,Vue 都有 前端路由 的概念,但是前端路由究竟是如何实现的呢?且看下面代码:

/**
 * Created by lonelydawn on 2018-04-03.
 * javascript version: ES 6
 */

import homepage from '../views/homepage.html'
import product from '../views/product.html'
import server from '../views/server.html'

let Router = function (config) {
  config = config || {}
  // 页面容器
  let app = document.getElementById(config.el) || document.body
  let routes = Object.prototype.toString.call(config.routes) === '[object Array]'
    ? config.routes : []
  // 加载页面
  let load = function (route) {
    if (route) {
      let beforeLoad = route.beforeLoad || function () {}
      let afterLoad = route.afterLoad || function () {}
      beforeLoad()
      app.innerHTML = route.template
      afterLoad()
    }
  }
  // 根据 location 的 hash 属性实现页面切换
  let redirect = function () {
    let url = window.location.hash.slice(1) || '/'
    for (let route of routes) {
      if (url === route.url) {
        load(route)
        return
      }
    }
    load(routes[0])
  }
  // 添加路由规则
  this.push = function (route) {
    if (Object.prototype.toString.call(route) === '[object Object]') {
      routes.push(route)
    }
  }
  // 更改页面容器
  this.bind = function (el) {
    app = document.getElementById(el) || document.body
  }
  // event
  window.addEventListener('load', redirect, false)
  // 监控 hash 变化
  window.addEventListener('hashchange', redirect, false)
}
// 创建路由对象
let router = new Router()
router.bind('app')
router.push({
  url: '/',
  template: homepage
})
router.push({
  url: '/product',
  template: product
})
router.push({
  url: '/server',
  template: server
})

示例

源代码

demo下载

猜你喜欢

转载自my.oschina.net/lonelydawn/blog/1789432