专栏首页前端导学用js徒手写一个路由框架

用js徒手写一个路由框架

分别创建 index.html 、 main.js 、router.js 和 route.js文件

route.js

export class Route {
  constructor(name, path, handler) {
    this.name = name;
    this.path = path;
    this.handler = handler;
  }

  get name() {
    return this._name;
  }

  set name(name) {
    this._name = name;
  }

  get path() {
    return this._path;
  }

  set path(path) {
    this._path = path;
  }

  get handler() {
    return this._handler;
  }

  set handler(handler) {
    this._handler = handler;
  }
}

router.js

import {
  Route
} from './route.js'

export class Router {
  constructor() {
    this.mode = 'history'
    this.routes = []
    this.root = '/'
  }

  get root() {
    return this._root;
  }

  set root(val) {
    this._root = val;
  }

  get mode() {
    return this._mode
  }

  set mode(val) {
    this._mode = (val == 'history' && window.history.pushState) ? 'history' : 'hash'
  }

  get routes() {
    return this._routes;
  }

  set routes(val) {
    this._routes = val;
  }

  add(route) {
    this.routes.push(new Route(route.name, route.path, route.handler))
    return this
  }

  navigate(route) {
    route = route ? route : ''
    this.match(route)
  }

  match(route) {
    for (var i = 0; i < this.routes.length; i++) {
      let paramNames = []
      let regexPath = this.routes[i].path.replace(/([:*])(\w+) /g, function (full, colon, name) {
        paramNames.push(name)
        return '([^\/]+)';
      }) + '(?:\/|$)'

      let routeMatch = route.match(new RegExp(regexPath));
      if (routeMatch !== null) {
        var params = routeMatch
          .slice(1, routeMatch.length)
          .reduce((params, value, index) => {
            if (params === null) params = {};
            params[paramNames[index]] = value;
            return params;
          }, null);
        if (params === null) {
          this.routes[i].handler()
        } else {
          this.routes[i].handler(params)
        }
        this.location(route)
      }
    }
  }

  location(route) {
    if (this.mode === 'history') {
      window.history.pushState(null, null, this.root + route)
    } else {
      route = route.replace(/^\//, '').replace(/\/$/, '')
      window.kk = window.kk.replace(/#(.*)$/, '') + '#' + route
    }
  }
}

main.js

import {
  Router
} from './router.js'

const router = new Router()
router.mode = 'hash'
router.root = 'http://192.168.1.103:8080'
router.add({
  name: 'home',
  path: '/home',
  handler: () => console.log('handler to home')
})

router.add({
  name: 'about',
  path: '/about',
  handler: () => console.log('handler to about')
})

router.add({
  name: 'contact',
  path: '/contact',
  handler: () => console.log('handler to contact')
})

router.add({
  name: 'user',
  path: '/user/:id/:action',
  handler: (params) => console.log('user handler params')
})

const activeRoutes = Array.from(document.querySelectorAll('[route]'))
activeRoutes.forEach((route) => route.addEventListener('click', (e) => {
  e.preventDefault();
  router.navigate(e.target.getAttribute('route'))
}, false))

index.html

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Router</title>
  <script type="module" src="main.js"></script>
</head>

<body>
  <h3>Router</h3>
  <div id="view"></div>
  <button route="/"> Root</button>
  <button route="/about">About</button>
  <button route="/contact">Contact</button>
  <button route="404">404</button>
  <button route="/user/24/save">User add</button>
</body>

</html>

源码地址 https://github.com/lilugirl/handmade_router

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

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 重新撸一遍javascript (三)

    lilugirl
  • TypeScript入门笔记

    lilugirl
  • ionic4 解决键盘遮挡输入框的问题

    lilugirl
  • Vue路由History模式分析

    Vue-router是Vue的核心组件,主要是作为Vue的路由管理器,Vue-router默认hash模式,通过引入Vue-router对象模块时配置mode属...

    WindrunnerMax
  • Vue路由Hash模式分析

    Vue-router是Vue的核心组件,主要是作为Vue的路由管理器,Vue-router默认hash模式,即使用URL的Hash来模拟一个完整的URL,当UR...

    WindrunnerMax
  • 海尔透明工厂,拍了乔式发布会一巴掌,也在中国制造2025&quot;立了一个坐标

    当互联网开始颠覆传统经济的发展模式,人们就一直在探寻新的生产模式。德国提出的工业4.0、美国创造的工业互联网成为西方探索的典范。当“中国制造2025”成为我国从...

    曾响铃
  • iOS XMPP系列教程(Swift)一 概述与环境搭建

    现在很多软件都加入了聊天功能,也有许多公司直接提供了app聊天的组件,简单集成就行,但是弊端在于组件一是要收费,二是不灵活,没法自定义

    剑行者
  • 微软RPC技术学习小结

    RPC,即Remote Procedure Call,远程过程调用,是进程间通信(IPC, Inter Process Communication)技术的一种...

    宋凯伦
  • Hibernate 5 @Entity 如何 extends 另外一个类

    但是在这个 @Entity 类中,我们希望 extends 另外一个类,在另外一个类中我们可以把一些通用的属性设置到里面。

    HoneyMoose
  • 设计师编程指南之Sketch插件开发 2

    Sketch 是 Mac 系统才有的软件,可以理解为精简版的 PS ,比 PS 更适合 UI 设计,Sketch 插件开发的语言是类 Javascript ,...

    mixlab

扫码关注云+社区

领取腾讯云代金券