# 简单实现
# 1.路由模式和地址
class historyRoute {
constructor() {
this.current = null
}
}
class VueRouter {
constructor(options) {
this.mode = options.mode || "hash"
this.routes = options.routes || []
//你传递的这个路由是一个数组{'/home':Home,'/about',About}
this.routesMap = this.createMap(this.routes)
// 路由中需要存放当前的路径 需要状态
this.history = new historyRoute()
}
createMap(routes) {
return routes.reduce((memo, current) => {
memo[current.path] = current.component
return memo
}, [])
}
}
VueRouter.install = function(Vue) {
//在所有组件中获取同一个路由实例
Vue.mixin({
beforeCreate() {
if (this.$options && this.$options.router) {
//定位根组件
this._root = this
this._router = this.$options.router
} else {
this._root = this.$parent._root
}
},
})
}
//使用vue.use就会调用install
export default VueRouter
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
# 2.路由模式和地址
class historyRoute {
constructor() {
this.current = null
}
}
class VueRouter {
constructor(options) {
this.mode = options.mode || "hash"
this.routes = options.routes || []
//你传递的这个路由是一个数组{'/home':Home,'/about',About}
this.routesMap = this.createMap(this.routes)
// 路由中需要存放当前的路径 需要状态
this.history = new historyRoute()
this.init()
}
init() {
if (this.mode === "hash") {
location.hash ? "" : (location.hash = "/")
window.addEventListener("load", () => {
this.history.current = location.hash.slice(1)
})
window.addEventListener("hashchange", () => {
this.history.current = location.hash.slice(1)
})
} else {
location.pathname ? "" : (location.pathname = "/")
window.addEventListener("load", () => {
this.history.current = location.pathname
})
window.addEventListener("popstate", () => {
this.history.current = location.pathname
})
}
}
createMap(routes) {
return routes.reduce((memo, current) => {
memo[current.path] = current.component
return memo
}, [])
}
}
VueRouter.install = function(Vue) {
//在所有组件中获取同一个路由实例
Vue.mixin({
beforeCreate() {
if (this.$options && this.$options.router) {
//定位根组件
this._root = this
this._router = this.$options.router
} else {
this._root = this.$parent._root
}
},
})
}
//使用vue.use就会调用install
export default VueRouter
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
# 3.获取$router和$route
class historyRoute {
constructor() {
this.current = null
}
}
class VueRouter {
constructor(options) {
this.mode = options.mode || "hash"
this.routes = options.routes || []
//你传递的这个路由是一个数组{'/home':Home,'/about',About}
this.routesMap = this.createMap(this.routes)
// 路由中需要存放当前的路径 需要状态
this.history = new historyRoute()
this.init()
}
init() {
if (this.mode === "hash") {
location.hash ? "" : (location.hash = "/")
window.addEventListener("load", () => {
this.history.current = location.hash.slice(1)
})
window.addEventListener("hashchange", () => {
this.history.current = location.hash.slice(1)
})
} else {
location.pathname ? "" : (location.pathname = "/")
window.addEventListener("load", () => {
this.history.current = location.pathname
})
window.addEventListener("popstate", () => {
this.history.current = location.pathname
})
}
}
createMap(routes) {
return routes.reduce((memo, current) => {
memo[current.path] = current.component
return memo
}, [])
}
}
VueRouter.install = function(Vue) {
//在所有组件中获取同一个路由实例
Vue.mixin({
beforeCreate() {
if (this.$options && this.$options.router) {
//定位根组件
this._root = this
this._router = this.$options.router
} else {
this._root = this.$parent._root
}
Object.defineProperty(this, "$router", {
get() {
return this._root._router
},
})
Object.defineProperty(this, "$route", {
get() {
return {
// 当前的路由所在的状态
current: this._root._router.history.current,
}
},
})
},
})
}
//使用vue.use就会调用install
export default VueRouter
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
# 4.router-link 和 router-view
class historyRoute {
constructor() {
this.current = null
}
}
class VueRouter {
constructor(options) {
this.mode = options.mode || "hash"
this.routes = options.routes || []
//你传递的这个路由是一个数组{'/home':Home,'/about',About}
this.routesMap = this.createMap(this.routes)
// 路由中需要存放当前的路径 需要状态
this.history = new historyRoute()
this.init()
}
init() {
if (this.mode === "hash") {
location.hash ? "" : (location.hash = "/")
window.addEventListener("load", () => {
this.history.current = location.hash.slice(1)
})
window.addEventListener("hashchange", () => {
this.history.current = location.hash.slice(1)
})
} else {
location.pathname ? "" : (location.pathname = "/")
window.addEventListener("load", () => {
this.history.current = location.pathname
})
window.addEventListener("popstate", () => {
this.history.current = location.pathname
})
}
}
go() {}
back() {}
push() {}
createMap(routes) {
return routes.reduce((memo, current) => {
memo[current.path] = current.component
return memo
}, [])
}
}
VueRouter.install = function(Vue) {
//在所有组件中获取同一个路由实例
Vue.mixin({
beforeCreate() {
if (this.$options && this.$options.router) {
//定位根组件
this._root = this
this._router = this.$options.router
} else {
this._root = this.$parent._root
}
Object.defineProperty(this, "$router", {
get() {
return this._root._router
},
})
Object.defineProperty(this, "$route", {
get() {
return {
// 当前的路由所在的状态
current: this._root.xxx.current,
}
},
})
},
})
Vue.component("router-link", {
render(h) {
return h("a", {}, "首页")
},
})
Vue.component("router-view", {
render(h) {
console.log(this)
return <h1>首页</h1>
},
})
}
//使用vue.use就会调用install
export default VueRouter
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
# 5.路由渲染
class historyRoute {
constructor() {
this.current = null
}
}
class VueRouter {
constructor(options) {
this.mode = options.mode || "hash"
this.routes = options.routes || []
//你传递的这个路由是一个数组{'/home':Home,'/about',About}
this.routesMap = this.createMap(this.routes)
// 路由中需要存放当前的路径 需要状态
this.history = new historyRoute()
this.init()
}
init() {
if (this.mode === "hash") {
location.hash ? "" : (location.hash = "/")
window.addEventListener("load", () => {
this.history.current = location.hash.slice(1)
})
window.addEventListener("hashchange", () => {
this.history.current = location.hash.slice(1)
})
} else {
location.pathname ? "" : (location.pathname = "/")
window.addEventListener("load", () => {
this.history.current = location.pathname
})
window.addEventListener("popstate", () => {
this.history.current = location.pathname
})
}
}
go() {}
back() {}
push() {}
createMap(routes) {
return routes.reduce((memo, current) => {
memo[current.path] = current.component
return memo
}, [])
}
}
VueRouter.install = function(Vue) {
//在所有组件中获取同一个路由实例
Vue.mixin({
beforeCreate() {
if (this.$options && this.$options.router) {
//定位根组件
this._root = this
this._router = this.$options.router
Vue.util.defineReactive(this, "xxx", this._router.history)
} else {
this._root = this.$parent._root
}
Object.defineProperty(this, "$router", {
get() {
return this._root._router
},
})
Object.defineProperty(this, "$route", {
get() {
return {
// 当前的路由所在的状态
current: this._root.xxx.current,
}
},
})
},
})
Vue.component("router-link", {
render(h) {
return h("a", {}, "首页")
},
})
Vue.component("router-view", {
render(h) {
let current = this._self._root._router.history.current
let routeMap = this._self._root._router.routesMap
return h(routeMap[current])
},
})
}
//使用vue.use就会调用install
export default VueRouter
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
# 6.实现跳转
class historyRoute {
constructor() {
this.current = null
}
}
class VueRouter {
constructor(options) {
this.mode = options.mode || "hash"
this.routes = options.routes || []
//你传递的这个路由是一个数组{'/home':Home,'/about',About}
this.routesMap = this.createMap(this.routes)
// 路由中需要存放当前的路径 需要状态
this.history = new historyRoute()
this.init()
}
init() {
if (this.mode === "hash") {
location.hash ? "" : (location.hash = "/")
window.addEventListener("load", () => {
this.history.current = location.hash.slice(1)
})
window.addEventListener("hashchange", () => {
this.history.current = location.hash.slice(1)
})
} else {
location.pathname ? "" : (location.pathname = "/")
window.addEventListener("load", () => {
this.history.current = location.pathname
})
window.addEventListener("popstate", () => {
this.history.current = location.pathname
})
}
}
go() {}
back() {}
push() {}
createMap(routes) {
return routes.reduce((memo, current) => {
memo[current.path] = current.component
return memo
}, [])
}
}
VueRouter.install = function(Vue) {
//在所有组件中获取同一个路由实例
Vue.mixin({
beforeCreate() {
if (this.$options && this.$options.router) {
//定位根组件
this._root = this
this._router = this.$options.router
Vue.util.defineReactive(this, "xxx", this._router.history)
} else {
this._root = this.$parent._root
}
Object.defineProperty(this, "$router", {
get() {
return this._root._router
},
})
Object.defineProperty(this, "$route", {
get() {
return {
// 当前的路由所在的状态
current: this._root.xxx.current,
}
},
})
},
})
Vue.component("router-link", {
props: {
to: String,
},
render() {
let mode = this._self._root._router.mode
return (
<a href={mode === "hash" ? `#${this.to}` : this.to}>
{" "}
{this.$slots.default}{" "}
</a>
)
},
})
Vue.component("router-view", {
render(h) {
let current = this._self._root._router.history.current
let routeMap = this._self._root._router.routesMap
return h(routeMap[current])
},
})
}
//使用vue.use就会调用install
export default VueRouter
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
# 7.tag 的实现
class historyRoute {
constructor() {
this.current = null
}
}
class VueRouter {
constructor(options) {
this.mode = options.mode || "hash"
this.routes = options.routes || []
//你传递的这个路由是一个数组{'/home':Home,'/about',About}
this.routesMap = this.createMap(this.routes)
// 路由中需要存放当前的路径 需要状态
this.history = new historyRoute()
this.init()
}
init() {
if (this.mode === "hash") {
location.hash ? "" : (location.hash = "/")
window.addEventListener("load", () => {
this.history.current = location.hash.slice(1)
})
window.addEventListener("hashchange", () => {
this.history.current = location.hash.slice(1)
})
} else {
location.pathname ? "" : (location.pathname = "/")
window.addEventListener("load", () => {
this.history.current = location.pathname
})
window.addEventListener("popstate", () => {
this.history.current = location.pathname
})
}
}
go() {}
back() {}
push() {}
createMap(routes) {
return routes.reduce((memo, current) => {
memo[current.path] = current.component
return memo
}, [])
}
}
VueRouter.install = function(Vue) {
//在所有组件中获取同一个路由实例
Vue.mixin({
beforeCreate() {
if (this.$options && this.$options.router) {
//定位根组件
this._root = this
this._router = this.$options.router
Vue.util.defineReactive(this, "xxx", this._router.history)
} else {
this._root = this.$parent._root
}
Object.defineProperty(this, "$router", {
get() {
return this._root._router
},
})
Object.defineProperty(this, "$route", {
get() {
return {
// 当前的路由所在的状态
current: this._root.xxx.current,
}
},
})
},
})
Vue.component("router-link", {
props: {
to: String,
tag: String,
},
methods: {
handleClick() {
//跳转逻辑
},
},
render() {
let mode = this._self._root._router.mode
let tag = this.tag || "a"
return (
<tag
on-click={this.handleClick}
href={mode === "hash" ? `#${this.to}` : this.to}
>
{" "}
{this.$slots.default}{" "}
</tag>
)
},
})
Vue.component("router-view", {
render(h) {
let current = this._self._root._router.history.current
let routeMap = this._self._root._router.routesMap
return h(routeMap[current])
},
})
}
//使用vue.use就会调用install
export default VueRouter
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106