From 236a2e43f37bfbad12f56bfd6fb60b97a9b8fdff Mon Sep 17 00:00:00 2001 From: neverland Date: Sun, 21 Aug 2022 11:18:20 +0800 Subject: [PATCH] fix(Popover): can not scroll inside popup (#10949) * fix(Popover): can not scroll inside popup * fix: ref --- packages/vant/package.json | 2 +- .../vant/src/composables/use-lock-scroll.ts | 4 +- packages/vant/src/popover/Popover.tsx | 21 ++++-- pnpm-lock.yaml | 75 ++++++++++++------- 4 files changed, 66 insertions(+), 36 deletions(-) diff --git a/packages/vant/package.json b/packages/vant/package.json index 8940c1a79..187121958 100644 --- a/packages/vant/package.json +++ b/packages/vant/package.json @@ -46,7 +46,7 @@ "dependencies": { "@vant/icons": "^1.8.0", "@vant/popperjs": "^1.2.1", - "@vant/use": "^1.4.1" + "@vant/use": "^1.4.2" }, "peerDependencies": { "vue": "^3.0.0" diff --git a/packages/vant/src/composables/use-lock-scroll.ts b/packages/vant/src/composables/use-lock-scroll.ts index dacc64229..e227d6d28 100644 --- a/packages/vant/src/composables/use-lock-scroll.ts +++ b/packages/vant/src/composables/use-lock-scroll.ts @@ -12,11 +12,13 @@ export function useLockScroll( shouldLock: () => boolean ) { const touch = useTouch(); + const DIRECTION_UP = '01'; + const DIRECTION_DOWN = '10'; const onTouchMove = (event: TouchEvent) => { touch.move(event); - const direction = touch.deltaY.value > 0 ? '10' : '01'; + const direction = touch.deltaY.value > 0 ? DIRECTION_DOWN : DIRECTION_UP; const el = getScrollParent( event.target as Element, rootRef.value diff --git a/packages/vant/src/popover/Popover.tsx b/packages/vant/src/popover/Popover.tsx index 69369f652..e7b007cd9 100644 --- a/packages/vant/src/popover/Popover.tsx +++ b/packages/vant/src/popover/Popover.tsx @@ -3,6 +3,7 @@ import { watch, nextTick, onMounted, + watchEffect, onBeforeUnmount, defineComponent, type PropType, @@ -90,6 +91,7 @@ export default defineComponent({ setup(props, { emit, slots, attrs }) { let popper: Instance | null; + const popupRef = ref(); const wrapperRef = ref(); const popoverRef = ref(); @@ -144,11 +146,6 @@ export default defineComponent({ } }; - const onTouchstart = (event: TouchEvent) => { - event.stopPropagation(); - emit('touchstart', event); - }; - const onClickAction = (action: PopoverAction, index: number) => { if (action.disabled) { return; @@ -163,6 +160,7 @@ export default defineComponent({ const onClickAway = () => { if ( + props.show && props.closeOnClickOutside && (!props.overlay || props.closeOnClickOverlay) ) { @@ -203,7 +201,13 @@ export default defineComponent({ ); }; - onMounted(updateLocation); + onMounted(() => { + updateLocation(); + watchEffect(() => { + popupRef.value = popoverRef.value?.popupRef.value; + }); + }); + onBeforeUnmount(() => { if (popper) { popper.destroy(); @@ -213,7 +217,9 @@ export default defineComponent({ watch(() => [props.show, props.offset, props.placement], updateLocation); - useClickAway(wrapperRef, onClickAway, { eventName: 'touchstart' }); + useClickAway([wrapperRef, popupRef], onClickAway, { + eventName: 'touchstart', + }); return () => ( <> @@ -226,7 +232,6 @@ export default defineComponent({ position={''} transition="van-popover-zoom" lockScroll={false} - onTouchstart={onTouchstart} onUpdate:show={updateShow} {...attrs} {...pick(props, popupProps)} diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 09acdc75b..6a2bca88d 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -51,7 +51,7 @@ importers: '@vant/eslint-config': workspace:* '@vant/icons': ^1.8.0 '@vant/popperjs': ^1.2.1 - '@vant/use': ^1.4.1 + '@vant/use': ^1.4.2 '@vue/runtime-core': ^3.2.27 '@vue/test-utils': ^2.0.1 typescript: ^4.7.4 @@ -199,7 +199,7 @@ importers: '@typescript-eslint/parser': 5.30.3_eslint@8.19.0+typescript@4.7.4 eslint-config-airbnb-base: 15.0.0_86af6c937a18f7b068a2d4281b478827 eslint-config-prettier: 8.5.0_eslint@8.19.0 - eslint-plugin-import: 2.26.0_eslint@8.19.0 + eslint-plugin-import: 2.26.0_b991b8cc37fbaea14375bc1442f912c5 eslint-plugin-vue: 9.1.1_eslint@8.19.0 devDependencies: enhanced-resolve: 5.10.0 @@ -253,6 +253,9 @@ packages: peerDependencies: '@algolia/client-search': ^4.9.1 algoliasearch: ^4.9.1 + peerDependenciesMeta: + '@algolia/client-search': + optional: true dependencies: '@algolia/autocomplete-shared': 1.7.1 algoliasearch: 4.13.1 @@ -800,6 +803,13 @@ packages: '@types/react': '>= 16.8.0 < 19.0.0' react: '>= 16.8.0 < 19.0.0' react-dom: '>= 16.8.0 < 19.0.0' + peerDependenciesMeta: + '@types/react': + optional: true + react: + optional: true + react-dom: + optional: true dependencies: '@algolia/autocomplete-core': 1.7.1 '@algolia/autocomplete-preset-algolia': 1.7.1_algoliasearch@4.13.1 @@ -1601,14 +1611,12 @@ packages: '@vue/shared': 3.2.37 estree-walker: 2.0.2 source-map: 0.6.1 - dev: true /@vue/compiler-dom/3.2.37: resolution: {integrity: sha512-yxJLH167fucHKxaqXpYk7x8z7mMEnXOw3G2q62FTkmsvNxu4FQSu5+3UMb+L7fjKa26DEzhrmCxAgFLLIzVfqQ==} dependencies: '@vue/compiler-core': 3.2.37 '@vue/shared': 3.2.37 - dev: true /@vue/compiler-sfc/3.2.37: resolution: {integrity: sha512-+7i/2+9LYlpqDv+KTtWhOZH+pa8/HnX/905MdVmAcI/mPQOBwkHHIzrsEsucyOIZQYMkXUiTkmZq5am/NyXKkg==} @@ -1623,14 +1631,12 @@ packages: magic-string: 0.25.9 postcss: 8.4.14 source-map: 0.6.1 - dev: true /@vue/compiler-ssr/3.2.37: resolution: {integrity: sha512-7mQJD7HdXxQjktmsWp/J67lThEIcxLemz1Vb5I6rYJHR5vI+lON3nPGOH3ubmbvYGt8xEUaAr1j7/tIFWiEOqw==} dependencies: '@vue/compiler-dom': 3.2.37 '@vue/shared': 3.2.37 - dev: true /@vue/devtools-api/6.2.0: resolution: {integrity: sha512-pF1G4wky+hkifDiZSWn8xfuLOJI1ZXtuambpBEYaf7Xaf6zC/pM29rvAGpd3qaGXnr4BAXU1Pxz/VfvBGwexGA==} @@ -1643,20 +1649,17 @@ packages: '@vue/shared': 3.2.37 estree-walker: 2.0.2 magic-string: 0.25.9 - dev: true /@vue/reactivity/3.2.37: resolution: {integrity: sha512-/7WRafBOshOc6m3F7plwzPeCu/RCVv9uMpOwa/5PiY1Zz+WLVRWiy0MYKwmg19KBdGtFWsmZ4cD+LOdVPcs52A==} dependencies: '@vue/shared': 3.2.37 - dev: true /@vue/runtime-core/3.2.37: resolution: {integrity: sha512-JPcd9kFyEdXLl/i0ClS7lwgcs0QpUAWj+SKX2ZC3ANKi1U4DOtiEr6cRqFXsPwY5u1L9fAjkinIdB8Rz3FoYNQ==} dependencies: '@vue/reactivity': 3.2.37 '@vue/shared': 3.2.37 - dev: true /@vue/runtime-dom/3.2.37: resolution: {integrity: sha512-HimKdh9BepShW6YozwRKAYjYQWg9mQn63RGEiSswMbW+ssIht1MILYlVGkAGGQbkhSh31PCdoUcfiu4apXJoPw==} @@ -1664,7 +1667,6 @@ packages: '@vue/runtime-core': 3.2.37 '@vue/shared': 3.2.37 csstype: 2.6.20 - dev: true /@vue/server-renderer/3.2.37_vue@3.2.37: resolution: {integrity: sha512-kLITEJvaYgZQ2h47hIzPh2K3jG8c1zCVbp/o/bzQOyvzaKiCquKS7AaioPI28GNxIsE/zSx+EwWYsNxDCX95MA==} @@ -1674,11 +1676,9 @@ packages: '@vue/compiler-ssr': 3.2.37 '@vue/shared': 3.2.37 vue: 3.2.37 - dev: true /@vue/shared/3.2.37: resolution: {integrity: sha512-4rSJemR2NQIo9Klm1vabqWjD8rs/ZaJSzMxkMNeJS6lHiUjjUeYFbooN19NgFjztubEKh3WlZUeOLVdbbUWHsw==} - dev: true /@vue/test-utils/2.0.1_vue@3.2.37: resolution: {integrity: sha512-4kt7Sw1gzXeQOsMqrwrQbmEiG8El4MP8P4hfxkmfXdUHf7yHa3xC5CQc0x2YyuhT41w2d4K4O0ZdRvZhGdZlow==} @@ -2537,7 +2537,6 @@ packages: /csstype/2.6.20: resolution: {integrity: sha512-/WwNkdXfckNgw6S5R125rrW8ez139lBHWouiBvX8dfMFtcn6V81REDqnH7+CRpRipfYlyU1CmOnOxrmGcFOjeA==} - dev: true /dargs/7.0.0: resolution: {integrity: sha512-2iy1EkLdlBzQGvbweYRFxmFath8+K7+AKB0TlhHWkNuH+TmovaMH/Wp7V7R4u7f4SnX3OgLsU9t1NI9ioDnUpg==} @@ -2563,6 +2562,11 @@ packages: /debug/2.6.9: resolution: {integrity: sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true dependencies: ms: 2.0.0 dev: false @@ -3135,7 +3139,7 @@ packages: dependencies: confusing-browser-globals: 1.0.11 eslint: 8.19.0 - eslint-plugin-import: 2.26.0_eslint@8.19.0 + eslint-plugin-import: 2.26.0_b991b8cc37fbaea14375bc1442f912c5 object.assign: 4.1.2 object.entries: 1.1.5 semver: 6.3.0 @@ -3157,27 +3161,46 @@ packages: resolve: 1.22.1 dev: false - /eslint-module-utils/2.7.3: + /eslint-module-utils/2.7.3_0e410f8f48e63a2eb2da71474b5e1cf0: resolution: {integrity: sha512-088JEC7O3lDZM9xGe0RerkOMd0EjFl+Yvd1jPWIkMT5u3H9+HC34mWWPnqPrN13gieT9pBOO+Qt07Nb/6TresQ==} engines: {node: '>=4'} + peerDependencies: + '@typescript-eslint/parser': '*' + eslint-import-resolver-node: '*' + eslint-import-resolver-typescript: '*' + eslint-import-resolver-webpack: '*' + peerDependenciesMeta: + '@typescript-eslint/parser': + optional: true + eslint-import-resolver-node: + optional: true + eslint-import-resolver-typescript: + optional: true + eslint-import-resolver-webpack: + optional: true dependencies: - debug: 3.2.7 - find-up: 2.1.0 + '@typescript-eslint/parser': 5.30.3_eslint@8.19.0+typescript@4.7.4 + eslint-import-resolver-node: 0.3.6 dev: false - /eslint-plugin-import/2.26.0_eslint@8.19.0: + /eslint-plugin-import/2.26.0_b991b8cc37fbaea14375bc1442f912c5: resolution: {integrity: sha512-hYfi3FXaM8WPLf4S1cikh/r4IxnO6zrhZbEGz2b660EJRbuxgpDS5gkCuYgGWg2xxh2rBuIr4Pvhve/7c31koA==} engines: {node: '>=4'} peerDependencies: + '@typescript-eslint/parser': '*' eslint: ^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8 + peerDependenciesMeta: + '@typescript-eslint/parser': + optional: true dependencies: + '@typescript-eslint/parser': 5.30.3_eslint@8.19.0+typescript@4.7.4 array-includes: 3.1.5 array.prototype.flat: 1.3.0 debug: 2.6.9 doctrine: 2.1.0 eslint: 8.19.0 eslint-import-resolver-node: 0.3.6 - eslint-module-utils: 2.7.3 + eslint-module-utils: 2.7.3_0e410f8f48e63a2eb2da71474b5e1cf0 has: 1.0.3 is-core-module: 2.9.0 is-glob: 4.0.3 @@ -3185,6 +3208,10 @@ packages: object.values: 1.1.5 resolve: 1.22.1 tsconfig-paths: 3.14.1 + transitivePeerDependencies: + - eslint-import-resolver-typescript + - eslint-import-resolver-webpack + - supports-color dev: false /eslint-plugin-vue/9.1.1_eslint@8.19.0: @@ -5063,7 +5090,6 @@ packages: hasBin: true dependencies: js-tokens: 4.0.0 - dev: true /lower-case/2.0.2: resolution: {integrity: sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg==} @@ -5098,7 +5124,6 @@ packages: resolution: {integrity: sha512-RmF0AsMzgt25qzqqLc1+MbHmhdx0ojF2Fvs4XnOqz2ZOBXzzkEwc/dJQZCYHAn7v1jbVOjAZfK8msRn4BxO4VQ==} dependencies: sourcemap-codec: 1.4.8 - dev: true /make-dir/2.1.0: resolution: {integrity: sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==} @@ -5926,11 +5951,13 @@ packages: resolution: {integrity: sha512-6IMTriUmvsjHUjNtEDudZfuDQUoWXVxKHhlEGSk81n4YFS+r/Kl99wXiwlVXtPBtJenozv2P+hxDsw9eA7Xo6g==} peerDependencies: react: ^18.2.0 + peerDependenciesMeta: + react: + optional: true dependencies: loose-envify: 1.4.0 react: 18.2.0 scheduler: 0.23.0 - dev: true /react-is/17.0.2: resolution: {integrity: sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==} @@ -5941,7 +5968,6 @@ packages: engines: {node: '>=0.10.0'} dependencies: loose-envify: 1.4.0 - dev: true /read-pkg-up/3.0.0: resolution: {integrity: sha512-YFzFrVvpC6frF1sz8psoHDBGF7fLPc+llq/8NB43oagqWkx8ar5zYtsTORtOjw9W2RHLpWP+zTWwBvf1bCmcSw==} @@ -6204,7 +6230,6 @@ packages: resolution: {integrity: sha512-CtuThmgHNg7zIZWAXi3AsyIzA3n4xx7aNyjwC2VJldO2LMVDhFK+63xGqq6CsJH4rTAt6/M+N4GhZiDYPx9eUw==} dependencies: loose-envify: 1.4.0 - dev: true /section-matter/1.0.0: resolution: {integrity: sha512-vfD3pmTzGpufjScBh50YHKzEu2lxBWhVEHsNGoEXmCmn2hKGfeNLYMzCJpe8cD7gqX7TJluOVpBkAequ6dgMmA==} @@ -6325,7 +6350,6 @@ packages: /sourcemap-codec/1.4.8: resolution: {integrity: sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==} - dev: true /spdx-correct/3.1.1: resolution: {integrity: sha512-cOYcUWwhCuHCXi49RhFRCyJEK3iPj1Ziz9DpViV3tbZOwXD49QzIN3MpOLJNxh2qwq2lJJZaKMVw9qNi4jTC0w==} @@ -6927,7 +6951,6 @@ packages: '@vue/runtime-dom': 3.2.37 '@vue/server-renderer': 3.2.37_vue@3.2.37 '@vue/shared': 3.2.37 - dev: true /w3c-hr-time/1.0.2: resolution: {integrity: sha512-z8P5DvDNjKDoFIHK7q8r8lackT6l+jo/Ye3HOle7l9nICP9lf1Ci25fy9vHd0JOWewkIFzXIEig3TdKT7JQ5fQ==}