From 65d774da653eb299c56b35505ce896e9314be72c Mon Sep 17 00:00:00 2001 From: RyanZephyr Date: Sat, 12 Aug 2023 21:37:52 +0800 Subject: [PATCH] commit. --- src/history/base.js | 1 + src/install.js | 21 +++++++++++++++++++++ src/router.js | 15 +++++++++++++-- 3 files changed, 35 insertions(+), 2 deletions(-) diff --git a/src/history/base.js b/src/history/base.js index 4751cd97a..362483291 100644 --- a/src/history/base.js +++ b/src/history/base.js @@ -36,6 +36,7 @@ export class History { cleanupListeners: Function // implemented by sub-classes + // +: syntax from flow, meaning read-only properties. +go: (n: number) => void +push: (loc: RawLocation, onComplete?: Function, onAbort?: Function) => void +replace: ( diff --git a/src/install.js b/src/install.js index ee8506aa8..811bf8e7e 100644 --- a/src/install.js +++ b/src/install.js @@ -1,12 +1,20 @@ import View from './components/view' import Link from './components/link' +// 引用Vue构造函数。 export let _Vue +// 做四件事: +// 1. 全局混入两个lifecycle hook:beforeCreate & destroyed. +// 2. 在Vue.prototype上设置两个只读属性:$router & $route. +// 3. 全局注册两个组件:RouterView & RouterLink. +// 4. 设置路由相关的三个lifecycle hook的合并策略:取created使用的合并策略。 export function install (Vue) { + // 借助install.installed属性确保install操作只进行一次。 if (install.installed && _Vue === Vue) return install.installed = true + // 设置Vue构造函数引用。 _Vue = Vue const isDef = v => v !== undefined @@ -18,14 +26,23 @@ export function install (Vue) { } } + // 全局混入:给所有后续创建的组件混入两个生命周期钩子函数:beforeCreate和destroyed。 Vue.mixin({ beforeCreate () { + // 判断组件选项中是否有router选项。只有根组件选项终会有router选项。 if (isDef(this.$options.router)) { + // 当前创建的组件实例为根组件实例,且组件选项中有router选项。 + + // 设置属性_routerRoot引用根路由:根实例的引用 this._routerRoot = this + // 设置属性_router引用路由对象 this._router = this.$options.router + // 初始化路由对象 this._router.init(this) + // 定义_router属性,指向当前历史记录。(?) Vue.util.defineReactive(this, '_route', this._router.history.current) } else { + // 当前创建的组件实例不是根组件实例,向上获取根实例的引用来设置属性_routerRoot。 this._routerRoot = (this.$parent && this.$parent._routerRoot) || this } registerInstance(this, this) @@ -35,6 +52,7 @@ export function install (Vue) { } }) + // 在Vue.prototype上设置两个静态只读属性:$router和$route。 Object.defineProperty(Vue.prototype, '$router', { get () { return this._routerRoot._router } }) @@ -43,9 +61,12 @@ export function install (Vue) { get () { return this._routerRoot._route } }) + // 全局注册两个组件:RouterView和RouterLink。 Vue.component('RouterView', View) Vue.component('RouterLink', Link) + // 将created使用的合并策略 设为 三个路由相关生命周期钩子的合并策略: + // beforeRouteEnter/beforeRouteLeave/beforeRouteUpdate const strats = Vue.config.optionMergeStrategies // use the same hook merging strategy for route hooks strats.beforeRouteEnter = strats.beforeRouteLeave = strats.beforeRouteUpdate = strats.created diff --git a/src/router.js b/src/router.js index 5f677dc82..78021bfff 100644 --- a/src/router.js +++ b/src/router.js @@ -17,6 +17,7 @@ import { AbstractHistory } from './history/abstract' import type { Matcher } from './create-matcher' +// router组件选项,对应一个VueRouter实例。 export default class VueRouter { static install: () => void static version: string @@ -41,25 +42,34 @@ export default class VueRouter { if (process.env.NODE_ENV !== 'production') { warn(this instanceof VueRouter, `Router must be called with the new operator.`) } + this.app = null this.apps = [] this.options = options this.beforeHooks = [] this.resolveHooks = [] this.afterHooks = [] - this.matcher = createMatcher(options.routes || [], this) + this.matcher = createMatcher(options.routes || [], this) // 创建matcher实例 + + // 1. 确定使用的路由模式 + let mode = options.mode || 'hash' // 默认使用hash路由模式 - let mode = options.mode || 'hash' + // 如果路由选项设置了history路由模式, + // 同时,环境不支持history.pushState,且路由选项fallback允许回退到hash路由模式, + // 则回退到hash路由模式。 this.fallback = mode === 'history' && !supportsPushState && options.fallback !== false if (this.fallback) { mode = 'hash' } + + // 非浏览器环境下,使用abstract路由模式 if (!inBrowser) { mode = 'abstract' } this.mode = mode + // 2. 应用最终选定的路由模式,创建相应的History实例。 switch (mode) { case 'history': this.history = new HTML5History(this, options.base) @@ -116,6 +126,7 @@ export default class VueRouter { this.app = app + // 调用this.history的两个方法:transitionTo() & listen(). const history = this.history if (history instanceof HTML5History || history instanceof HashHistory) {