• js web简单的路由管理器


    灵感来自此博客此库

    index.html

    <!DOCTYPE html>
    <html lang="en">
      <head>
        <meta charset="UTF-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <title>Document</title>
      </head>
      <body>
        <div id="root"></div>
        <template id="home">
          <h1>home</h1>
        </template>
        <template id="about">
          <h1>about</h1>
        </template>
        <template id="dog">
          <h1>dog</h1>
        </template>
        <template id="notFound">
          <h1>404 not found</h1>
        </template>
        <script src="./aja-router.js"></script>
        <script>
          const router = new AjaRouter();
          router.forRoot([
            {
              path: "",
              redirectTo: "home"
            },
            {
              path: "home",
              render(host) {
                const t = document.querySelector("#home");
                host.append(document.importNode(t.content, true));
              }
            },
            {
              path: "about",
              render(host) {
                const t = document.querySelector("#about");
                host.append(document.importNode(t.content, true));
              }
            },
            {
              path: "dog/:id",
              render(host, route) {
                const t = document.querySelector("#dog");
                const dog = document.importNode(t.content, true);
                dog.querySelector(
                  "h1"
                ).innerHTML = `dog, id is ${route.params.id.value}`;
                host.append(dog);
              }
            },
            {
              path: "**",
              render(host) {
                const t = document.querySelector("#notFound");
                host.append(document.importNode(t.content, true));
              }
            }
          ]);
    
          setTimeout(() => {
            router.push("about");
          }, 1200);
        </script>
      </body>
    </html>
    

    aja-router.js

    const _textIsDynamicRouteExp = //?:[a-zA-Z]+/;
    class AjaRouter {
      _host = document.querySelector("#root");
      _routes = [];
    
      constructor(host) {
        if (host) this._host = host;
        this._setup();
      }
    
      _setup() {
        window.addEventListener("load", e => {
          this._render();
        });
    
        window.addEventListener("popstate", e => {
          this._render();
        });
    
        // window.addEventListener("hashchange", e => {
        //   console.log("hash ");
        // });
      }
    
      forRoot(routes = []) {
        this._routes = routes.map(route => {
          const { path } = route;
          const pathSplit = path.split("/");
          if (path && path.match(_textIsDynamicRouteExp)) {
            route.isDynamic = true;
            // 动态路由
            const params = {};
            let exp = "";
            for (var i = 0; i < pathSplit.length; i++) {
              const item = pathSplit[i];
              let expItem = "/" + item;
              if (item.startsWith(":")) {
                params[item.replace(/^:/, "")] = { index: i };
                expItem = `/(?<${item.replace(/^:/, "")}>[^/]+)`;
              }
              exp += expItem;
            }
            if (exp && exp.trim() != "") {
              exp = exp.replace(///, "");
            }
            route.exp = new RegExp(exp);
            route.params = params;
          }
    
          return route;
        });
      }
    
      _findHashRoute(path) {
        const hash = path ?? document.location.hash.replace(/#/?/, "");
        return this._match(hash);
      }
    
      /**
       * 使用path在routes中寻找路由
       */
      _match(path) {
        // 1, 先找普通路由
        let route = this._routes.find(i => i.path === path);
        if (route) {
          return route;
        }
    
        // 2, 找动态路由
        route = this._routes
          .filter(i => i.isDynamic)
          .find(i => {
            const pattern = "/";
            const routeNameSplit = path.split(pattern);
            const dynamicRouteNameSplit = i.path.split(pattern);
            const equalRouteLength =
              routeNameSplit.length == dynamicRouteNameSplit.length;
            const match = path.match(i.exp);
            if (match && match.groups) {
              for (const k in match.groups) {
                const param = i.params[k];
                param.value = match.groups[k];
              }
            }
    
            return equalRouteLength && match;
          });
    
        if (route) {
          return route;
        }
    
        // 3, 都没找到,默认返回404路由
        return this._find404Route();
      }
    
      _find404Route() {
        return this._routes.find(i => i.path === "**");
      }
    
      _render(path) {
        const matchRoute = this._findHashRoute(path);
        if (matchRoute) {
          this._host.innerHTML = "";
          if (matchRoute.redirectTo) {
            this._render(matchRoute.redirectTo);
          } else {
            matchRoute.render(this._host, matchRoute);
          }
        }
      }
    
      push(path) {
        try {
          this._render(path);
          window.history.pushState({}, document.title, `#/${path}`);
        } catch (error) {}
      }
    }
    
  • 相关阅读:
    东方财富炒股公式
    centos8安装MySQL8——通过yum
    官网下载工具时。各种不同后缀名称的区别。
    线上不停机部署mysql主从
    店员任务项目总结
    JS到PHP使用RSA算法进行加密通讯
    无锁同步-JAVA之Volatile、Atomic和CAS
    无锁同步-C++11之Atomic和CAS
    浅谈一个网页打开的全过程(涉及DNS、CDN、Nginx负载均衡等)
    SQLServer数据库卡,内存吃不上去,系统资源用不上
  • 原文地址:https://www.cnblogs.com/ajanuw/p/12517086.html
Copyright © 2020-2023  润新知