mirror of
https://gitee.com/vant-contrib/vant.git
synced 2025-04-06 03:57:59 +08:00
fix(Sticky): resize or orientationchange wrapper no reset width and height (#11753)
* fix(Swipe): props changed but component didn't * fix(Swipe): target watch windowWidth * Update packages/vant/src/swipe/Swipe.tsx * fix(Sticky): resize or orientationchange wrapper no reset width and height * fix(Sticky): resize or orientationchange wrapper no reset width and height * fix(Sticky): resize or orientationchange wrapper no reset width and height * fix(Sticky): resize or orientationchange wrapper no reset width and height --------- Co-authored-by: neverland <jait.chen@foxmail.com>
This commit is contained in:
parent
5338367ea3
commit
68d1ade239
@ -7,6 +7,7 @@ import {
|
|||||||
type PropType,
|
type PropType,
|
||||||
type CSSProperties,
|
type CSSProperties,
|
||||||
type ExtractPropTypes,
|
type ExtractPropTypes,
|
||||||
|
nextTick,
|
||||||
} from 'vue';
|
} from 'vue';
|
||||||
|
|
||||||
// Utils
|
// Utils
|
||||||
@ -20,6 +21,8 @@ import {
|
|||||||
makeStringProp,
|
makeStringProp,
|
||||||
makeNumericProp,
|
makeNumericProp,
|
||||||
createNamespace,
|
createNamespace,
|
||||||
|
windowWidth,
|
||||||
|
windowHeight,
|
||||||
} from '../utils';
|
} from '../utils';
|
||||||
|
|
||||||
// Composables
|
// Composables
|
||||||
@ -56,12 +59,16 @@ export default defineComponent({
|
|||||||
height: 0, // root height
|
height: 0, // root height
|
||||||
transform: 0,
|
transform: 0,
|
||||||
});
|
});
|
||||||
|
const isReset = ref(false);
|
||||||
|
|
||||||
const offset = computed(() =>
|
const offset = computed(() =>
|
||||||
unitToPx(props.position === 'top' ? props.offsetTop : props.offsetBottom)
|
unitToPx(props.position === 'top' ? props.offsetTop : props.offsetBottom)
|
||||||
);
|
);
|
||||||
|
|
||||||
const rootStyle = computed<CSSProperties | undefined>(() => {
|
const rootStyle = computed<CSSProperties | undefined>(() => {
|
||||||
|
if (isReset.value) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
const { fixed, height, width } = state;
|
const { fixed, height, width } = state;
|
||||||
if (fixed) {
|
if (fixed) {
|
||||||
return {
|
return {
|
||||||
@ -72,7 +79,7 @@ export default defineComponent({
|
|||||||
});
|
});
|
||||||
|
|
||||||
const stickyStyle = computed<CSSProperties | undefined>(() => {
|
const stickyStyle = computed<CSSProperties | undefined>(() => {
|
||||||
if (!state.fixed) {
|
if (!state.fixed || isReset.value) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -146,9 +153,25 @@ export default defineComponent({
|
|||||||
});
|
});
|
||||||
useVisibilityChange(root, onScroll);
|
useVisibilityChange(root, onScroll);
|
||||||
|
|
||||||
|
watch([windowWidth, windowHeight], () => {
|
||||||
|
if (!root.value || isHidden(root) || !state.fixed) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
isReset.value = true;
|
||||||
|
nextTick(() => {
|
||||||
|
const rootRect = useRect(root);
|
||||||
|
state.width = rootRect.width;
|
||||||
|
state.height = rootRect.height;
|
||||||
|
isReset.value = false;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
return () => (
|
return () => (
|
||||||
<div ref={root} style={rootStyle.value}>
|
<div ref={root} style={rootStyle.value}>
|
||||||
<div class={bem({ fixed: state.fixed })} style={stickyStyle.value}>
|
<div
|
||||||
|
class={bem({ fixed: state.fixed && !isReset.value })}
|
||||||
|
style={stickyStyle.value}
|
||||||
|
>
|
||||||
{slots.default?.()}
|
{slots.default?.()}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -82,6 +82,34 @@ exports[`should sticky inside container when using container prop 2`] = `
|
|||||||
</div>
|
</div>
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
exports[`should sticky resize or orientationchange reset root height and width 1`] = `
|
||||||
|
<div style="width: 375px; height: 20px;">
|
||||||
|
<div class="van-sticky van-sticky--fixed"
|
||||||
|
style="width: 375px; height: 20px; top: 0px;"
|
||||||
|
>
|
||||||
|
<div class="content"
|
||||||
|
style="height: 20px;"
|
||||||
|
>
|
||||||
|
Content
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
|
|
||||||
|
exports[`should sticky resize or orientationchange reset root height and width 2`] = `
|
||||||
|
<div style="width: 677px; height: 20px;">
|
||||||
|
<div class="van-sticky van-sticky--fixed"
|
||||||
|
style="width: 677px; height: 20px; top: 0px;"
|
||||||
|
>
|
||||||
|
<div class="content"
|
||||||
|
style="height: 20px;"
|
||||||
|
>
|
||||||
|
Content
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
|
|
||||||
exports[`should sticky to bottom after scrolling 1`] = `
|
exports[`should sticky to bottom after scrolling 1`] = `
|
||||||
<div style="height: 10px;">
|
<div style="height: 10px;">
|
||||||
<div class="van-sticky van-sticky--fixed"
|
<div class="van-sticky van-sticky--fixed"
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import { nextTick, ref } from 'vue';
|
import { nextTick, ref } from 'vue';
|
||||||
import { VueWrapper } from '@vue/test-utils';
|
import { VueWrapper, flushPromises } from '@vue/test-utils';
|
||||||
import { mockScrollTop, trigger, mount } from '../../../test';
|
import { mockScrollTop, trigger, mount } from '../../../test';
|
||||||
import { Sticky } from '..';
|
import { Sticky } from '..';
|
||||||
import { ComponentInstance } from '../../utils';
|
import { ComponentInstance } from '../../utils';
|
||||||
@ -353,3 +353,41 @@ test('should emit change event when sticky status changed', async () => {
|
|||||||
|
|
||||||
restore();
|
restore();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('should sticky resize or orientationchange reset root height and width', async () => {
|
||||||
|
const wrapper = mount({
|
||||||
|
render() {
|
||||||
|
return (
|
||||||
|
<Sticky>
|
||||||
|
<div class="content" style="height:20px">
|
||||||
|
Content
|
||||||
|
</div>
|
||||||
|
</Sticky>
|
||||||
|
);
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
window.innerWidth = 375;
|
||||||
|
const mockStickyRect = jest
|
||||||
|
.spyOn(wrapper.element, 'getBoundingClientRect')
|
||||||
|
.mockReturnValue({
|
||||||
|
top: -100,
|
||||||
|
bottom: -90,
|
||||||
|
width: window.innerWidth,
|
||||||
|
height: 20,
|
||||||
|
} as DOMRect);
|
||||||
|
|
||||||
|
await mockScrollTop(100);
|
||||||
|
expect(wrapper.html()).toMatchSnapshot();
|
||||||
|
|
||||||
|
window.innerWidth = 677;
|
||||||
|
mockStickyRect.mockReturnValue({
|
||||||
|
width: window.innerWidth,
|
||||||
|
height: 20,
|
||||||
|
} as DOMRect);
|
||||||
|
await trigger(window, 'resize');
|
||||||
|
await flushPromises();
|
||||||
|
expect(wrapper.html()).toMatchSnapshot();
|
||||||
|
|
||||||
|
mockStickyRect.mockRestore();
|
||||||
|
});
|
||||||
|
Loading…
x
Reference in New Issue
Block a user