vue路由有三种模式:hash history和abstract:
hash:使用URL hash值作路由,支持所有浏览器
history:需要HTML5 History API和服务器配置结合。对浏览器版本有要求,不支持低版本
abstract:支持所有js运行环境。如果当前环境没有浏览器API,路由会自动进入这个模式
我们在vue项目中,是怎么使用vue-router的呢?
首先,要从npm install vue-router -g 在系统中安装router插件,然后新建router文件在文件中通过 import 引入,新建好route目录后对外导出,在main.js中引入,挂载到vue中,即可使用
import Vue for "vue"
import Router from "vue-router"
Vue.use(Router)
let router =new Router({
......})
export default router
main.js中引用如下
import Vue from "vue"
import router from "./router/router"
new Vue({
router,
render:h=>h(App)
}).$mount("#app")
要自己手写一个router方法那么,通过上面的一系列操作得知,自己写的属于一个插件,要通过vue.use()使用,那么我们在插件中必须提供一个install方法,并对外暴露
class myRouter{
constructor(options){
this.$options=options
this.routerMap={
} //保存router列表
// 使用vue的响应式机制,使路由切换的时候 进行相应
this.app=new Vue({
data:{
// 默认为根目录
current:"/"
}
})
}
static install(_Vue){
......
}
}
做好一个路由,需要明确需求是什么,首先要监听路由变化,其次处理router.js中设置的路由列表,还有初始化路由组件
//由此可以设置一个init函数用为罗列我们需要完成的需求
init(){
//负责启动整个路由
//1.监听路由变化
this.bindRouterEvent()
//2.处理路由列表
this.createRouterList()
//3.初始化路由组件 router-view router-link
this.setComponent()
}
下面来监听一下路由变化,此处可以直接window直接hashchange事件hashchange。
bindRouterEvent(){
window.addEventListener("hashchange",this.beginChange.bind(this),false)
//初始化时同样需要监听
window.addEventListener('load',this.onHashChange.bind(thsi),false)
}
beginChange(event){
//获取当前hash值
let hash = window.location.hash.slice(1) || '/';
//将hash值写入
this.app.current=hash
}
当前已经监听到了hash的变化,获取到了hash值,接下来,处理一下已经配置好的路由列表
createRouterList(){
//在constructor中已经将option保存到了$option中,在此我们直接取用
this.$options.routes.forEach(item=>{
//将当前数组路由转为字典对象 方便查询
this.routerMap[item.path]=item
})
}
已经完成了监测hash变化和获取路由列表,下面我们需要注册组件,然后就可以应用了
setComponent(){
Vue.component('router-view',{
render:h=>{
// this.app.current 是我们默认的路由
const component = this.routerMap[this.app.current].component
//使用h新建一个虚拟dom
return h(component)
}
})
Vue.component('router-link',{
props:{
to:String //vue自带的参数校验
},
//动态显示的时候 依然推荐用render 更快更强
render(h){
// h三个参数 h=createElement
// 组件名
// 参数
// 子元素
return h('a',{
attrs:{
href:`#${
this.to}`
}
},
[this.$slots.default]//插槽
)
}
//template最终是转换成render执行 但是会多一层编译
// template:" " 解析不成功
})
}
除了router-view 和 router-link,还有一种常用的push方法来改变路由,从而访问其它页面,这里可以直接写入
push(url){
// hash模式直接赋值
window.location.hash=url
}
最后,要在前面写好的install中整体调用一下
static install(_Vue){
Vue=_Vue
Vue.mixin({
beforeCreate(){
if(this.$options.router){
//将定义好的路由放到vue的prototype中,这样可以在任何页面使用push方法改变路由
//把整个router对象挂载到vue原型链上,这样内部可以通过this.$router来获取路由实例
Vue.prototype.$myrouter=this.$option.router
this.$option.router.init()
}
}
})
}
vue-router 还有一些生命周期的设置,目前还没有写好,可以在监听hash变化的时候做判断,感兴趣的话可以先自己完善一下。