diff options
| author | syuilo <4439005+syuilo@users.noreply.github.com> | 2025-03-19 18:06:22 +0900 |
|---|---|---|
| committer | syuilo <4439005+syuilo@users.noreply.github.com> | 2025-03-19 18:06:22 +0900 |
| commit | 81ac71f7e59623625369aaff75a8712923450b80 (patch) | |
| tree | c36eb84c0724121db8d2381cbb8fab0593ff53ea /packages/frontend/src/components | |
| parent | better import paths (diff) | |
| download | misskey-81ac71f7e59623625369aaff75a8712923450b80.tar.gz misskey-81ac71f7e59623625369aaff75a8712923450b80.tar.bz2 misskey-81ac71f7e59623625369aaff75a8712923450b80.zip | |
refactor(frontend): router refactoring
Diffstat (limited to 'packages/frontend/src/components')
4 files changed, 53 insertions, 108 deletions
diff --git a/packages/frontend/src/components/MkPageWindow.vue b/packages/frontend/src/components/MkPageWindow.vue index fae4246335..4fbdc51d22 100644 --- a/packages/frontend/src/components/MkPageWindow.vue +++ b/packages/frontend/src/components/MkPageWindow.vue @@ -59,7 +59,7 @@ const windowRouter = createRouter(props.initialPath); const pageMetadata = ref<null | PageMetadata>(null); const windowEl = shallowRef<InstanceType<typeof MkWindow>>(); const history = ref<{ path: string; }[]>([{ - path: windowRouter.getCurrentPath(), + path: windowRouter.getCurrentFullPath(), }]); const buttonsLeft = computed(() => { const buttons: Record<string, unknown>[] = []; @@ -97,20 +97,20 @@ function getSearchMarker(path: string) { const searchMarkerId = ref<string | null>(getSearchMarker(props.initialPath)); windowRouter.addListener('push', ctx => { - history.value.push({ path: ctx.path }); + history.value.push({ path: ctx.fullPath }); }); windowRouter.addListener('replace', ctx => { history.value.pop(); - history.value.push({ path: ctx.path }); + history.value.push({ path: ctx.fullPath }); }); windowRouter.addListener('change', ctx => { - if (_DEV_) console.log('windowRouter: change', ctx.path); - searchMarkerId.value = getSearchMarker(ctx.path); + if (_DEV_) console.log('windowRouter: change', ctx.fullPath); + searchMarkerId.value = getSearchMarker(ctx.fullPath); analytics.page({ - path: ctx.path, - title: ctx.path, + path: ctx.fullPath, + title: ctx.fullPath, }); }); @@ -139,14 +139,14 @@ const contextmenu = computed(() => ([{ icon: 'ti ti-external-link', text: i18n.ts.openInNewTab, action: () => { - window.open(url + windowRouter.getCurrentPath(), '_blank', 'noopener'); + window.open(url + windowRouter.getCurrentFullPath(), '_blank', 'noopener'); windowEl.value?.close(); }, }, { icon: 'ti ti-link', text: i18n.ts.copyLink, action: () => { - copyToClipboard(url + windowRouter.getCurrentPath()); + copyToClipboard(url + windowRouter.getCurrentFullPath()); }, }])); @@ -164,12 +164,12 @@ function close() { } function expand() { - mainRouter.push(windowRouter.getCurrentPath(), 'forcePage'); + mainRouter.push(windowRouter.getCurrentFullPath(), 'forcePage'); windowEl.value?.close(); } function popout() { - _popout(windowRouter.getCurrentPath(), windowEl.value?.$el); + _popout(windowRouter.getCurrentFullPath(), windowEl.value?.$el); windowEl.value?.close(); } diff --git a/packages/frontend/src/components/global/NestedRouterView.vue b/packages/frontend/src/components/global/NestedRouterView.vue index 5b22d0b7a8..af00347db8 100644 --- a/packages/frontend/src/components/global/NestedRouterView.vue +++ b/packages/frontend/src/components/global/NestedRouterView.vue @@ -14,8 +14,9 @@ SPDX-License-Identifier: AGPL-3.0-only </template> <script lang="ts" setup> -import { inject, onBeforeUnmount, provide, ref, shallowRef } from 'vue'; -import type { Router, Resolved } from '@/router.js'; +import { inject, provide, ref, shallowRef } from 'vue'; +import type { Router } from '@/router.js'; +import type { PathResolvedResult } from '@/lib/nirax.js'; import MkLoadingPage from '@/pages/_loading_.vue'; import { DI } from '@/di.js'; @@ -32,7 +33,7 @@ if (router == null) { const currentDepth = inject(DI.routerCurrentDepth, 0); provide(DI.routerCurrentDepth, currentDepth + 1); -function resolveNested(current: Resolved, d = 0): Resolved | null { +function resolveNested(current: PathResolvedResult, d = 0): PathResolvedResult | null { if (d === currentDepth) { return current; } else { @@ -47,19 +48,13 @@ function resolveNested(current: Resolved, d = 0): Resolved | null { const current = resolveNested(router.current)!; const currentPageComponent = shallowRef('component' in current.route ? current.route.component : MkLoadingPage); const currentPageProps = ref(current.props); -const key = ref(router.getCurrentPath()); +const key = ref(router.getCurrentFullPath()); -function onChange({ resolved }) { +router.useListener('change', ({ resolved }) => { const current = resolveNested(resolved); if (current == null || 'redirect' in current.route) return; currentPageComponent.value = current.route.component; currentPageProps.value = current.props; - key.value = router.getCurrentPath(); -} - -router.addListener('change', onChange); - -onBeforeUnmount(() => { - router.removeListener('change', onChange); + key.value = router.getCurrentFullPath(); }); </script> diff --git a/packages/frontend/src/components/global/RouterView.vue b/packages/frontend/src/components/global/RouterView.vue index 720034a942..fbdb7d261e 100644 --- a/packages/frontend/src/components/global/RouterView.vue +++ b/packages/frontend/src/components/global/RouterView.vue @@ -5,10 +5,7 @@ SPDX-License-Identifier: AGPL-3.0-only <template> <div class="_pageContainer" style="height: 100%;"> - <KeepAlive - :max="prefer.s.numberOfPageCache" - :exclude="pageCacheController" - > + <KeepAlive :max="prefer.s.numberOfPageCache"> <Suspense :timeout="0"> <component :is="currentPageComponent" :key="key" v-bind="Object.fromEntries(currentPageProps)"/> @@ -21,10 +18,9 @@ SPDX-License-Identifier: AGPL-3.0-only </template> <script lang="ts" setup> -import { inject, onBeforeUnmount, provide, ref, shallowRef, computed, nextTick } from 'vue'; -import type { Router, Resolved, RouteDef } from '@/router.js'; +import { inject, provide, ref, shallowRef } from 'vue'; +import type { Router } from '@/router.js'; import { prefer } from '@/preferences.js'; -import { globalEvents } from '@/events.js'; import MkLoadingPage from '@/pages/_loading_.vue'; import { DI } from '@/di.js'; @@ -44,45 +40,12 @@ provide(DI.routerCurrentDepth, currentDepth + 1); const current = router.current!; const currentPageComponent = shallowRef('component' in current.route ? current.route.component : MkLoadingPage); const currentPageProps = ref(current.props); -const key = ref(router.getCurrentPath()); +const key = ref(router.getCurrentFullPath()); -function onChange({ resolved }) { +router.useListener('change', ({ resolved }) => { if (resolved == null || 'redirect' in resolved.route) return; currentPageComponent.value = resolved.route.component; currentPageProps.value = resolved.props; - key.value = router.getCurrentPath(); - - nextTick(() => { - // ページ遷移完了後に再びキャッシュを有効化 - if (clearCacheRequested.value) { - clearCacheRequested.value = false; - } - }); -} - -router.addListener('change', onChange); - -// #region キャッシュ制御 - -/** - * キャッシュクリアが有効になったら、全キャッシュをクリアする - * - * keepAlive側にwatcherがあるのですぐ消えるとはおもうけど、念のためページ遷移完了まではキャッシュを無効化しておく。 - * キャッシュ有効時向けにexcludeを使いたい場合は、pageCacheControllerに並列に突っ込むのではなく、下に追記すること - */ -const pageCacheController = computed(() => clearCacheRequested.value ? /.*/ : undefined); -const clearCacheRequested = ref(false); - -globalEvents.on('requestClearPageCache', () => { - if (_DEV_) console.log('clear page cache requested'); - if (!clearCacheRequested.value) { - clearCacheRequested.value = true; - } -}); - -// #endregion - -onBeforeUnmount(() => { - router.removeListener('change', onChange); + key.value = router.getCurrentFullPath(); }); </script> diff --git a/packages/frontend/src/components/global/StackingRouterView.vue b/packages/frontend/src/components/global/StackingRouterView.vue index b94e020072..c95c74aef3 100644 --- a/packages/frontend/src/components/global/StackingRouterView.vue +++ b/packages/frontend/src/components/global/StackingRouterView.vue @@ -13,7 +13,7 @@ SPDX-License-Identifier: AGPL-3.0-only :duration="200" tag="div" :class="$style.tabs" > - <div v-for="(tab, i) in tabs" :key="tab.key" :class="$style.tab" :style="{ '--i': i - 1 }"> + <div v-for="(tab, i) in tabs" :key="tab.fullPath" :class="$style.tab" :style="{ '--i': i - 1 }"> <div v-if="i > 0" :class="$style.tabBg" @click="back()"></div> <div :class="$style.tabFg" @click.stop="back()"> <div v-if="i > 0" :class="$style.tabMenu"> @@ -41,10 +41,9 @@ SPDX-License-Identifier: AGPL-3.0-only </template> <script lang="ts" setup> -import { inject, onBeforeUnmount, provide, ref, shallowRef, computed, nextTick } from 'vue'; -import type { Router, Resolved, RouteDef } from '@/router.js'; +import { inject, provide, shallowRef } from 'vue'; +import type { Router } from '@/router.js'; import { prefer } from '@/preferences.js'; -import { globalEvents } from '@/events.js'; import MkLoadingPage from '@/pages/_loading_.vue'; import { DI } from '@/di.js'; import { deepEqual } from '@/utility/deep-equal.js'; @@ -63,26 +62,36 @@ const currentDepth = inject(DI.routerCurrentDepth, 0); provide(DI.routerCurrentDepth, currentDepth + 1); const tabs = shallowRef([{ - key: router.getCurrentPath(), - path: router.getCurrentPath(), - route: router.current.route.path, + fullPath: router.getCurrentFullPath(), + routePath: router.current.route.path, component: 'component' in router.current.route ? router.current.route.component : MkLoadingPage, props: router.current.props, }]); -function onChange({ resolved }) { +function mount() { const currentTab = tabs.value[tabs.value.length - 1]; - const route = resolved.route.path; + tabs.value = [currentTab]; +} + +function back() { + const prev = tabs.value[tabs.value.length - 2]; + tabs.value = [...tabs.value.slice(0, tabs.value.length - 1)]; + router.replace(prev.fullPath); +} + +router.useListener('change', ({ resolved }) => { + const currentTab = tabs.value[tabs.value.length - 1]; + const routePath = resolved.route.path; if (resolved == null || 'redirect' in resolved.route) return; - if (resolved.route.path === currentTab.path && deepEqual(resolved.props, currentTab.props)) return; - const fullPath = router.getCurrentPath(); + if (resolved.route.path === currentTab.routePath && deepEqual(resolved.props, currentTab.props)) return; + const fullPath = router.getCurrentFullPath(); - if (tabs.value.some(tab => tab.route === route && deepEqual(resolved.props, tab.props))) { + if (tabs.value.some(tab => tab.routePath === routePath && deepEqual(resolved.props, tab.props))) { const newTabs = []; for (const tab of tabs.value) { newTabs.push(tab); - if (tab.route === route && deepEqual(resolved.props, tab.props)) { + if (tab.routePath === routePath && deepEqual(resolved.props, tab.props)) { break; } } @@ -93,45 +102,23 @@ function onChange({ resolved }) { tabs.value = tabs.value.length >= prefer.s.numberOfPageCache ? [ ...tabs.value.slice(1), { - key: fullPath, - path: fullPath, - route, + fullPath: fullPath, + routePath, component: resolved.route.component, props: resolved.props, }, ] : [...tabs.value, { - key: fullPath, - path: fullPath, - route, + fullPath: fullPath, + routePath, component: resolved.route.component, props: resolved.props, }]; -} +}); -function onReplace({ path }) { +router.useListener('replace', ({ fullPath }) => { const currentTab = tabs.value[tabs.value.length - 1]; - console.log('replace', currentTab.path, path); - currentTab.path = path; + currentTab.fullPath = fullPath; tabs.value = [...tabs.value.slice(0, tabs.value.length - 1), currentTab]; -} - -function mount() { - const currentTab = tabs.value[tabs.value.length - 1]; - tabs.value = [currentTab]; -} - -function back() { - const prev = tabs.value[tabs.value.length - 2]; - tabs.value = [...tabs.value.slice(0, tabs.value.length - 1)]; - router.replace(prev.path); -} - -router.addListener('replace', onReplace); -router.addListener('change', onChange); - -onBeforeUnmount(() => { - router.removeListener('replace', onReplace); - router.removeListener('change', onChange); }); </script> |