简单分析过程
源码如下:
1、创建一个vue-router.js文件
// 声明变量,缓存Vue实例对象
let Vue
/**
* 声明VueRouter类
*/
class VueRouter {
constructor(options) {
this.$options = options
// 创建一个路由path和route映射
this.routeMap = {}
// 当前路径current需要响应式-利用vue响应式实现
this.app = new Vue({
data: {
current: '/'
}
})
}
init() {
// 绑定浏览器事件,监听路由事件
this.bindEvents()
// 解析传入的路由配置-routes
this.createRouteMap(this.$options);
// 声明两个全局组件:router-link 和 router-view
this.initComponent()
}
bindEvents() {
window.addEventListener('hashchange', this.onHashChange.bind(this))
window.addEventListener('load', this.onHashChange.bind(this))
}
onHashChange() {
// http://localhost/#/home
this.app.current = window.location.hash.slice(1) || '/'
}
createRouteMap(options) {
// 遍历,然后缓存
options.routes.forEach(item => {
// ['/home']: {path: '/home', component: Home}
this.routeMap[item.path] = item
})
}
initComponent() {
// 声明两个全局组件
Vue.component('router-link', {
props: {
to: String
},
render(h) {
// 目标是: <a href="to">XXX</a>
return h('a', {attrs: {href: '#' + this.to}}, this.$slots.default)
// return <a href={this.to}>this.$slots.default</a>
}
})
// hash -> current -> render
Vue.component('router-view', {
// 箭头函数能保留this指向,这里指向VueRouter实例
render: h => {
const Comp = this.routeMap[this.app.current].component
return h(Comp)
}
})
}
}
// 把VueRouter变为插件-必须实现install
VueRouter.install = function(_vue) {
// 保存vue实例
Vue = _vue
// 混入任务-混入就是扩展Vue
Vue.mixin({
beforeCreate() {
// 这里的代码将来会在外面初始化的时候被调用
// 这样实现了Vue扩展
// this指向Vue组件实例
// 这里只希望根组件执行一次
if (this.$options.router) {
Vue.prototype.$router = this.$options.router
// 初始化
this.$options.router.init()
}
}
})
}
export default VueRouter
2、创建main.js
import Vue from "vue";
import App from "./App.vue";
import VueRouter from './vue-router';
//以插件的形式,使用VueRouter
Vue.use(VueRouter);
//路由配置信息,可以从外部文件引入,在此直接写是为了方便演示
const Home = { template: '<div>home</div>' }
const About = { template: '<div>about</div>' }
const routes = [
{ path: '/', component: Home },
{ path: '/about', component: About }
]
//初始化并与 Vue 实例关联
const router = new VueRouter({routes});
new Vue({
router,
render: h => h(App),
}).$mount("#root");
3、创建App.vue-用于测试
<template>
<div>
<h1 @click="goBack">App Test</h1>
<router-link to="/">Home</router-link>
<router-link to="/bar">About</router-link>
<router-view></router-view>
</div>
</template>
<script>
export default {
methods: {
goBack() {
console.log(this.$router);
window.history.length > 1 ? this.$router.go(-1) : this.$router.push('/')
}
}
}
</script>
<style lang="less" scoped>
</style>
标签:
Vue-router