前端路由的简单实现

概念

路由这个概念首先出现在后台。传统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下载

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏小尘哥的专栏

nodejs作为前后端分离中间件的跨域解决方案

前后端分离时候SEO问题很头疼,上次提供了nuxt+axios解决服务端渲染问题的解决方案,其实nodejs一样可以做服务端渲染,这时候会产生ajax跨域问题,...

922
来自专栏Ryan Miao

使用git提交中删除idea

https://segmentfault.com/q/1010000000720031 http://www.tuicool.com/articles/a6Nf...

6326
来自专栏Spring相关

动态加载布局的技巧

1.在res下面新建一个layout-large的文件夹,下面建一个activity_main.xml:

1124
来自专栏ionic3+

Cordova插件扩展——Themeablebrowser自拷贝图片

插件全名叫: cordova-plugin-themeablebrowser 这个插件会弹出一个浏览器窗口,打开外部网页,功能比较强大,能自定义导航工具栏、...

1375
来自专栏C/C++基础

Linux命令(20)——cat命令

(4)把 textfile1 的文档内容加上行号后输入 textfile2 这个文档里。

823
来自专栏运维

怎样把ESXI5.0导出的OVF模板导入到ESXI4.X中

怎样把ESXI5.0导出的OVF模板导入到ESXI4.X中 1,用workstation8或9打开ovf虚拟机模板,即建立了虚拟机 2,右击相应虚拟机---...

2302
来自专栏码神联盟

IntelliJ系列 ④ | IDEA 之 Tomcat配置全过程

1.4K3
来自专栏你不就像风一样

基于Netty实现可自动渲染HTML页面的静态Web服务器

Github:https://github.com/yueshutong/JerryServer/ 码云:https://gitee.com/zyzpp/J...

4362
来自专栏有困难要上,没有困难创造困难也要上!

Python2.x设置命令执行的超时时间

3837
来自专栏小筱月

script 标签的属性、事件的探究

有 async 没有 defer 时,会与渲染后续文档元素并行加载(加载过程不会阻塞 dom 解析),加载完自动执行(执行会阻塞 dom 解析)

2092

扫码关注云+社区

领取腾讯云代金券