最近几天在公司是处理一个新的模块,这个新模块因为要放弃老的组件,需要进行新的开发,在这个页面上有一个左侧导航,右边是内容,这时候需要一个视图的路由来进行右边的内容的切换。项目中没有引入视图的插件,老的进行熟悉的成本又太大,于是就需要重新写路由。
首先,我们要明确路由是什么,为什么使用路由。下面引用知乎上2个大神的回答。
在web开发中,“route”是指根据url分配到对应的处理程序。 ---贺师俊
为什么要使用路由?
传统web开发是每一个请求地址都会请求服务器来进行处理,但是用户有些操作则无需请求服务器,直接页面端修改下逻辑就能达到目的,这种最好使用路由,也许题主会有疑问:直接使用js处理下不就行了。使用js直接处理这些是可以的,事实上以前我们也这么做,但是这样做不便于用户收藏当前页,因为使用js时并不更新url,但是使用路由时,url也是随着改变的,用户浏览到一个网页时可以直接复制或收藏当前页的url给别人,这种方式对于搜索引擎和用户来说都是友好的。 ---李超
相信通过上面大神的回答会更清晰的理解路由。
当前项目中已经有固定的目录结构,我没法给每个view来添加不同的controler来控制,所以在封装的需求上,我的目的是通过改变url来改变我的当前视图,在一个整体的js文件里把几个页面的js来分割独立区域来完成业务需求。
谈谈我在独立思考这个问题时的迷茫,在选择的时候,我首先想到这个封装要对url进行监听,这里说一下url的一点小东西,url在识别的时候在url后面添加#,#后面的字符会被浏览器识别为锚点,这个在之前的页面跳转中用到现在很多都是用js的scroll方法来操作,这里只要#后面的字符不会被浏览器发送请求这个功能。接下来我在做的时候就想着监听url的变化,产生回调方法,切换不同的视图。写了一个hashchange的监听函数,然后想在函数里处理我不同url时的操作,这时我就懵了,怎么回调不同的操作函数。这时候我在百度js写路由的时候,找到了下面这段代码。
function opRoute() {
this.routes = {};
this.currentUrl = '';
}
//设置路由
opRoute.prototype.route = function (path, callback) {
this.routes [path] = callback || function () { };
}
//执行路由
opRoute.prototype.refresh = function () {
this.currentUrl = (location.hash.split('#')[1]).split('?')[0];
if(this.routes[this.currentUrl]){this.routes[this.currentUrl]()};
}
//设置监听
opRoute.prototype.init = function () {
window.addEventListener('load', this.refresh.bind(this),false);
window.addEventListener('hashchange', this.refresh.bind(this),false);
}
window.opRoute = new opRoute();
window.opRoute.init();
之前很少用过构造函数这种方法,这次跟着体验了一遍,首先opRoute创建一个构造函数,在这个函数里进行存储已注册的路由,this.routes对象来存储不同url对应的回调函数,this.currentUrl进行存储当前路由。首先使用原型来进行一个注册路由方法,这里key,value对应的是路由地址和对应回调函数。接着创建执行路由的方法,通过location来获取到当前的url,进行分割来获取到模块信息,我这里的?主要是问号后面是我页面的传参数据,取?前的模块名字。最后进行方法的初始化,这里进行设置绑定监听函数。需要注意的是这里的this关键字,在监听函数里的this会在执行时触发,那样this的指向会绑定监听的对象,这里为window,所以要bind来绑定this来把对象进行传递(最近在看es6,使用(this)=>方法会让this绑定到当前创建的对象上,而不是触发时的对象上)。在使用的时候在window上来new一个对象的实例,这样在使用的时候会在根的方法上,全局都可以使用。然后init()来进行初始化设置。
opRoute.route('form',function () {
console.log('这是路由form');
changeView();
})
在不同视图的路径位置对应js那里来进行路由的注册,同时function来进行回调函数的处理。
这是一个简单的路由思路,在这里就可以完成了我的业务需求,想起来之前用过的框架的路由,感觉对路由的模块了解的更深入了。