如何实现一个vue-router?

路由,简单来说就是用来跟后端服务器进行交互的一种方式,通过不同的路径,来请求不同的资源,请求不同的页面是路由的其中一种功能。后端有后端路由,根据路由返回特定的网页,代表者是传统的mvc模式,模板引擎+node。前端也有前端的路由,我们用三大框架做spa的时候,总是和路由离不开关系。

其中, “更新视图但不重新请求页面”是前端路由原理的核心之一。

目前实现前端路由的两种方法:

  • 利用URL中的hash(“#”)

  • 利用History interface在 HTML5中新增的方法

hash方法

  • #后面的内容是网页位置标识符,一般是锚点 <a name='xx'> 或id属性 <div id='xx'>。通过location.hash可以取到该值,常见的返回顶部也可以利用href='#'
  • 改变#后面的内容不会引起页面重新刷新,但是会有历史记录,所以可以后退。
  • 这对于ajax应用程序特别有用,可以用不同的#值,表示不同的访问状态,然后向用户给出可以访问某个状态的链接。(但是IE 6和IE 7不会有历史记录。#后面的内容不会提交到服务器。)
  • 对于a标签,平时有一个常规的操作:
    想要在某个点击按钮变成a标签的那个cursor:pointer(手指),一般就用a标签包住文字,<a href="#">按钮</a>但是这样子是会有历史记录,所以我们应该改成<a href="javascript:void 0">按钮</a>

使用hash方法实现vue-router:

class Routers {
    constructor () {
        this.routes = {}; // 存放路由path及callback
        this.currentUrl = '';
        this.refresh = this.refresh.bind(this);
        // 监听路由change调用相对应的路由回调
        window.addEventListener('load', this.refresh, false);
        window.addEventListener('hashchange', this.refresh, false);
    }
    route(path, callback){
        this.routes[path] = callback;
    }
    push() {
        this.currentUrl = location.hash.slice(1) || '/';
        this.routes[this.currentUrl] && this.routes[this.currentUrl]()
    }
}

简版的hash router 已经实现了, 我们可以这样使用

window.VueRouter = new Routers();
VueRouter.route('/', ()=> console.log('page1'))
VueRouter.route('/detail', ()=> console.log('page2'))

history方法

  • history 对象
  • history.pushState()方法用于在历史中添加一条记录。
  • history.replaceState()方法用来修改 History 对象的当前记录,其他都与pushState()方法一模一样。
  • history.popState 每当同一个文档的浏览历史(即history对象)出现变化时,就会触发popstate事件。

使用history方法实现vue-router:

class Routers {
    contructor () {
        this.routes = {};
        this.listerPopState()
    }
    init(path) {
        history.replaceState({path: path}, null, path);
        this.routes[path] && this.routes[path]();
    }
    route(path, callback){
        this.routes[path] = callback;
    }
    push(path) {
        history.pushState({path: path}, null, path);
        this.routes[path] && this.routes[path]();
    }
    listerPopState () {
        window.addEventListener('popstate' , e => {
            const path = e.state && e.state.path;
            this.routers[path] && this.routers[path]()
        })
    }
}

简版的history router 已经实现了, 我们可以这样使用

window.VueRouter = new Routers();
VueRouter.route('/', ()=> console.log('page1'))
VueRouter.route('/detail', ()=> console.log('page2'))
// 跳转
VueRouter.push('/detail')  // page2

如果你嫌哈希路由有#难看可以用history路由。不过history路由有一个问题,我们知道pushState和replaceState只是对url栏进行改变,不会触发页面刷新,只是导致history对象发生变化,另外也==不能跨域==。既然不会触发页面更新,那么也不会发送http请求,就有了一个问题:如果直接输入url,后端又没有对应的url处理的话,那肯定是404,而哈希路由则可以直接输入 url直接定位到某个视图。

参考:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值