mirror of
https://gitee.com/vant-contrib/vant.git
synced 2025-04-06 03:57:59 +08:00
types(Swipe): use tsx (#8148)
This commit is contained in:
parent
6a24e0d5ea
commit
d67b6e1184
@ -60,7 +60,7 @@
|
|||||||
"@vant/icons": "^1.5.2",
|
"@vant/icons": "^1.5.2",
|
||||||
"@vant/lazyload": "^1.0.2",
|
"@vant/lazyload": "^1.0.2",
|
||||||
"@vant/popperjs": "^1.0.2",
|
"@vant/popperjs": "^1.0.2",
|
||||||
"@vant/use": "^1.0.4"
|
"@vant/use": "^1.0.5"
|
||||||
},
|
},
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"vue": "^3.0.0"
|
"vue": "^3.0.0"
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import { computed, nextTick, onMounted, reactive } from 'vue';
|
import { computed, CSSProperties, nextTick, onMounted, reactive } from 'vue';
|
||||||
import { SWIPE_KEY } from '../swipe';
|
import { SWIPE_KEY, SwipeProvide } from '../swipe';
|
||||||
import { createNamespace } from '../utils';
|
import { createNamespace } from '../utils';
|
||||||
import { useParent } from '@vant/use';
|
import { useParent } from '@vant/use';
|
||||||
import { useExpose } from '../composables/use-expose';
|
import { useExpose } from '../composables/use-expose';
|
||||||
@ -8,17 +8,24 @@ const [createComponent, bem] = createNamespace('swipe-item');
|
|||||||
|
|
||||||
export default createComponent({
|
export default createComponent({
|
||||||
setup(props, { slots }) {
|
setup(props, { slots }) {
|
||||||
let rendered;
|
let rendered: boolean;
|
||||||
const state = reactive({
|
const state = reactive({
|
||||||
offset: 0,
|
offset: 0,
|
||||||
inited: false,
|
inited: false,
|
||||||
mounted: false,
|
mounted: false,
|
||||||
});
|
});
|
||||||
|
|
||||||
const { parent, index } = useParent(SWIPE_KEY);
|
const { parent, index } = useParent<SwipeProvide>(SWIPE_KEY);
|
||||||
|
|
||||||
|
if (!parent) {
|
||||||
|
if (process.env.NODE_ENV !== 'production') {
|
||||||
|
console.error('[Vant] SwipeItem must be a child component of Swipe.');
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
const style = computed(() => {
|
const style = computed(() => {
|
||||||
const style = {};
|
const style: CSSProperties = {};
|
||||||
const { vertical } = parent.props;
|
const { vertical } = parent.props;
|
||||||
|
|
||||||
if (parent.size.value) {
|
if (parent.size.value) {
|
||||||
@ -56,7 +63,7 @@ export default createComponent({
|
|||||||
return rendered;
|
return rendered;
|
||||||
});
|
});
|
||||||
|
|
||||||
const setOffset = (offset) => {
|
const setOffset = (offset: number) => {
|
||||||
state.offset = offset;
|
state.offset = offset;
|
||||||
};
|
};
|
||||||
|
|
@ -1,5 +1,6 @@
|
|||||||
import {
|
import {
|
||||||
ref,
|
ref,
|
||||||
|
Ref,
|
||||||
watch,
|
watch,
|
||||||
reactive,
|
reactive,
|
||||||
computed,
|
computed,
|
||||||
@ -7,6 +8,8 @@ import {
|
|||||||
onActivated,
|
onActivated,
|
||||||
onDeactivated,
|
onDeactivated,
|
||||||
onBeforeUnmount,
|
onBeforeUnmount,
|
||||||
|
CSSProperties,
|
||||||
|
ComponentPublicInstance,
|
||||||
} from 'vue';
|
} from 'vue';
|
||||||
|
|
||||||
// Utils
|
// Utils
|
||||||
@ -27,11 +30,25 @@ const [createComponent, bem] = createNamespace('swipe');
|
|||||||
|
|
||||||
export const SWIPE_KEY = 'vanSwipe';
|
export const SWIPE_KEY = 'vanSwipe';
|
||||||
|
|
||||||
|
export type SwipeToOptions = {
|
||||||
|
immediate?: boolean;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type SwipeProvide = {
|
||||||
|
props: {
|
||||||
|
loop: boolean;
|
||||||
|
vertical?: boolean;
|
||||||
|
lazyRender?: boolean;
|
||||||
|
};
|
||||||
|
size: Ref<number>;
|
||||||
|
count: Ref<number>;
|
||||||
|
activeIndicator: Ref<number>;
|
||||||
|
};
|
||||||
|
|
||||||
export default createComponent({
|
export default createComponent({
|
||||||
props: {
|
props: {
|
||||||
width: [Number, String],
|
width: [Number, String],
|
||||||
height: [Number, String],
|
height: [Number, String],
|
||||||
autoplay: [Number, String],
|
|
||||||
vertical: Boolean,
|
vertical: Boolean,
|
||||||
lazyRender: Boolean,
|
lazyRender: Boolean,
|
||||||
indicatorColor: String,
|
indicatorColor: String,
|
||||||
@ -39,6 +56,10 @@ export default createComponent({
|
|||||||
type: Boolean,
|
type: Boolean,
|
||||||
default: true,
|
default: true,
|
||||||
},
|
},
|
||||||
|
autoplay: {
|
||||||
|
type: [Number, String],
|
||||||
|
default: 0,
|
||||||
|
},
|
||||||
duration: {
|
duration: {
|
||||||
type: [Number, String],
|
type: [Number, String],
|
||||||
default: 500,
|
default: 500,
|
||||||
@ -64,9 +85,9 @@ export default createComponent({
|
|||||||
emits: ['change'],
|
emits: ['change'],
|
||||||
|
|
||||||
setup(props, { emit, slots }) {
|
setup(props, { emit, slots }) {
|
||||||
const root = ref();
|
const root = ref<HTMLElement>();
|
||||||
const state = reactive({
|
const state = reactive({
|
||||||
rect: null,
|
rect: null as DOMRect | null,
|
||||||
width: 0,
|
width: 0,
|
||||||
height: 0,
|
height: 0,
|
||||||
offset: 0,
|
offset: 0,
|
||||||
@ -76,7 +97,10 @@ export default createComponent({
|
|||||||
|
|
||||||
const touch = useTouch();
|
const touch = useTouch();
|
||||||
const windowSize = useWindowSize();
|
const windowSize = useWindowSize();
|
||||||
const { children, linkChildren } = useChildren(SWIPE_KEY);
|
const { children, linkChildren } = useChildren<
|
||||||
|
// eslint-disable-next-line
|
||||||
|
ComponentPublicInstance<{}, any>
|
||||||
|
>(SWIPE_KEY);
|
||||||
|
|
||||||
const count = computed(() => children.length);
|
const count = computed(() => children.length);
|
||||||
|
|
||||||
@ -86,11 +110,13 @@ export default createComponent({
|
|||||||
props.vertical ? touch.deltaY.value : touch.deltaX.value
|
props.vertical ? touch.deltaY.value : touch.deltaX.value
|
||||||
);
|
);
|
||||||
|
|
||||||
const minOffset = computed(
|
const minOffset = computed(() => {
|
||||||
() =>
|
if (state.rect) {
|
||||||
(props.vertical ? state.rect.height : state.rect.width) -
|
const base = props.vertical ? state.rect.height : state.rect.width;
|
||||||
size.value * count.value
|
return base - size.value * count.value;
|
||||||
);
|
}
|
||||||
|
return 0;
|
||||||
|
});
|
||||||
|
|
||||||
const maxCount = computed(() =>
|
const maxCount = computed(() =>
|
||||||
Math.ceil(Math.abs(minOffset.value) / size.value)
|
Math.ceil(Math.abs(minOffset.value) / size.value)
|
||||||
@ -110,7 +136,7 @@ export default createComponent({
|
|||||||
const trackStyle = computed(() => {
|
const trackStyle = computed(() => {
|
||||||
const mainAxis = props.vertical ? 'height' : 'width';
|
const mainAxis = props.vertical ? 'height' : 'width';
|
||||||
const crossAxis = props.vertical ? 'width' : 'height';
|
const crossAxis = props.vertical ? 'width' : 'height';
|
||||||
const style = {
|
const style: CSSProperties = {
|
||||||
transitionDuration: `${state.swiping ? 0 : props.duration}ms`,
|
transitionDuration: `${state.swiping ? 0 : props.duration}ms`,
|
||||||
transform: `translate${props.vertical ? 'Y' : 'X'}(${state.offset}px)`,
|
transform: `translate${props.vertical ? 'Y' : 'X'}(${state.offset}px)`,
|
||||||
};
|
};
|
||||||
@ -123,7 +149,7 @@ export default createComponent({
|
|||||||
return style;
|
return style;
|
||||||
});
|
});
|
||||||
|
|
||||||
const getTargetActive = (pace) => {
|
const getTargetActive = (pace: number) => {
|
||||||
const { active } = state;
|
const { active } = state;
|
||||||
|
|
||||||
if (pace) {
|
if (pace) {
|
||||||
@ -135,7 +161,7 @@ export default createComponent({
|
|||||||
return active;
|
return active;
|
||||||
};
|
};
|
||||||
|
|
||||||
const getTargetOffset = (targetActive, offset = 0) => {
|
const getTargetOffset = (targetActive: number, offset = 0) => {
|
||||||
let currentPosition = targetActive * size.value;
|
let currentPosition = targetActive * size.value;
|
||||||
if (!props.loop) {
|
if (!props.loop) {
|
||||||
currentPosition = Math.min(currentPosition, -minOffset.value);
|
currentPosition = Math.min(currentPosition, -minOffset.value);
|
||||||
@ -149,7 +175,15 @@ export default createComponent({
|
|||||||
return targetOffset;
|
return targetOffset;
|
||||||
};
|
};
|
||||||
|
|
||||||
const move = ({ pace = 0, offset = 0, emitChange }) => {
|
const move = ({
|
||||||
|
pace = 0,
|
||||||
|
offset = 0,
|
||||||
|
emitChange,
|
||||||
|
}: {
|
||||||
|
pace?: number;
|
||||||
|
offset?: number;
|
||||||
|
emitChange?: boolean;
|
||||||
|
}) => {
|
||||||
if (count.value <= 1) {
|
if (count.value <= 1) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -218,7 +252,7 @@ export default createComponent({
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
let autoplayTimer;
|
let autoplayTimer: NodeJS.Timeout;
|
||||||
|
|
||||||
const stopAutoplay = () => {
|
const stopAutoplay = () => {
|
||||||
clearTimeout(autoplayTimer);
|
clearTimeout(autoplayTimer);
|
||||||
@ -230,7 +264,7 @@ export default createComponent({
|
|||||||
autoplayTimer = setTimeout(() => {
|
autoplayTimer = setTimeout(() => {
|
||||||
next();
|
next();
|
||||||
autoplay();
|
autoplay();
|
||||||
}, props.autoplay);
|
}, +props.autoplay);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -249,8 +283,8 @@ export default createComponent({
|
|||||||
state.rect = rect;
|
state.rect = rect;
|
||||||
state.swiping = true;
|
state.swiping = true;
|
||||||
state.active = active;
|
state.active = active;
|
||||||
state.width = +props.width || rect.width;
|
state.width = +(props.width ?? rect.width);
|
||||||
state.height = +props.height || rect.height;
|
state.height = +(props.height ?? rect.height);
|
||||||
state.offset = getTargetOffset(active);
|
state.offset = getTargetOffset(active);
|
||||||
children.forEach((swipe) => {
|
children.forEach((swipe) => {
|
||||||
swipe.setOffset(0);
|
swipe.setOffset(0);
|
||||||
@ -263,9 +297,9 @@ export default createComponent({
|
|||||||
initialize(state.active);
|
initialize(state.active);
|
||||||
};
|
};
|
||||||
|
|
||||||
let touchStartTime;
|
let touchStartTime: number;
|
||||||
|
|
||||||
const onTouchStart = (event) => {
|
const onTouchStart = (event: TouchEvent) => {
|
||||||
if (!props.touchable) return;
|
if (!props.touchable) return;
|
||||||
|
|
||||||
touch.start(event);
|
touch.start(event);
|
||||||
@ -275,7 +309,7 @@ export default createComponent({
|
|||||||
correctPosition();
|
correctPosition();
|
||||||
};
|
};
|
||||||
|
|
||||||
const onTouchMove = (event) => {
|
const onTouchMove = (event: TouchEvent) => {
|
||||||
if (props.touchable && state.swiping) {
|
if (props.touchable && state.swiping) {
|
||||||
touch.move(event);
|
touch.move(event);
|
||||||
|
|
||||||
@ -323,7 +357,7 @@ export default createComponent({
|
|||||||
autoplay();
|
autoplay();
|
||||||
};
|
};
|
||||||
|
|
||||||
const swipeTo = (index, options = {}) => {
|
const swipeTo = (index: number, options: SwipeToOptions = {}) => {
|
||||||
correctPosition();
|
correctPosition();
|
||||||
touch.reset();
|
touch.reset();
|
||||||
|
|
||||||
@ -350,9 +384,11 @@ export default createComponent({
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
const renderDot = (_, index) => {
|
const renderDot = (_: number, index: number) => {
|
||||||
const active = index === activeIndicator.value;
|
const active = index === activeIndicator.value;
|
||||||
const style = active ? { backgroundColor: props.indicatorColor } : null;
|
const style: CSSProperties = {
|
||||||
|
backgroundColor: active ? props.indicatorColor : undefined,
|
||||||
|
};
|
||||||
return <i style={style} class={bem('indicator', { active })} />;
|
return <i style={style} class={bem('indicator', { active })} />;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -379,7 +415,12 @@ export default createComponent({
|
|||||||
|
|
||||||
linkChildren({ size, props, count, activeIndicator });
|
linkChildren({ size, props, count, activeIndicator });
|
||||||
|
|
||||||
watch(() => props.initialSwipe, initialize);
|
watch(
|
||||||
|
() => props.initialSwipe,
|
||||||
|
(value) => {
|
||||||
|
initialize(+value);
|
||||||
|
}
|
||||||
|
);
|
||||||
watch(
|
watch(
|
||||||
() => children.length,
|
() => children.length,
|
||||||
() => {
|
() => {
|
@ -1981,10 +1981,10 @@
|
|||||||
resolved "https://registry.yarnpkg.com/@vant/touch-emulator/-/touch-emulator-1.2.0.tgz#486300b23e57db9ce9231a04e0a0c621c68692d8"
|
resolved "https://registry.yarnpkg.com/@vant/touch-emulator/-/touch-emulator-1.2.0.tgz#486300b23e57db9ce9231a04e0a0c621c68692d8"
|
||||||
integrity sha512-sJ97zU85zOq51qoi7+CpBEcOyH3CitjP1KC7/GQwqaurUJni+EP7/F9n0HMnAh8GXMjgtgDBNJ5z48x+coNKYQ==
|
integrity sha512-sJ97zU85zOq51qoi7+CpBEcOyH3CitjP1KC7/GQwqaurUJni+EP7/F9n0HMnAh8GXMjgtgDBNJ5z48x+coNKYQ==
|
||||||
|
|
||||||
"@vant/use@^1.0.4":
|
"@vant/use@^1.0.5":
|
||||||
version "1.0.4"
|
version "1.0.5"
|
||||||
resolved "https://registry.npm.taobao.org/@vant/use/download/@vant/use-1.0.4.tgz#67f827a40e74f3c318d5f05c31751610d8056184"
|
resolved "https://registry.npm.taobao.org/@vant/use/download/@vant/use-1.0.5.tgz#44bee952ebccf9396414a51c4d4b458434a9de23"
|
||||||
integrity sha1-Z/gnpA5088MY1fBcMXUWENgFYYQ=
|
integrity sha1-RL7pUuvM+TlkFKUcTUtFhDSp3iM=
|
||||||
dependencies:
|
dependencies:
|
||||||
"@babel/runtime" "7.x"
|
"@babel/runtime" "7.x"
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user