目标
一 实现插件的基本功能
·全局注册$router
·注册两个全局组件 router-view 和 router-link
二实现VueRouter类
·处理路由与选项
·监听url变化,当前选择hash模式
·相应路由变化更新页面
实现
router插件类 myvue-router.js
vue将来调用插件的方法会是install.call(VueRouter,Vue),将vue构造函数作为参数传入让插件使用,可以对Vue进行扩展
h就是createElement(标签,属性,显示内容) 返回一个虚拟dom
[ myvue-router插件文件]
let Vue; //为了给构造函数使用
class VueRouter{
constructor(options){
//为了方便使用
this.$options = options
//给指定对象对应响应式属性 current
Vue.util.defineReactive(this,'current',
window.location.hash.slice(1) || '/'
)
//监听hashChange
window.addEventListener('hashChange',()=>{
// #/about-> /about
this.current= window.location.hash.slice(1)
})
}
}
//形参为vue的构造函数
VueRouter.install = function(_Vue){
Vue = _Vue
//将$router注册一下,但vue实例还未创建,需要全局混入,延迟到根实例创建时
Vue.mixin({
//只在根实例执行 不是所有的
beforeCreate(){
if(this.$options.router){
Vue.prototype.$router = this.$options.router
}
}
})
//注册两个全局组件
Vue.component('router-link',{
props:{
to:{
type:String,
required:true
}
}
render(h){
//默认插槽内容 this.$slots.default
//给a标签添加特性
return h('a',{
attrs:{
//当前模式为hash 添加#
href: '/#'+ this.to
},
this.$slots.default
}
'this is router link')
}
})
Vue.component('router-view',{
render(h){
let component = null
//根据浏览器hash地址(window.location.hash), 动态获取链接的hash值动态匹配相应的组件
//current要做成响应式 路由发生变化 依赖的组件就会重新render
const route = this.$router.$options.routes.find(
route => route.path === this.$router.current
)
if(route){
component = route.component
}
return h(component)
}
})
}
export default VueRouter
【router.js文件】
import Vue from 'vue'
import VueRouter from './myvue-router'
//调用插件的静态install方法
Vue.use(VueRouter)
//path和组件的映射表
const routes=[
{
path:'/',
name:'Home',
component:Home
},
{
path:'/about',
name:'About',
component:About
}
]
const router = new VueRouter({
routes
})
export default router
[main.js 文件]
import router from './router.js'
new Vue({
router,//router实例放入到vue选项中,挂在到vue原型上
render:h=>h(App)
}).$mount('#app')