Hash 模式
- URL 中#后面的内容作为路径地址
- 监听 hashchange 事件
- 根据当前路由地址找到对应组件进行渲染
History 模式
- 通过 history.pushState()方法改变地址栏
- 监听 popstate 事件
- 根据当前路由地址找到对应组件重新渲染
// router/index.js
import Router from 'vue-router'
//注册插件
Vue.use(VueRouter);
//创建路由对象
const router = new VueRouter({
routes: [{ name: "home", path: "/",component:homeComponent }],
});
// main.js
// 创建Vue实例,注册 router对象
import router from './router'
new Vue({
router,
render:h=>h(App)
}).$mount('#app')
VueRouter(类图)
- +options
- +data
- +routeMap
- +constructor(Options):VueRouter
- —install(vue):void
- +init():void
- +initEvent():void
- +createRouteMap():void
- initComponents(Vue):viod
install
let _Vue = null;
export default class VueRouter {
static install(Vue) {
// 1. 判断挡圈 插件是否已经安装
if (VueRouter.install.installed) {
return;
}
VueRouter.install.intalled = true;
// 2. 把Vue构造函数记录到全局变量
_Vue = Vue;
// 3,把创建Vue实例时候传入router对象注入Vue实例上
// 混入
_Vue.mixin({
beforeCreate() {
if (this.$options.router) {
_Vue.prototype.$router = this.$options.router;
this.$options.router.init();
}
},
});
}
constructor(options) {
this.options = options;
this.routeMap = {};
this.data = _Vue.observable({
current: "/",
});
}
init() {
this.createRouteMap();
this.initeCompents(_Vue);
this.initEvent()
}
createRouteMap() {
//遍历所有的路由规则,把路由规则解析成键值对的形式 储存到routemap中
this.options.routes.forEach((route) => {
this.routeMap[route.path] = route.component;
});
}
initComponents(Vue) {
Vue.component("router-link", {
props: {
to: String,
},
render(h) {
return h(
"a",
{
attrs: {
href: this.to,
},
on: {
click: this.clickHandler,
},
},
[this.$slots.default]
);
},
methods: {
clickHandler(e) {
history.pushState({}, "", this.to);
this.$router.data.current = this.to;
e.preventDefault();
},
},
// template: '<a :href="to"><slot></slot></a>',
});
const self = this;
Vue.component("router-view", {
render(h) {
const component = self.routeMap[self.data.current];
return h(component);
},
});
}
initEvent(){
window.addEventListener('popstate',()=>{
this.data.current = window.location.pathname
})
}
}
Vue 的构建版本
- 运行时版本:不支持 template 模板,需要打包的时候提前编译
- 完整时版本:包含运行时和编译器,体积比运行时版本大 10k 左右,程序运行的时候把模板转换成 render 函数
方法一
//vue.config.js module.exports = { runtimeCompiler: true, };