From: Eduardo San Martin Morote Date: Sun, 22 Mar 2020 18:08:14 +0000 (+0100) Subject: refactor: use symbols for properties X-Git-Tag: v4.0.0-alpha.4~32 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=05bcde410fa124bd6c406561839a4b313a195efe;p=thirdparty%2Fvuejs%2Frouter.git refactor: use symbols for properties --- diff --git a/__tests__/mount.ts b/__tests__/mount.ts index 782570ee..ac99e772 100644 --- a/__tests__/mount.ts +++ b/__tests__/mount.ts @@ -2,6 +2,7 @@ import { Component, createApp, nextTick } from 'vue' import * as runtimeDom from '@vue/runtime-dom' import { compile } from '@vue/compiler-dom' import { Router } from '../src' +import { routerKey, routeLocationKey } from '../src/utils/injectionSymbols' export function mount( router: Router, @@ -14,8 +15,8 @@ export function mount( const { template, components, ...ComponentWithoutTemplate } = Component const app = createApp(ComponentWithoutTemplate as any, rootProps) - app.provide('router', router) - app.provide('route', router.currentRoute) + app.provide(routerKey, router) + app.provide(routeLocationKey, router.currentRoute) for (const componentName in components) { app.component(componentName, components[componentName]) diff --git a/src/components/Link.ts b/src/components/Link.ts index afd3b20e..4d2f8262 100644 --- a/src/components/Link.ts +++ b/src/components/Link.ts @@ -10,7 +10,7 @@ import { } from 'vue' import { RouteLocation, RouteLocationNormalized, Immutable } from '../types' import { isSameLocationObject, isSameRouteRecord } from '../utils' -import { routerKey } from '../injectKeys' +import { routerKey } from '../utils/injectionSymbols' type VueUseOptions = { [k in keyof T]: Ref | T[k] @@ -26,6 +26,7 @@ type UseLinkOptions = VueUseOptions export function useLink(props: UseLinkOptions) { const router = inject(routerKey)! + const currentRoute = router.currentRoute const route = computed(() => router.resolve(unref(props.to))) const href = computed(() => router.createHref(route.value)) @@ -33,7 +34,7 @@ export function useLink(props: UseLinkOptions) { const activeRecordIndex = computed(() => { // TODO: handle children with empty path: they should relate to their parent const currentMatched = route.value.matched[route.value.matched.length - 1] - return router.currentRoute.value.matched.findIndex( + return currentRoute.value.matched.findIndex( isSameRouteRecord.bind(null, currentMatched) ) }) @@ -41,13 +42,12 @@ export function useLink(props: UseLinkOptions) { const isActive = computed( () => activeRecordIndex.value > -1 && - includesParams(router.currentRoute.value.params, route.value.params) + includesParams(currentRoute.value.params, route.value.params) ) const isExactActive = computed( () => - activeRecordIndex.value === - router.currentRoute.value.matched.length - 1 && - isSameLocationObject(router.currentRoute.value.params, route.value.params) + activeRecordIndex.value === currentRoute.value.matched.length - 1 && + isSameLocationObject(currentRoute.value.params, route.value.params) ) // TODO: handle replace prop diff --git a/src/components/View.ts b/src/components/View.ts index 3414a9dd..07faee9e 100644 --- a/src/components/View.ts +++ b/src/components/View.ts @@ -5,18 +5,15 @@ import { defineComponent, PropType, computed, - InjectionKey, ref, ComponentPublicInstance, - ComputedRef, } from 'vue' -import { routeKey } from '../injectKeys' import { RouteLocationMatched } from '../types' - -// TODO: make it work with no symbols too for IE -export const matchedRouteKey = Symbol() as InjectionKey< - ComputedRef -> +import { + matchedRouteKey, + viewDepthKey, + routeLocationKey, +} from '../utils/injectionSymbols' export const View = defineComponent({ name: 'RouterView', @@ -28,9 +25,9 @@ export const View = defineComponent({ }, setup(props, { attrs }) { - const route = inject(routeKey)! - const depth: number = inject('routerViewDepth', 0) - provide('routerViewDepth', depth + 1) + const route = inject(routeLocationKey)! + const depth: number = inject(viewDepthKey, 0) + provide(viewDepthKey, depth + 1) const matchedRoute = computed( () => route.value.matched[depth] as RouteLocationMatched | undefined diff --git a/src/index.ts b/src/index.ts index 4bccbb7b..567d35d5 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,6 +1,8 @@ import createWebHistory from './history/html5' import createMemoryHistory from './history/memory' import createWebHashHistory from './history/hash' +import { inject } from 'vue' +import { routerKey, routeLocationKey } from './utils/injectionSymbols' export { RouteLocationNormalized, @@ -10,8 +12,15 @@ export { export { createRouter, Router, RouterOptions } from './router' export { onBeforeRouteLeave } from './navigationGuards' -export { useRoute, useRouter } from './injectKeys' export { Link } from './components/Link' export { View } from './components/View' export { createWebHistory, createMemoryHistory, createWebHashHistory } + +export function useRouter() { + return inject(routerKey)! +} + +export function useRoute() { + return inject(routeLocationKey)! +} diff --git a/src/injectKeys.ts b/src/injectKeys.ts deleted file mode 100644 index a79bbb78..00000000 --- a/src/injectKeys.ts +++ /dev/null @@ -1,16 +0,0 @@ -import { InjectionKey, Ref, inject } from 'vue' -import { Router, RouteLocationNormalized } from '.' -import { RouteLocationNormalizedResolved } from './types' - -export const routerKey = ('router' as unknown) as InjectionKey -export const routeKey = ('route' as unknown) as InjectionKey< - Ref -> - -export function useRouter(): Router { - return inject(routerKey)! -} - -export function useRoute(): Ref { - return inject(routeKey)! -} diff --git a/src/navigationGuards.ts b/src/navigationGuards.ts index 515fd3e9..2671cb99 100644 --- a/src/navigationGuards.ts +++ b/src/navigationGuards.ts @@ -1,7 +1,7 @@ import { NavigationGuard } from './types' import { inject, getCurrentInstance, warn } from 'vue' -import { matchedRouteKey } from './components/View' import { RouteRecordNormalized } from './matcher/types' +import { matchedRouteKey } from './utils/injectionSymbols' export function onBeforeRouteLeave(leaveGuard: NavigationGuard) { const instance = getCurrentInstance() diff --git a/src/router.ts b/src/router.ts index 4c7a82d9..bdb819b6 100644 --- a/src/router.ts +++ b/src/router.ts @@ -38,6 +38,7 @@ import { ref, Ref, markNonReactive, nextTick, App, warn } from 'vue' import { RouteRecordNormalized } from './matcher/types' import { Link } from './components/Link' import { View } from './components/View' +import { routerKey, routeLocationKey } from './utils/injectionSymbols' type ErrorHandler = (error: any) => any // resolve, reject arguments of Promise constructor @@ -553,8 +554,8 @@ function applyRouterPlugin(app: App, router: Router) { }) // TODO: merge strats? - app.provide('router', router) - app.provide('route', router.currentRoute) + app.provide(routerKey, router) + app.provide(routeLocationKey, router.currentRoute) } async function runGuardQueue(guards: Lazy[]): Promise { diff --git a/src/types/index.ts b/src/types/index.ts index dd7bd201..93f502c0 100644 --- a/src/types/index.ts +++ b/src/types/index.ts @@ -136,7 +136,7 @@ export interface RouteRecordCommon { props?: | boolean | Record - | ((to: RouteLocationNormalized) => Record) + | ((to: Immutable) => Record) // TODO: beforeEnter has no effect with redirect, move and test beforeEnter?: NavigationGuard | NavigationGuard[] meta?: Record diff --git a/src/utils/index.ts b/src/utils/index.ts index ec4c0a20..ac3ec408 100644 --- a/src/utils/index.ts +++ b/src/utils/index.ts @@ -8,12 +8,10 @@ import { import { guardToPromiseFn } from './guardToPromiseFn' import { RouteRecordNormalized } from '../matcher/types' import { LocationQueryValue } from './query' +import { hasSymbol } from './injectionSymbols' export * from './guardToPromiseFn' -const hasSymbol = - typeof Symbol === 'function' && typeof Symbol.toStringTag === 'symbol' - function isESModule(obj: any): obj is { default: RouteComponent } { return obj.__esModule || (hasSymbol && obj[Symbol.toStringTag] === 'Module') } diff --git a/src/utils/injectionSymbols.ts b/src/utils/injectionSymbols.ts new file mode 100644 index 00000000..7f4f6e8c --- /dev/null +++ b/src/utils/injectionSymbols.ts @@ -0,0 +1,28 @@ +import { InjectionKey, ComputedRef, Ref } from 'vue' +import { + RouteLocationMatched, + Immutable, + RouteLocationNormalizedResolved, +} from '../types' +import { Router } from '../router' + +export const hasSymbol = + typeof Symbol === 'function' && typeof Symbol.toStringTag === 'symbol' + +export const PolySymbol = (name: string) => + // vr = vue router + hasSymbol ? Symbol(name) : `_vr_` + name + +// rvlm = Router View Location Matched +export const matchedRouteKey = PolySymbol('rvlm') as InjectionKey< + ComputedRef +> +// rvd = Router View Depth +export const viewDepthKey = PolySymbol('rvd') as InjectionKey + +// r = router +export const routerKey = PolySymbol('r') as InjectionKey +// rt = route location +export const routeLocationKey = PolySymbol('rl') as InjectionKey< + Ref> +>