最近看了一些教学,做为本身的总结一下。实现一下low 版本Vue-routerjavascript
install
方法,详情参考这里constructor
须要接收一个对象router-link
,router-view
,须要全局注册router-link
,router-view
这两个方法options
的参数。还有对应的三个方法,分别执行 第一步4中的事情,仍是实现install
方法let Vue // 先定义定义一个Vue
class MyVueRouter {
constructor (options) { // 在建立实例的时候会接受一个配置项
this.$options = options
this.routeMap = {} // 后面会说
// 路由响应式 强绑定,这就是与 react 里面router区别的缘由 只能用于Vue
this.app = new Vue({
data: {
current: '/'
}
})
}
init () {
this.bindEvents() // 监听 url变化,绑定事件
this.createRouterMap(this.$options) // 解析路由配置
this.initComponent() // 实现router-view 那两个组件
}
bindEvents () { // 监听 url变化
}
onHashChange () { // 解析路由配置
}
createRouterMap (options) { // 实现router-view 那两个组件
}
initComponent () {
// router-link router-view
Vue.component('router-link', {
}
})
// router-view
Vue.component('router-view', {
}
}
复制代码
说一下上面为何要new Vue()
,咱们须要一个值来 记录当前的地址栏current
,因此这里面就用到了Vue的特性。这就是Vue-router只能用在Vue不能用在其余语言中的缘由html
// 做为建立
MyVueRouter.install = function (_vue) { // 做为插件 实际执行的是这个方法 在执行过程当中会返回一个Vue实例
Vue = _vue
Vue.mixin({ // 扩展组件
beforeCreate () {
// this 是当前Vue实例
if (this.$options.router) {
// 在跟组件执行一次
Vue.prototype.$router = this.$options.router
this.$options.router.init()
}
}
})
}
// 使用组件
Vue.use(MyVueRouter)
复制代码
首先理清楚这个方法的做用就是,监听url的变化。当url变化的时候执行指定的方法/函数vue
bindEvents () {
// 监听刚打开页面的时候 注意绑定this指向
window.addEventListener('load', this.onHashChange.bind(this))
// 监听刚url变化的时候
window.addEventListener('hashchange', this.onHashChange.bind(this))
}
复制代码
经常使用事件的网址,须要的你们自行点击 这里 ,注意 不须要加onjava
onHashChange () {
this.app.current = window.location.hash.slice(1) || '/'
// 方便你们看到全部改变 打印的日志
console.log(this.app.current)
console.log(window.location.hash)
}
复制代码
这个没什么解释的,就是利用改变Vue的响应, 改变current
node
为何要从1位开始?react
hash路由,前面有# 详细请看 打印日志vue-router
做用 解析路由配置,让其一一对应api
这时在上面建立的routeMap
就有用了app
createRouterMap (options) {
options.routes.forEach(item => {
this.routeMap[item.path] = item.component
})
}
复制代码
建立键值对,使component
和路由current
一一对应框架
做用 实现router-link
,router-view
这两个方法
initComponent () {
// router-link router-view
Vue.component('router-link', {
props: { to: String },
render (createElement) {
// createElement 参数 tag data(可选) children attrs原生的html属性 this.$slots.default a标签里面的文字
return createElement('a', { attrs: { href: '#' + this.to } }, [this.$slots.default])
// 返回Vnode 虚拟dom
}
})
// router-view
Vue.component('router-view', {
render: (h) => { // h createElement简写 用件头函数 改变了this指向
// 全局组件 跟全局vue有关 里面属性发生变化
const comp = this.routeMap[this.app.current]
// comp 拿到了对应的组件
return h(comp)
}
})
}
复制代码
有关 createElement的详情,请点击这里
有关render 函数,请点击 这里
首先进行全局注册
接受一个参数 props:{to: String}
平时使用的是这样使用,若是有须要多加一些,这里只实现这一个
<router-link to="/">Home</router-link>
由于 router-link
最主要做用是跳转,因此咱们建立一个a标签
,配置跳转信息来实现跳转
注意,这里面使用的是箭头函数,不是普通函数,目的,解决this指向问题
由于使用的过程当中不须要参数,因此不用写props
咱们只须要拿到当前current
对应的,拿到对应的模板,交给createElement渲染就行
import a from './../components/a'
import b from './../components/b'
// url变化 路由解析 组件配置
class MyVueRouter {
constructor (options) { // 在建立实例的时候会接受一个配置项
this.$options = options
this.routeMap = {}
// 路由响应式 强绑定,这就是与 react 里面router区别的缘由 只能用于Vue
this.app = new Vue({
data: {
current: '/form'
}
})
}
init () {
this.bindEvents() // 监听 url变化
this.createRouterMap(this.$options) // 解析路由配置
this.initComponent() // 实现router-view 那两个组件
}
bindEvents () {
window.addEventListener('load', this.onHashChange.bind(this))
window.addEventListener('hashchange', this.onHashChange.bind(this))
}
onHashChange () {
this.app.current = window.location.hash.slice(1) || '/'
console.log(this.app.current)
console.log(window.location.hash)
}
createRouterMap (options) {
options.routes.forEach(item => {
this.routeMap[item.path] = item.component
})
}
initComponent () {
// router-link router-view
Vue.component('router-link', {
props: { to: String },
render (createElement) {
// createElement 参数 tag data(可选) children attrs原生的html属性 this.$slots.default a标签里面的文字
return createElement('a', { attrs: { href: '#' + this.to } }, [this.$slots.default])
}
})
// router-view
Vue.component('router-view', {
render: (h) => {
// h createElement缩写 用件头函数 改变了this指向 // 全局组件 跟全局vue有关 里面属性发生变化
const comp = this.routeMap[this.app.current]
console.log(comp)
return h(comp)
}
})
}
}
// 做为建立
MyVueRouter.install = function (Vue) {
// 做为插件 实际执行的是这个方法
// 是能够收到一个Vue实例
Vue.mixin({ // 扩展组件
beforeCreate () {
// this 是当前Vue实例
if (this.$options.router) {
// 在跟组件执行一次
Vue.prototype.$router = this.$options.router
this.$options.router.init()
}
}
})
}
Vue.use(MyVueRouter)
export default new MyVueRouter({
routes: [
{
path: '/',
name: 'A',
component: a
},
{
path: '/b',
name: 'B',
component: b
}
]
})
复制代码
<template>
<div id="app">
<router-link to="/">Home</router-link> |
<router-link to="/b">B</router-link> |
<router-view></router-view>
</div>
</template>
复制代码