vue-router源码分析(路由初始化)

路由初始化

进行路由的跳转,改变URL,渲染对应的组件

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
init(app: any /* Vue component instance */) {
// assert是个断言,测试install.installed是否为真,为真,则说明vueRouter已经安装了
process.env.NODE_ENV !== "production" &&
assert(
install.installed,
`not installed. Make sure to call \`Vue.use(VueRouter)\` ` +
`before creating root instance.`
);

// 保存组件实例:将vue实例推到apps列表中,install里面最初是将vue根实例推进去的
this.apps.push(app);

// set up app destroyed handler
// https://github.com/vuejs/vue-router/issues/2639
// app被destroyed时候,会$emit ‘hook:destroyed’事件,监听这个事件,执行下面方法
// 从apps 里将app移除
app.$once("hook:destroyed", () => {
// clean out app from this.apps array once destroyed
const index = this.apps.indexOf(app);
if (index > -1) this.apps.splice(index, 1);
// ensure we still have a main app or null if no apps
// we do not release the router so it can be reused
if (this.app === app) this.app = this.apps[0] || null;
});

// 如果根组件已经有了就返回
if (this.app) {
return;
}

// 赋值路由模式
this.app = app;

const history = this.history;

// 判断路由模式,并根据不同路由模式进行跳转。hashHistory需要监听hashchange和popshate两个事件,而html5History监听popstate事件
if (history instanceof HTML5History) {
history.transitionTo(history.getCurrentLocation());
} else if (history instanceof HashHistory) {
// 添加 hashchange 监听
const setupHashListener = () => {
history.setupListeners();
};
// 路由跳转
history.transitionTo(
history.getCurrentLocation(),
setupHashListener,
setupHashListener
);
}

// 该回调会在 transitionTo 中调用
// 对组件的 _route 属性进行赋值,触发组件渲染;且将apps中的组件的_route全部更新至最新的
history.listen(route => {
this.apps.forEach(app => {
app._route = route;
});
});
}