# 简单实现

# 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.路由模式和地址

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

# 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
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

# 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

# 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

# 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