一 使用
-
下载
npm install vue-router --save -
在项目中新建文件夹 router/index.js
import Vue from 'vue'
import VueRouter from 'vue-router'
/*引入pages*/
const MSite = ()=>import('../pages/MSite/MSite');
const Profile = ()=>import('../pages/Profile/profile');
//申明使用插件
Vue.use(VueRouter)
export default new VueRouter({
routes:[
{
path:'/msite',
component: MSite,
meta: {
showFooter: true
}
},
{
path:'/profile',
component:Profile,
meta: {
showFooter: true
}
}
{
path: '/',
redirect: '/msite' //系统默认页
}
]
})
- 在main.js中全局使用router
import Vue from 'vue'
import App from './App'
import router from './router' //引入路由
new Vue({
el: '#app',
components: { App },
template: '<App/>',
router //引入路由
})
- 在页面中的使用
<template>
<div class="hello">
<router-link to="/">网站首页</router-link>
<router-view></router-view>
</div>
</template>
二 原理
2.1 index.js文件改写和说明
下方文件可以看出vue-route是用的new,说明./vue-router文件中是一个构造函数或者类,传入的参数是一个对象。
import Vue from 'vue'
import VueRouter from './vue-router'
import Home from '../views/Home.vue'
Vue.use(VueRouter)
const routes =[
{
path:'/',
name:'home',
component:Home
},
{
path:'/about',
name:'about',
component: () => import('../views/About.vue')
}
]
const router=new VueRouter({
mode:'history',
base:process.env.BASE_URL,
routes
})
export default router
2.2kvue-router.js文件说明
首先声明一个全局变量let vue,这是一个插件,在加入vue中都会执行install方法,并且将vue传入。我们用 Vue=_Vue;将前方声明的全局变量赋值为vue。接下来通过混入的方法将所有的组件种豆混入生命周期函数beforeCreate和原有的合并,判断在根实例后挂载。让后全局注册两个组件。
声明了一个类KVueRouter,类在new的时候会执行constructor函数,constructor函数首先将传入的参数保存,接着通过vue源码中的util.defineReactive将current做响应式,current变化就会刷新页面,接着给window绑定hashchange和load事件。执行onHashChange函数,函数内会将最新的值赋值给current。
将参数route数组进行处理,处理为一个对象,对象中的key为route.path,值为route(数组的每一项)
当URL的片段标识符更改时,将触发hashchange事件
load事件 就是窗体加载事件 应对不在首页点击刷新。
import Link from './router-link'
import View from './router-view'
let Vue;
class KVueRouter{
constructor(options){
this.$options=options
// 需要创建响应式的current属性
// 利用Vue提供的defineReactive做响应化
// 这样将来current变化的时候,依赖的组件会重新render
Vue.util.defineReactive(this,'current','/')
window.addEventListener('hashchange',this.onHashChange.bind(this))
window.addEventListener('load', this.onHashChange.bind(this))
this.routeMap={}
options.routes.forEach(route=>{
this.routeMap[route.path]=route
})
}
onHashChange(){
this.current=window.location.hash.slice(1)
}
}
KVueRouter.install=function(_Vue){
Vue=_Vue;
Vue.mixin({
//混入所有的组件执行该生命周期时都会执行下面的事件
beforeCreate(){
if(this.$options.router){
//this指向vue实力确保是根实例让后挂载。
Vue.prototype.$router=this.$options.router
}
}
})
//全局注册组件
Vue.component('router-link',Link)
Vue.component('router-view',View)
}
export default KVueRouter
2.3router-link文件说明
router-link组件的内容,将router-link标签转换为a标签。
export default{
props:{
to:{
type:String,
required:true
}
},
render(h){
// <a href="#/about">abc</a>
// <router-link to="/about">xxx</router-link>
// h(tag, data, children)
//console.log(this.$slots);
return h('a', { attrs: { href: '#' + this.to } }, this.$slots.default)
// return <a href={'#' + this.to}>{this.$slots.default}</a>
}
}
2.4router-view文件说明
route-view组件的内容,将route-view标签改为和路由对应的组件
export default{
render(h){
const {routeMap,current}=this.$router;
const component = routeMap[current].compont || null;
return h(compont)
}
}