zoukankan      html  css  js  c++  java
  • Router的实现原理

    Router

    单页面应用(SPA)需配置Router来解决页面跳转,Vue、React等框架都支持Router配置,路由常分为hash、history两种模式。hash模式URL尾部带有“#”,history模式不带“#”。history模式需要配合服务器的URL重写,否则将出现404。下面使用原生JS实现Router。

    路由原理

    1. Router 注册
      1.1 提供注册的URL
      1.2 提供回调函数
    2. URL 跳转模式
      2.1 push 跳转
      2.2 replace 跳转
    3. Router 监听
      3.1 hashRouter 监听
      3.2 historyRouter 监听
    4. Router 模式
      4.1 hashRouter
      4.2 historyRouter

    路由实现

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Router</title>
    </head>
    <body>
        <!-- push 跳转模式 -->
        <ul>
            <li onclick="Router.push(baseUrl + '')">首页</li>
            <li onclick="Router.push(baseUrl + 'news')">新闻</li>
            <li onclick="Router.push(baseUrl + 'products')">产品</li>
        </ul>
        <!-- replace 跳转模式 -->
        <ul>
            <li onclick="Router.replace(baseUrl + '')">首页</li>
            <li onclick="Router.replace(baseUrl + 'news')">新闻</li>
            <li onclick="Router.replace(baseUrl + 'products')">产品</li>
        </ul>
        <div id="app">
    
        </div>
    
    <script>
        var app = document.getElementById("app")
        var baseUrl = "/"      // 根目录
    
        function RouterClass(options) {
            this.routerMap = {} // 用于路由注册
            this.curUrl = ""    // 当前的url
            this.mode = -1
            this.modeWhiteList = {
                "hash":this.eventHashRouter.bind(this),
                "history":this.eventHistoryRouter.bind(this)
            }
    
            Object.keys(this.modeWhiteList).forEach((key,index)=>{
                if(key === options.mode){
                    this.mode = index
                    this.modeWhiteList[key]()
                }
            })
    
            // 默认为hash模式
            if(this.mode === -1){
                console.log("default")
                this.mode = 0;
                this.modeWhiteList['hash']();
            }
        }
    
        // hash 路由
        RouterClass.prototype.hashRouter = function(){
            this.curUrl = window.location.hash.slice(1) || "/"
            this.routerMap[this.curUrl]()
        }
    
        // history 路由
        RouterClass.prototype.historyRouter = function(){
            this.curUrl = window.location.pathname
            console.log(this.curUrl)
            this.routerMap[this.curUrl]()
        }
    
    
        /* 事件监听 */
    
        // hash 模式监听
        RouterClass.prototype.eventHashRouter = function(){
            window.addEventListener("hashchange",this.hashRouter.bind(this))
            window.addEventListener("load",this.hashRouter.bind(this))
        }
    
        // history 模式监听
        RouterClass.prototype.eventHistoryRouter = function(){
            window.addEventListener("popstate",this.historyRouter.bind(this))
        }
    
        /* 路由注册 */
        RouterClass.prototype.register = function(path,callback){
            this.routerMap[path] = callback || function(){}
        }
    
        /* 跳转模式 */
    
        // push 模式跳转
        RouterClass.prototype.push = function(url){
            if(this.mode === Object.keys(this.modeWhiteList).indexOf("history")){
                window.history.pushState({},"",url)
                this.routerMap[url]()
            }else{
                url = "#" + url;
                window.location.href = url;
            }
        }
    
        // replace 模式跳转
        RouterClass.prototype.replace = function (url) {
            if(this.mode === Object.keys(this.modeWhiteList).indexOf("history")){
                window.history.replaceState({},"",url)
                this.routerMap[url]()
            }else{
                url = "#" + url;
                window.location.replace = url;
            }
        }
    
    
        var Router = new RouterClass(
            {mode:"history"}
        );
    
        Router.register(baseUrl + "",function () {
            app.innerHTML = "index"
        })
    
        Router.register(baseUrl + "news",function () {
            app.innerHTML = "news"
        })
    
        Router.register(baseUrl + "products",function () {
            app.innerHTML = "products"
        })
    </script>
    
    </body>
    </html>
    
    
  • 相关阅读:
    [LintCode] Set Matrix Zeros
    [LintCode] Identify Celebrity
    [LintCode] Edit Distance
    [LintCode] Edit Distance II
    [LintCode] Strings Serialization
    二十七. Keepalived热备 Keepalived+LVS 、 HAProxy服务器
    二十六. 集群及LVS简介 LVS-NAT集群 LVS-DR集群
    二十五 存储技术与应用 iSCSI技术应用 、 udev配置 NFS网络文件系统 、 Multipath多路径 、 NFS网络文件系统 、 udev配置
    二十三.Subversion基本操作、使用Subversion协同工作、制作nginx的RPM包
    二十二. 安装部署Tomcat服务器、使用Tomcat部署虚拟主机、使用Varnish加速Web
  • 原文地址:https://www.cnblogs.com/chir/p/13451795.html
Copyright © 2011-2022 走看看