Vue Router
Vue Router是VueJS官方的路由管理器。它和VueJS的核心深度集成,让构建单页面应用变得易如反掌
基于Hash模式的路由实现
kRouter.js
import Vue from 'vue'
import Home from '../views/Home.vue'
import About from '../views/About.vue'
class VueRouter {
constructor (options) {
this.$options = options
this.routeMap = {}
// 引用Vue中数据的响应式 当路由发生改变重新去渲染页面
this.app = new Vue({
data: {
current: '/'
}
})
}
init () {
// 监听URL的变化
this.bindEvents()
// 解析路由配置
this.createRouteMap(this.$options)
// 实现两个组件
this.initComponent()
}
bindEvents () {
window.addEventListener('load', this.onHashChange.bind(this))
window.addEventListener('hashchange', this.onHashChange.bind(this))
}
onHashChange () {
// console.log(window.location.hash) #/home
this.app.current = window.location.hash.slice(1) || '/'
}
createRouteMap (options) {
options.routes.forEach(item => {
// {'/':Home,'/about':About}
this.routeMap[item.path] = item.component
})
}
initComponent () {
// <router-link>home</router-link>
Vue.component('router-link', {
props: { to: String },
render (h) {
// this.$slots.default 存储了当前元素的子节点
return h('a', { attrs: { href: '#' + this.to } }, [
this.$slots.default
])
}
})
// router-view
Vue.component('router-view', {
render: h => {
const comp = this.routeMap[this.app.current]
return h(comp)
}
})
}
}
// 入参是Vue构造函数
VueRouter.install = function (Vue) {
// 混入
Vue.mixin({
beforeCreate () {
// this.$options 表示new VUe({})实例中的配置项
// this 是 当前的Vue实例
if (this.$options.router) {
// 仅在根组件中执行一次
// 后面的组件中都可以使用this.$router
Vue.prototype.$router = this.$options.router
this.$options.router.init()
}
}
})
}
Vue.use(VueRouter)
const routes = [
{
path: '/',
name: 'Home',
component: Home
},
{
path: '/about',
name: 'About',
component: About
}
]
const router = new VueRouter({
routes
})
export default router
1、在创建VueRouter
类的时候,需要去实现install
方法使用VueRouter
作为VueJS
的插件来使用。VueRouter
作为插件加入使用,通过mixin
混入来影响每一个Vue
实例化,在beforeCreate钩子的时候就会完成router的初始化,并且只初始化一次。
2、在VueRouter
中有三个核心的方法
- 监听URL变化
通过监听URL的变化,去找到对应的组件渲染 - 解析路由配置
将URL与组件映射成一个对象 - 构建两个组件
渲染组件(view-router)页面跳转组件(view-link)
3、render
渲染函数
简单的说,在Vue中我们使用模板HTML语法来组建页面,使用render函数我们可以用js语言来构建DOM。因为Vue是虚拟DOM,所以在拿到template模板时也要转译成vNode的函数,而用render函数构建的DOM,Vue就免去了转译过程
render: h => {
const comp = this.routeMap[this.app.current]
return h(comp)
}
这里我们将路由匹配的组件,通过render函数渲染成VNode。
基于HTML5History模式
import Vue from 'vue'
import Home from '../views/Home.vue'
import About from '../views/About.vue'
class VueRouter {
constructor (options) {
this.$options = options
this.routeMap = {}
// 引用Vue中数据的响应式 当路由发生改变重新去渲染页面
this.app = new Vue({
data: {
current: '/'
}
})
}
init () {
// 监听URL的变化
this.bindEvents()
// 解析路由配置
this.createRouteMap(this.$options)
// 实现两个组件
this.initComponent()
}
bindEvents () {
window.addEventListener('load', this.onHashChange.bind(this))
window.addEventListener('hashchange', this.onHashChange.bind(this))
}
onHashChange () {
this.app.current = window.location.pathname || '/'
}
createRouteMap (options) {
options.routes.forEach(item => {
// {'/':Home,'/about':About}
this.routeMap[item.path] = item.component
})
}
initComponent () {
// <router-link>home</router-link>
Vue.component('router-link', {
props: { to: String },
render (h) {
return h('a', { attrs: { href: this.to } }, [
this.$slots.default
])
}
})
// router-view
Vue.component('router-view', {
render: h => {
const comp = this.routeMap[this.app.current]
return h(comp)
}
})
}
}
// 入参是Vue构造函数
VueRouter.install = function (Vue) {
// 混入
Vue.mixin({
beforeCreate () {
// this.$options 表示new VUe({})实例中的配置项
// this 是 当前的Vue实例
if (this.$options.router) {
// 仅在根组件中执行一次
// 后面的组件中都可以使用this.$router
Vue.prototype.$router = this.$options.router
this.$options.router.init()
}
}
})
}
Vue.use(VueRouter)
const routes = [
{
path: '/',
name: 'Home',
component: Home
},
{
path: '/about',
name: 'About',
component: About
}
]
const router = new VueRouter({
routes
})
export default router