笔记-前端路由

126 阅读2分钟

路由

路由是不同的url,显示不同的页面或内容的功能

前端路由
  1. hash路由 监听浏览器地址hash值变化,执行相应的回调改变网页内容

    url上有#号

    // http://baidu.com/#xxx
    loaction.hash
    
    //可以通过hashchange事件监听hash变化
    window.addEventLitener('hashchange',function(){})
    
  2. history路由

    利用history API实现url地址改变,改变网页内容

    pushState方法、replaceState方法,poststate事件

    //http://xxx.abc.com/path?param=test
    window.addEventListener('popstate', (event) => {
        //toto
    });
    history.pushState({page:1},'title','?page=1')
    history.pushState({page:2},'title','?page=2')
    history.replaceState({page:2},'title','?page=2')
    history.back()
    history.back()
    history.go(2)
    

    服务端相关配置

    ## history
    location / {
        root    /var/www;
        index index.php index.html index.htm;
        try_files $uri $uri/ /index.html;
    }
    

实现简单的hash路由和history路由

  1. hash路由
    1. 创建HashRouter类,创建map保存 path 和其对应的 callback,保存当前的 path
    class HashRouter(){
        constructor(){
            //保存path和对应函数
            this.routes = new Map();
            //当前path
            this.currentHash = '';
        }
    }
    
    1. 注册路由方法
    class HashRouter(){
        constructor(){
            //保存path和对应函数
            this.routes = new Map();
            //当前path
            this.currentHash = '';
        }
    
        // path和callback对应起来存储进routes中
        route(path,callback){
            const cb = callback || function(){};
            this.routes.set(path,cb);
        }
    }
    
    1. hash改变时拿到当前的 hash 执行对应的callback,更新页面内容
    class HashRouter(){
        constructor(){
            //保存path和对应函数
            this.routes = new Map();
            //当前path
            this.currentHash = '';
    
            //监听hashchange 事件
            window.addEventLitener('hanshchange',()=>{
                this.changeUrl();
            })
        }
        // path和callback对应起来存储进routes中
        route(path,callback){
            const cb = callback || function(){};
            this.routes.set(path,cb);
        }
    
        //执行map中的callback
        changeUrl(){
            //通过location.hash 拿到当前hash slice(1)截掉 # 号
            this.currentHash = window.location.hash.slice(1) || '/'
             // 执行存入routes中 当前 hash 对应的 callback
            this.routes.get(this.currentHash) && this.routes.get(this.currentHash)();
        }
    }
    
    
  2. history路由
    1. 创建HashRouter类,创建map保存 path 和其对应的 callback,添加注册路由方法
    class HistoryRouter(){
        constructor(){
            //保存path和对应函数
            this.routes = new Map();
        }
    
        // path和callback对应起来存储进routes中
        route(path,callback){
            const cb = callback || function(){};
            this.routes.set(path,cb);
        }
    }
    
    1. // 监听poststate事件 浏览器回退和前进按钮触发并执行存储的当前 path 对应的callback
    class HistoryRouter(){
        constructor(){
            //保存path和对应函数
            this.routes = new Map();
    
            // 监听poststate事件
            window.addEventListener('popstate',()=>{
                const path = this.getPath();
                this.routes.has(path) && this.routes.get(path);
            })
        }
    
        //获取url路径(path)部分
        getPath(){
            const path = window.location.pathname;
            return path?path:'/'
        }
    
        // path和callback对应起来存储进routes中
        route(path,callback){
            const cb = callback || function(){};
            this.routes.set(path,cb);
        }
    }
    
    1. 实现go方法,将当前 path 压入浏览历史对象,执行回调
    class HistoryRouter(){
        constructor(){
            //保存path和对应函数
            this.routes = new Map();
    
            // 监听poststate事件
            window.addEventListener('popstate',()=>{
                const path = this.getPath();
                this.routes.has(path) && this.routes.get(path);
            })
        }
    
        //获取url路径(path)部分
        getPath(){
            const path = window.location.pathname;
            return path?path:'/'
        }
    
        // path和callback对应起来存储进routes中
        route(path,callback){
            const cb = callback || function(){};
            this.routes.set(path,cb);
        }
    
        //初次进入页面时表现一致
        init(path){
            history.replaceState(null,null,path);
            this.routes.has(path) && this.routes.get(path)();
        }
    
        go(path){
            // 压入浏览历史对象
            history.pushState(null,null,path);
    
            // 修改页面
            this.routes.has(path) && this.routes.get(path)();
        }
    }
    
    使用(history) -- 服务端需做相应配置
    const Router = new HistoryRouter();
    //初始化
    Router.init(location.pathname);
    
    //注册路由
    Router.route('/',function(){
    changeColor('pink');
    })
    
    Router.route('/a',function(){
        changeColor('yellow');
    })
    
    Router.route('/b',function(){
        changeColor('red');
    })
    
    function changeColor(color){
        document.querySelector('body').style.backgroundColor = color;
    }
    
    <ul>
        <li><a href="/">主页面</a></li>
        <li><a href="/a">a页面</a></li>
        <li><a href="/b">b页面</a></li>
    </ul>
    
    注:使用a标签要阻止其默认行为
    document.querySelector('ul').addEventListener('click',(e)=>{
        console.log('e :>> ', e);
        if(e.target.tagName === 'A'){
            e.preventDefault();
            Router.go(e.target.getAttribute('href'));
        }
    })