main.js
import Vue from 'vue'
import App from './App'
// import router from './router'
//采用自己的路由组件
import router from './zrouter'
Vue.config.productionTip = false
/* eslint-disable no-new */
new Vue({
el: '#app',
router,
components: { App },
template: '<App/>'
})
zrouter/index.js
import Vue from 'vue'
//采用自己写的zvue
import Router from './zvue-router'
import HelloWorld from '@/components/HelloWorld'
//为什么使用use方法
//1、vuerouter是插件,插件必须先use
//use做了什么
//1、install方法,所有组件中this.$router可以访问Router实例,所以内部肯定做了Vue.prototype.$router的挂载
//2、实现并且注册router-link,router-view
Vue.use(Router)
export default new Router({
routes: [
{
path: '/',
name: 'HelloWorld',
component: HelloWorld
},
{
path: '/about',
name: 'about',
component: ()=> import('@/components/about')
}
]
})
zvue-router.js
// router插件
let zVue
class zVueRouer{
constructor(options){
// options是router里边的配置的那些路径数组之类的
this.$options = options
// this.currentPath = "/" 这个要改成响应式数据,这样才能让router-view里的render函数重新执行
zVue.util.defineReactive(this,'currentPath',window.location.hash.slice(1)||'/')
//监听hashchange
window.addEventListener('hashchange',this.onHashChange.bind(this))
}
onHashChange(){
this.currentPath = window.location.hash.slice(1)
}
}
//形参Vue是vue构造函数
zVueRouer.install = function(Vue){
zVue = Vue
//1挂载$router
Vue.mixin({
beforeCreate(){
//全局混入,将来在组件实例化的时候才执行,此时就能拿到router 的实例了
if(this.$options.router){
// 此时的this是组件实例,这里的判断是判断是不是根组件,根组件上配置了路由选项,在main.js里
//在vue构造函数上挂载$router、这样之后的所有组件都能访问到$router
Vue.prototype.$router = this.$options.router
}
}
})
//2实现全局组件
Vue.component('router-link',{
props:{
to:{
type:String,
required:true
}
},
// h是createElement函数
// h(tag,props,children)
render(h){
// <a href="#/xxxx">xxxx</a>
return h('a',{attrs:{href:"#"+this.to}},this.$slots.default)
}
})
Vue.component('router-view',{
// h是createElement函数
render(h){
// 1、获取路由器实例
//因为上边已经通过mixin在构造函数上挂载了$router,并且router-view是组件,所以能直接访问到$router
const routes = this.$router.$options.routes
const currentPath = this.$router.currentPath
// console.log(this.$router)
const route = routes.find(item => item.path===currentPath)
const comp = route?route.component:null
return h(comp)
}
})
}
export default zVueRouer