RouterViewにScrollPositiionManagerを埋め込む
This commit is contained in:
parent
4bef4953b8
commit
e7251220d5
5 changed files with 69 additions and 61 deletions
|
|
@ -18,7 +18,7 @@
|
|||
</template>
|
||||
|
||||
<div ref="contents" :class="$style.root" style="container-type: inline-size;">
|
||||
<RouterView :key="reloadCount" :router="router"/>
|
||||
<RouterView :key="reloadCount" :router="router" :scrollContainer="contents"/>
|
||||
</div>
|
||||
</MkWindow>
|
||||
</template>
|
||||
|
|
@ -32,12 +32,11 @@ import copyToClipboard from '@/scripts/copy-to-clipboard';
|
|||
import { url } from '@/config';
|
||||
import { mainRouter, routes, page } from '@/router';
|
||||
import { $i } from '@/account';
|
||||
import { Router, useScrollPositionManager } from '@/nirax';
|
||||
import { Router } from '@/nirax';
|
||||
import { i18n } from '@/i18n';
|
||||
import { PageMetadata, provideMetadataReceiver } from '@/scripts/page-metadata';
|
||||
import { openingWindowsCount } from '@/os';
|
||||
import { claimAchievement } from '@/scripts/achievements';
|
||||
import { getScrollContainer } from '@/scripts/scroll';
|
||||
|
||||
const props = defineProps<{
|
||||
initialPath: string;
|
||||
|
|
@ -141,8 +140,6 @@ function popout() {
|
|||
windowEl.close();
|
||||
}
|
||||
|
||||
useScrollPositionManager(() => getScrollContainer(contents.value), router);
|
||||
|
||||
onMounted(() => {
|
||||
openingWindowsCount.value++;
|
||||
if (openingWindowsCount.value >= 3) {
|
||||
|
|
|
|||
|
|
@ -11,12 +11,18 @@
|
|||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { inject, onBeforeUnmount, provide } from 'vue';
|
||||
import { Resolved, Router } from '@/nirax';
|
||||
import { computed, inject, onBeforeUnmount, provide, nextTick } from 'vue';
|
||||
import { NiraxChangeEvent, Resolved, Router } from '@/nirax';
|
||||
import { defaultStore } from '@/store';
|
||||
import { getScrollContainer } from '@/scripts/scroll';
|
||||
|
||||
const props = defineProps<{
|
||||
router?: Router;
|
||||
|
||||
/**
|
||||
* Set any element if scroll position management needed
|
||||
*/
|
||||
scrollContainer?: HTMLElement | null;
|
||||
}>();
|
||||
|
||||
const router = props.router ?? inject('router');
|
||||
|
|
@ -45,17 +51,49 @@ let currentPageComponent = $shallowRef(current.route.component);
|
|||
let currentPageProps = $ref(current.props);
|
||||
let key = $ref(current.route.path + JSON.stringify(Object.fromEntries(current.props)));
|
||||
|
||||
function onChange({ resolved, key: newKey }) {
|
||||
const current = resolveNested(resolved);
|
||||
const scrollContainer = computed(() => props.scrollContainer ? (getScrollContainer(props.scrollContainer) ?? document.getElementsByTagName('html')[0]) : undefined);
|
||||
|
||||
const scrollPosStore = new Map<string, number>();
|
||||
|
||||
function onChange(ctx: NiraxChangeEvent) {
|
||||
// save scroll position
|
||||
if (scrollContainer.value) scrollPosStore.set(key, scrollContainer.value.scrollTop);
|
||||
|
||||
//#region change page
|
||||
const current = resolveNested(ctx.resolved);
|
||||
if (current == null) return;
|
||||
currentPageComponent = current.route.component;
|
||||
currentPageProps = current.props;
|
||||
key = current.route.path + JSON.stringify(Object.fromEntries(current.props));
|
||||
//#endregion
|
||||
|
||||
//#region scroll
|
||||
nextTick(() => {
|
||||
if (!scrollContainer.value) return;
|
||||
|
||||
const scrollPos = scrollPosStore.get(key) ?? 0;
|
||||
scrollContainer.value.scroll({ top: scrollPos, behavior: 'instant' });
|
||||
if (scrollPos !== 0) {
|
||||
window.setTimeout(() => { // 遷移直後はタイミングによってはコンポーネントが復元し切ってない可能性も考えられるため少し時間を空けて再度スクロール
|
||||
if (!scrollContainer.value) return;
|
||||
scrollContainer.value.scroll({ top: scrollPos, behavior: 'instant' });
|
||||
}, 100);
|
||||
}
|
||||
});
|
||||
//#endregion
|
||||
}
|
||||
|
||||
router.addListener('change', onChange);
|
||||
|
||||
function onSame() {
|
||||
if (!scrollContainer.value) return;
|
||||
scrollContainer.value.scroll({ top: 0, behavior: 'smooth' });
|
||||
}
|
||||
|
||||
router.addListener('same', onSame);
|
||||
|
||||
onBeforeUnmount(() => {
|
||||
router.removeListener('change', onChange);
|
||||
router.removeListener('same', onSame);
|
||||
});
|
||||
</script>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue