perf: 使用 vueuse 实现页面滚动锁定

This commit is contained in:
pengzhanbo 2023-12-23 01:52:12 +08:00
parent 1db07c4215
commit 387dff9a60
4 changed files with 44 additions and 136 deletions

View File

@ -68,7 +68,6 @@
"@vuepress/shared": "2.0.0-rc.0",
"@vuepress/utils": "2.0.0-rc.0",
"@vueuse/core": "^10.7.0",
"body-scroll-lock": "4.0.0-beta.0",
"date-fns": "^3.0.5",
"lodash.merge": "^4.6.2",
"nanoid": "^5.0.4",

View File

@ -1,33 +1,27 @@
<script setup lang="ts">
import { clearAllBodyScrollLocks, disableBodyScroll } from 'body-scroll-lock'
import { ref } from 'vue'
import { useScrollLock } from '@vueuse/core'
import { inBrowser } from '../../utils/index.js'
import NavScreenAppearance from './NavScreenAppearance.vue'
import NavScreenMenu from './NavScreenMenu.vue'
import NavScreenSocialLinks from './NavScreenSocialLinks.vue'
import NavScreenTranslates from './NavScreenTranslations.vue'
defineProps<{
open: boolean
}>()
const screen = ref<HTMLElement | null>(null)
const isLocked = useScrollLock(inBrowser ? document.body : null)
function lockBodyScroll() {
disableBodyScroll(screen.value!, { reserveScrollBarGap: true })
}
function unlockBodyScroll() {
clearAllBodyScrollLocks()
}
</script>
<template>
<Transition
name="fade"
@enter="lockBodyScroll"
@after-leave="unlockBodyScroll"
@enter="isLocked = true"
@after-leave="isLocked = false"
>
<div v-if="open" ref="screen" class="nav-screen">
<div v-if="open" id="navScreen" class="nav-screen">
<div class="container">
<NavScreenMenu class="menu" />
<NavScreenTranslates class="translations" />

View File

@ -1,7 +1,8 @@
<script lang="ts" setup>
import { clearAllBodyScrollLocks, disableBodyScroll } from 'body-scroll-lock'
import { ref, watchPostEffect } from 'vue'
import { useScrollLock } from '@vueuse/core'
import { ref, watch } from 'vue'
import { useSidebar } from '../composables/sidebar.js'
import { inBrowser } from '../utils/index.js'
import SidebarItem from './SidebarItem.vue'
const { sidebarGroups, hasSidebar } = useSidebar()
@ -12,23 +13,18 @@ const props = defineProps<{
// a11y: focus Nav element when menu has opened
const navEl = ref<HTMLElement | null>(null)
const isLocked = useScrollLock(inBrowser ? document.body : null)
function lockBodyScroll() {
disableBodyScroll(navEl.value!, { reserveScrollBarGap: true })
}
function unlockBodyScroll() {
clearAllBodyScrollLocks()
}
watchPostEffect(async () => {
if (props.open) {
lockBodyScroll()
navEl.value?.focus()
} else {
unlockBodyScroll()
}
})
watch(
[props, navEl],
() => {
if (props.open) {
isLocked.value = true
navEl.value?.focus()
} else isLocked.value = false
},
{ immediate: true, flush: 'post' }
)
</script>
<template>
@ -74,7 +70,7 @@ watchPostEffect(async () => {
overflow-x: hidden;
overflow-y: auto;
transform: translateX(-100%);
transition: opacity 0.5s, transform 0.25s ease;
transition: opacity 0.5s, transform 0.5s cubic-bezier(0.19, 1, 0.22, 1);
}
.sidebar-wrapper.open {
@ -92,7 +88,6 @@ watchPostEffect(async () => {
.sidebar-wrapper {
z-index: 1;
padding-top: var(--vp-nav-height);
padding-bottom: 128px;
width: var(--vp-sidebar-width);
max-width: 100%;
background-color: var(--vp-sidebar-bg-color);

124
pnpm-lock.yaml generated
View File

@ -103,7 +103,7 @@ importers:
version: 5.3.3
vite:
specifier: ^5.0.10
version: 5.0.10(@types/node@20.9.1)
version: 5.0.10(@types/node@20.9.1)(sass@1.69.5)
docs:
dependencies:
@ -474,9 +474,6 @@ importers:
'@vueuse/core':
specifier: ^10.7.0
version: 10.7.0(vue@3.3.13)
body-scroll-lock:
specifier: 4.0.0-beta.0
version: 4.0.0-beta.0
date-fns:
specifier: ^3.0.5
version: 3.0.5
@ -2012,7 +2009,7 @@ packages:
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
dependencies:
ajv: 6.12.6
debug: 4.3.4
debug: 4.3.4(supports-color@9.2.2)
espree: 9.6.1
globals: 13.19.0
ignore: 5.2.4
@ -2128,7 +2125,7 @@ packages:
engines: {node: '>=10.10.0'}
dependencies:
'@humanwhocodes/object-schema': 2.0.1
debug: 4.3.4
debug: 4.3.4(supports-color@9.2.2)
minimatch: 3.1.2
transitivePeerDependencies:
- supports-color
@ -4658,7 +4655,7 @@ packages:
'@typescript-eslint/type-utils': 6.15.0(eslint@8.56.0)(typescript@5.3.3)
'@typescript-eslint/utils': 6.15.0(eslint@8.56.0)(typescript@5.3.3)
'@typescript-eslint/visitor-keys': 6.15.0
debug: 4.3.4
debug: 4.3.4(supports-color@9.2.2)
eslint: 8.56.0
graphemer: 1.4.0
ignore: 5.2.4
@ -4684,7 +4681,7 @@ packages:
'@typescript-eslint/types': 6.15.0
'@typescript-eslint/typescript-estree': 6.15.0(typescript@5.3.3)
'@typescript-eslint/visitor-keys': 6.15.0
debug: 4.3.4
debug: 4.3.4(supports-color@9.2.2)
eslint: 8.56.0
typescript: 5.3.3
transitivePeerDependencies:
@ -4711,7 +4708,7 @@ packages:
dependencies:
'@typescript-eslint/typescript-estree': 6.15.0(typescript@5.3.3)
'@typescript-eslint/utils': 6.15.0(eslint@8.56.0)(typescript@5.3.3)
debug: 4.3.4
debug: 4.3.4(supports-color@9.2.2)
eslint: 8.56.0
ts-api-utils: 1.0.1(typescript@5.3.3)
typescript: 5.3.3
@ -4761,7 +4758,7 @@ packages:
dependencies:
'@typescript-eslint/types': 6.15.0
'@typescript-eslint/visitor-keys': 6.15.0
debug: 4.3.4
debug: 4.3.4(supports-color@9.2.2)
globby: 11.1.0
is-glob: 4.0.3
semver: 7.5.4
@ -5656,15 +5653,6 @@ packages:
/add-stream@1.0.0:
resolution: {integrity: sha512-qQLMr+8o0WC4FZGQTcJiKBVC59JylcPSrTtk6usvmIDFUOCKegapy1VHQwRbFMOFyb/inzUVqHs+eMYKDM1YeQ==}
/agent-base@6.0.2:
resolution: {integrity: sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==}
engines: {node: '>= 6.0.0'}
dependencies:
debug: 4.3.4
transitivePeerDependencies:
- supports-color
dev: true
/agent-base@6.0.2(supports-color@9.2.2):
resolution: {integrity: sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==}
engines: {node: '>= 6.0.0'}
@ -5672,13 +5660,12 @@ packages:
debug: 4.3.4(supports-color@9.2.2)
transitivePeerDependencies:
- supports-color
dev: false
/agent-base@7.1.0:
resolution: {integrity: sha512-o/zjMZRhJxny7OyEF+Op8X+efiELC7k7yOjMzgfzVqOzXqkBkWI79YoTdOtsuWd5BWhAGAuOY/Xa6xpiaWXiNg==}
engines: {node: '>= 14'}
dependencies:
debug: 4.3.4
debug: 4.3.4(supports-color@9.2.2)
transitivePeerDependencies:
- supports-color
dev: true
@ -5687,7 +5674,7 @@ packages:
resolution: {integrity: sha512-Zn4cw2NEqd+9fiSVWMscnjyQ1a8Yfoc5oBajLeo5w+YBHgDUcEBY2hS4YpTz6iN5f/2zQiktcuM6tS8x1p9dpA==}
engines: {node: '>= 8.0.0'}
dependencies:
debug: 4.3.4
debug: 4.3.4(supports-color@9.2.2)
depd: 1.1.2
humanize-ms: 1.2.1
transitivePeerDependencies:
@ -6330,10 +6317,6 @@ packages:
- supports-color
dev: false
/body-scroll-lock@4.0.0-beta.0:
resolution: {integrity: sha512-a7tP5+0Mw3YlUJcGAKUqIBkYYGlYxk2fnCasq/FUph1hadxlTRjF+gAcZksxANnaMnALjxEddmSi/H3OR8ugcQ==}
dev: false
/bonjour-service@1.0.13:
resolution: {integrity: sha512-LWKRU/7EqDUC9CTAQtuZl5HzBALoCYwtLhffW3et7vZMwv3bWLpJf8bRYlMD5OCcDpTfnPgNCV4yo9ZIaJGMiA==}
dependencies:
@ -7635,7 +7618,7 @@ packages:
hasBin: true
dependencies:
debounce: 1.2.1
debug: 4.3.4
debug: 4.3.4(supports-color@9.2.2)
duplexer: 0.1.2
fs-extra: 11.1.1
glob: 10.3.10
@ -7880,17 +7863,6 @@ packages:
dependencies:
ms: 2.1.3
/debug@4.3.4:
resolution: {integrity: sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==}
engines: {node: '>=6.0'}
peerDependencies:
supports-color: '*'
peerDependenciesMeta:
supports-color:
optional: true
dependencies:
ms: 2.1.2
/debug@4.3.4(supports-color@9.2.2):
resolution: {integrity: sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==}
engines: {node: '>=6.0'}
@ -7902,7 +7874,6 @@ packages:
dependencies:
ms: 2.1.2
supports-color: 9.2.2
dev: false
/decache@4.6.2:
resolution: {integrity: sha512-2LPqkLeu8XWHU8qNCS3kcF6sCcb5zIzvWaAHYSvPfwhdd7mHuah29NssMzrTYyHN4F5oFy2ko9OBYxegtU0FEw==}
@ -8912,7 +8883,7 @@ packages:
ajv: 6.12.6
chalk: 4.1.2
cross-spawn: 7.0.3
debug: 4.3.4
debug: 4.3.4(supports-color@9.2.2)
doctrine: 3.0.0
escape-string-regexp: 4.0.0
eslint-scope: 7.2.2
@ -10515,8 +10486,8 @@ packages:
engines: {node: '>= 6'}
dependencies:
'@tootallnate/once': 2.0.0
agent-base: 6.0.2
debug: 4.3.4
agent-base: 6.0.2(supports-color@9.2.2)
debug: 4.3.4(supports-color@9.2.2)
transitivePeerDependencies:
- supports-color
dev: true
@ -10526,7 +10497,7 @@ packages:
engines: {node: '>= 14'}
dependencies:
agent-base: 7.1.0
debug: 4.3.4
debug: 4.3.4(supports-color@9.2.2)
transitivePeerDependencies:
- supports-color
dev: true
@ -10616,16 +10587,6 @@ packages:
resolve-alpn: 1.2.1
dev: false
/https-proxy-agent@5.0.1:
resolution: {integrity: sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==}
engines: {node: '>= 6'}
dependencies:
agent-base: 6.0.2
debug: 4.3.4
transitivePeerDependencies:
- supports-color
dev: true
/https-proxy-agent@5.0.1(supports-color@9.2.2):
resolution: {integrity: sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==}
engines: {node: '>= 6'}
@ -10634,14 +10595,13 @@ packages:
debug: 4.3.4(supports-color@9.2.2)
transitivePeerDependencies:
- supports-color
dev: false
/https-proxy-agent@7.0.2:
resolution: {integrity: sha512-NmLNjm6ucYwtcUmL7JQC1ZQ57LmHP4lT15FQ8D61nak1rO6DH+fz5qNK2Ap5UN4ZapYICE3/0KodcLYSPsPbaA==}
engines: {node: '>= 14'}
dependencies:
agent-base: 7.1.0
debug: 4.3.4
debug: 4.3.4(supports-color@9.2.2)
transitivePeerDependencies:
- supports-color
dev: true
@ -10718,7 +10678,6 @@ packages:
/immutable@4.1.0:
resolution: {integrity: sha512-oNkuqVTA8jqG1Q6c+UglTOD1xhC1BtjKI7XkCXRkZHrN5m18/XsnUp8Q89GkQO/z+0WjonSvl0FLhDYftp46nQ==}
dev: false
/import-fresh@3.3.0:
resolution: {integrity: sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==}
@ -11746,7 +11705,7 @@ packages:
dependencies:
chalk: 5.3.0
commander: 11.1.0
debug: 4.3.4
debug: 4.3.4(supports-color@9.2.2)
execa: 8.0.1
lilconfig: 3.0.0
listr2: 8.0.0
@ -12126,7 +12085,7 @@ packages:
cacache: 16.1.3
http-cache-semantics: 4.1.1
http-proxy-agent: 5.0.0
https-proxy-agent: 5.0.1
https-proxy-agent: 5.0.1(supports-color@9.2.2)
is-lambda: 1.0.1
lru-cache: 7.14.1
minipass: 3.3.6
@ -14959,7 +14918,6 @@ packages:
chokidar: 3.5.3
immutable: 4.1.0
source-map-js: 1.0.2
dev: false
/sax@1.2.4:
resolution: {integrity: sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==}
@ -15316,8 +15274,8 @@ packages:
resolution: {integrity: sha512-Fgl0YPZ902wEsAyiQ+idGd1A7rSFx/ayC1CQVMw5P+EQx2V0SgpGtf6OKFhVjPflPUl9YMmEOnmfjCdMUsygww==}
engines: {node: '>= 10'}
dependencies:
agent-base: 6.0.2
debug: 4.3.4
agent-base: 6.0.2(supports-color@9.2.2)
debug: 4.3.4(supports-color@9.2.2)
socks: 2.7.1
transitivePeerDependencies:
- supports-color
@ -15328,7 +15286,7 @@ packages:
engines: {node: '>= 14'}
dependencies:
agent-base: 7.1.0
debug: 4.3.4
debug: 4.3.4(supports-color@9.2.2)
socks: 2.7.1
transitivePeerDependencies:
- supports-color
@ -15835,7 +15793,6 @@ packages:
/supports-color@9.2.2:
resolution: {integrity: sha512-XC6g/Kgux+rJXmwokjm9ECpD6k/smUoS5LKlUCcsYr4IY3rW0XyAympon2RmxGrlnZURMpg5T18gWDP9CsHXFA==}
engines: {node: '>=12'}
dev: false
/supports-hyperlinks@2.2.0:
resolution: {integrity: sha512-6sXEzV5+I5j8Bmq9/vUphGRM/RJNT9SCURJLjwfOg51heRtguGWDzcaBlgAzKhQa0EVNpPEKzQuBwZ8S8WaCeQ==}
@ -16335,7 +16292,7 @@ packages:
engines: {node: ^16.14.0 || >=18.0.0}
dependencies:
'@tufjs/models': 2.0.0
debug: 4.3.4
debug: 4.3.4(supports-color@9.2.2)
make-fetch-happen: 13.0.0
transitivePeerDependencies:
- supports-color
@ -16822,42 +16779,6 @@ packages:
- supports-color
dev: false
/vite@5.0.10(@types/node@20.9.1):
resolution: {integrity: sha512-2P8J7WWgmc355HUMlFrwofacvr98DAjoE52BfdbwQtyLH06XKwaL/FMnmKM2crF0iX4MpmMKoDlNCB1ok7zHCw==}
engines: {node: ^18.0.0 || >=20.0.0}
hasBin: true
peerDependencies:
'@types/node': ^18.0.0 || >=20.0.0
less: '*'
lightningcss: ^1.21.0
sass: '*'
stylus: '*'
sugarss: '*'
terser: ^5.4.0
peerDependenciesMeta:
'@types/node':
optional: true
less:
optional: true
lightningcss:
optional: true
sass:
optional: true
stylus:
optional: true
sugarss:
optional: true
terser:
optional: true
dependencies:
'@types/node': 20.9.1
esbuild: 0.19.10
postcss: 8.4.32
rollup: 4.4.1
optionalDependencies:
fsevents: 2.3.3
dev: true
/vite@5.0.10(@types/node@20.9.1)(sass@1.69.5):
resolution: {integrity: sha512-2P8J7WWgmc355HUMlFrwofacvr98DAjoE52BfdbwQtyLH06XKwaL/FMnmKM2crF0iX4MpmMKoDlNCB1ok7zHCw==}
engines: {node: ^18.0.0 || >=20.0.0}
@ -16893,7 +16814,6 @@ packages:
sass: 1.69.5
optionalDependencies:
fsevents: 2.3.3
dev: false
/vscode-oniguruma@1.7.0:
resolution: {integrity: sha512-L9WMGRfrjOhgHSdOYgCt/yRMsXzLDJSL7BPrOZt73gU0iWO4mpqzqQzOz5srxqTvMBaR0XZTSrVWo4j55Rc6cA==}
@ -16924,7 +16844,7 @@ packages:
peerDependencies:
eslint: '>=6.0.0'
dependencies:
debug: 4.3.4
debug: 4.3.4(supports-color@9.2.2)
eslint: 8.56.0
eslint-scope: 7.2.2
eslint-visitor-keys: 3.4.3