Article Directory
Step by step
Create the VueRouter class
/**
* VueRouter Class
* -------------------------------------
* + options
* + data
* + routeMap
* -------------------------------------
* + Constructor(Option): VueRouter
* _install(Vue): void
* + init(): void
* + initEvent: void
* + CreateRouteMap(): void
* + initComponents(Vue): void
*/
export default class VueRouter{
}
Create a static method to implement install
/**
* VueRouter Class
* -------------------------------------
* + options
* + data
* + routeMap
* -------------------------------------
* + Constructor(Option): VueRouter
* _install(Vue): void
* + init(): void
* + initEvent: void
* + CreateRouteMap(): void
* + initComponents(Vue): void
*/
export default class VueRouter{
static install(Vue){
// 1.判断当前插件是否被安装
if(VueRouter.install.installed){
return
}
VueRouter.install.installed = true
// 2.把 Vue 构造函数记录到全局变量
_Vue = Vue
// 3.把创建 Vue 实例的时候传入的 router 对象注入到 Vue 实例上
// 混入
_Vue.mixin({
beforeCreate(){
// router 执行,组件不执行
if(this.$options.router){
_Vue.prototype.$router = this.$options.router
}
}
})
}
}
implement the constructor
/**
* VueRouter Class
* -------------------------------------
* + options
* + data
* + routeMap
* -------------------------------------
* + Constructor(Option): VueRouter
* _install(Vue): void
* + init(): void
* + initEvent: void
* + CreateRouteMap(): void
* + initComponents(Vue): void
*/
export default class VueRouter{
static install(Vue){
// 1.判断当前插件是否被安装
if(VueRouter.install.installed){
return
}
VueRouter.install.installed = true
// 2.把 Vue 构造函数记录到全局变量
_Vue = Vue
// 3.把创建 Vue 实例的时候传入的 router 对象注入到 Vue 实例上
// 混入
_Vue.mixin({
beforeCreate(){
// router 执行,组件不执行
if(this.$options.router){
_Vue.prototype.$router = this.$options.router
}
}
})
}
constructor(options){
this.options = options
this.routeMap = {
}
// 将 current 注册为响应式对象
this.data = _Vue.observable({
current: '/'
})
}
}
Implement createRouteMap
/**
* VueRouter Class
* -------------------------------------
* + options
* + data
* + routeMap
* -------------------------------------
* + Constructor(Option): VueRouter
* _install(Vue): void
* + init(): void
* + initEvent: void
* + CreateRouteMap(): void
* + initComponents(Vue): void
*/
export default class VueRouter{
static install(Vue){
// 1.判断当前插件是否被安装
if(VueRouter.install.installed){
return
}
VueRouter.install.installed = true
// 2.把 Vue 构造函数记录到全局变量
_Vue = Vue
// 3.把创建 Vue 实例的时候传入的 router 对象注入到 Vue 实例上
// 混入
_Vue.mixin({
beforeCreate(){
// router 执行,组件不执行
if(this.$options.router){
_Vue.prototype.$router = this.$options.router
}
}
})
}
constructor(options){
this.options = options
this.routeMap = {
}
// 将 current 注册为响应式对象
this.data = _Vue.observable({
current: '/'
})
}
createRouteMap(){
// 遍历所有的路由规则,把路由规则解析成键值对的形式 存储到 routeMap 中
this.options.routes.forEach(route=>{
this.routeMap[route.path] = route.component
})
}
}
Implement the initComponents method - router-link
/**
* VueRouter Class
* -------------------------------------
* + options
* + data
* + routeMap
* -------------------------------------
* + Constructor(Option): VueRouter
* _install(Vue): void
* + init(): void
* + initEvent: void
* + CreateRouteMap(): void
* + initComponents(Vue): void
*/
export default class VueRouter{
static install(Vue){
// 1.判断当前插件是否被安装
if(VueRouter.install.installed){
return
}
VueRouter.install.installed = true
// 2.把 Vue 构造函数记录到全局变量
_Vue = Vue
// 3.把创建 Vue 实例的时候传入的 router 对象注入到 Vue 实例上
// 混入
_Vue.mixin({
beforeCreate(){
// router 执行,组件不执行
if(this.$options.router){
_Vue.prototype.$router = this.$options.router
this.$options.router.init()
}
}
})
}
constructor(options){
this.options = options
this.routeMap = {
}
// 将 current 注册为响应式对象
this.data = _Vue.observable({
current: '/'
})
}
init(){
this.createRouteMap()
this.initComponents(_Vue)
}
createRouteMap(){
// 遍历所有的路由规则,把路由规则解析成键值对的形式 存储到 routeMap 中
this.options.routes.forEach(route=>{
this.routeMap[route.path] = route.component
})
}
initComponents(Vue){
const self = this
Vue.component('route-link', {
props: {
to: String
},
template: '<a :href="to"><slot></slot></a>'
})
}
}
Encounter problems:you are using the runtime-only build of Vue where the template compiler is not avriable. ...
There is also a router-view error report. Don’t worry about it. The router-view component is not defined.
Vue build version:
two ways:
1. Modify configuration, add vue.config.js configuration file, modify runtimeCompiler: true
2. Replace template with render
Change to render function
/**
* VueRouter Class
* -------------------------------------
* + options
* + data
* + routeMap
* -------------------------------------
* + Constructor(Option): VueRouter
* _install(Vue): void
* + init(): void
* + initEvent: void
* + CreateRouteMap(): void
* + initComponents(Vue): void
*/
export default class VueRouter{
static install(Vue){
// 1.判断当前插件是否被安装
if(VueRouter.install.installed){
return
}
VueRouter.install.installed = true
// 2.把 Vue 构造函数记录到全局变量
_Vue = Vue
// 3.把创建 Vue 实例的时候传入的 router 对象注入到 Vue 实例上
// 混入
_Vue.mixin({
beforeCreate(){
// router 执行,组件不执行
if(this.$options.router){
_Vue.prototype.$router = this.$options.router
this.$options.router.init()
}
}
})
}
constructor(options){
this.options = options
this.routeMap = {
}
// 将 current 注册为响应式对象
this.data = _Vue.observable({
current: '/'
})
}
init(){
this.createRouteMap()
this.initComponents(_Vue)
}
createRouteMap(){
// 遍历所有的路由规则,把路由规则解析成键值对的形式 存储到 routeMap 中
this.options.routes.forEach(route=>{
this.routeMap[route.path] = route.component
})
}
initComponents(Vue){
const self = this
Vue.component('route-link', {
props: {
to: String
},
render(h){
return h('a', {
attrs: {
href: this.to
},
}, [this.$slots.default])
},
// template: '<a :href="to"><slot></slot></a>'
})
}
}
Implement the initComponents method - router-view
/**
* VueRouter Class
* -------------------------------------
* + options
* + data
* + routeMap
* -------------------------------------
* + Constructor(Option): VueRouter
* _install(Vue): void
* + init(): void
* + initEvent: void
* + CreateRouteMap(): void
* + initComponents(Vue): void
*/
export default class VueRouter{
static install(Vue){
// 1.判断当前插件是否被安装
if(VueRouter.install.installed){
return
}
VueRouter.install.installed = true
// 2.把 Vue 构造函数记录到全局变量
_Vue = Vue
// 3.把创建 Vue 实例的时候传入的 router 对象注入到 Vue 实例上
// 混入
_Vue.mixin({
beforeCreate(){
// router 执行,组件不执行
if(this.$options.router){
_Vue.prototype.$router = this.$options.router
this.$options.router.init()
}
}
})
}
constructor(options){
this.options = options
this.routeMap = {
}
// 将 current 注册为响应式对象
this.data = _Vue.observable({
current: '/'
})
}
init(){
this.createRouteMap()
this.initComponents(_Vue)
}
createRouteMap(){
// 遍历所有的路由规则,把路由规则解析成键值对的形式 存储到 routeMap 中
this.options.routes.forEach(route=>{
this.routeMap[route.path] = route.component
})
}
initComponents(Vue){
const self = this
Vue.component('route-link', {
props: {
to: String
},
render(h){
return h('a', {
attrs: {
href: this.to
},
on: {
click: this.clickHandler
}
}, [this.$slots.default])
},
methods: {
clickHandler(e){
// 取消默认行为
e.preventDefault()
// pushState 改变地址栏,但是不向服务器发送请求
history.pushState({
}, '', this.to)
// 当前路径记录到 current 里边
this.$router.data.current = this.to
}
}
// template: '<a :href="to"><slot></slot></a>'
})
Vue.component('router-view',{
// 由于 current 是响应式的,所以这里会自动渲染对应的组件
render(h){
const component = self.routeMap[self.data.current]
return h(component)
}
})
}
}
implement initEvents
/**
* VueRouter Class
* -------------------------------------
* + options
* + data
* + routeMap
* -------------------------------------
* + Constructor(Option): VueRouter
* _install(Vue): void
* + init(): void
* + initEvent: void
* + CreateRouteMap(): void
* + initComponents(Vue): void
*/
export default class VueRouter{
static install(Vue){
// 1.判断当前插件是否被安装
if(VueRouter.install.installed){
return
}
VueRouter.install.installed = true
// 2.把 Vue 构造函数记录到全局变量
_Vue = Vue
// 3.把创建 Vue 实例的时候传入的 router 对象注入到 Vue 实例上
// 混入
_Vue.mixin({
beforeCreate(){
// router 执行,组件不执行
if(this.$options.router){
_Vue.prototype.$router = this.$options.router
this.$options.router.init()
}
}
})
}
constructor(options){
this.options = options
this.routeMap = {
}
// 将 current 注册为响应式对象
this.data = _Vue.observable({
current: '/'
})
}
init(){
this.createRouteMap()
this.initComponents(_Vue)
this.initEvent()
}
createRouteMap(){
// 遍历所有的路由规则,把路由规则解析成键值对的形式 存储到 routeMap 中
this.options.routes.forEach(route=>{
this.routeMap[route.path] = route.component
})
}
initComponents(Vue){
const self = this
Vue.component('route-link', {
props: {
to: String
},
render(h){
return h('a', {
attrs: {
href: this.to
},
on: {
click: this.clickHandler
}
}, [this.$slots.default])
},
methods: {
clickHandler(e){
// 取消默认行为
e.preventDefault()
// pushState 改变地址栏,但是不向服务器发送请求
history.pushState({
}, '', this.to)
// 当前路径记录到 current 里边
this.$router.data.current = this.to
}
}
// template: '<a :href="to"><slot></slot></a>'
})
Vue.component('router-view',{
// 由于 current 是响应式的,所以这里会自动渲染对应的组件
render(h){
const component = self.routeMap[self.data.current]
return h(component)
}
})
}
initEvent(){
// 点击浏览器的前进后退按钮触发
window.addEventListener('popstate', ()=>{
this.data.current = window.location.pathname
})
}
}
full code
/**
* VueRouter Class
* -------------------------------------
* + options
* + data
* + routeMap
* -------------------------------------
* + Constructor(Option): VueRouter
* _install(Vue): void
* + init(): void
* + initEvent: void
* + CreateRouteMap(): void
* + initComponents(Vue): void
*/
export default class VueRouter{
static install(Vue){
// 1.判断当前插件是否被安装
if(VueRouter.install.installed){
return
}
VueRouter.install.installed = true
// 2.把 Vue 构造函数记录到全局变量
_Vue = Vue
// 3.把创建 Vue 实例的时候传入的 router 对象注入到 Vue 实例上
// 混入
_Vue.mixin({
beforeCreate(){
// router 执行,组件不执行
if(this.$options.router){
_Vue.prototype.$router = this.$options.router
this.$options.router.init()
}
}
})
}
constructor(options){
this.options = options
this.routeMap = {
}
// 将 current 注册为响应式对象
this.data = _Vue.observable({
current: '/'
})
}
init(){
this.createRouteMap()
this.initComponents(_Vue)
this.initEvent()
}
createRouteMap(){
// 遍历所有的路由规则,把路由规则解析成键值对的形式 存储到 routeMap 中
this.options.routes.forEach(route=>{
this.routeMap[route.path] = route.component
})
}
initComponents(Vue){
const self = this
Vue.component('route-link', {
props: {
to: String
},
render(h){
return h('a', {
attrs: {
href: this.to
},
on: {
click: this.clickHandler
}
}, [this.$slots.default])
},
methods: {
clickHandler(e){
// 取消默认行为
e.preventDefault()
// pushState 改变地址栏,但是不向服务器发送请求
history.pushState({
}, '', this.to)
// 当前路径记录到 current 里边
this.$router.data.current = this.to
}
}
// template: '<a :href="to"><slot></slot></a>'
})
Vue.component('router-view',{
// 由于 current 是响应式的,所以这里会自动渲染对应的组件
render(h){
const component = self.routeMap[self.data.current]
return h(component)
}
})
}
initEvent(){
// 点击浏览器的前进后退按钮触发
window.addEventListener('popstate', ()=>{
this.data.current = window.location.pathname
})
}
}
Note that this is just a simulation of the principle, and there are other restrictions and judgments inside, and other processing is not perfect.