diff --git a/src/swipe/index.js b/src/swipe/index.js index 46bb2e6bb..2f2d38306 100644 --- a/src/swipe/index.js +++ b/src/swipe/index.js @@ -367,6 +367,7 @@ export default createComponent({ useExpose({ prev, next, + state, resize, swipeTo, }); diff --git a/src/tab/index.js b/src/tab/index.js index a10a29152..c10d1bcbe 100644 --- a/src/tab/index.js +++ b/src/tab/index.js @@ -6,6 +6,9 @@ import { TABS_KEY } from '../tabs'; import { useParent } from '@vant/use'; import { routeProps } from '../composition/use-route'; +// Components +import SwipeItem from '../swipe-item'; + const [createComponent, bem] = createNamespace('tab'); export default createComponent({ @@ -20,7 +23,6 @@ export default createComponent({ }, setup(props, { slots }) { - const root = ref(); const inited = ref(false); const { parent, index } = useParent(TABS_KEY); @@ -62,28 +64,27 @@ export default createComponent({ return; } - const { animated, scrollspy, lazyRender } = parent.props; + const { animated, swipeable, scrollspy, lazyRender } = parent.props; const active = isActive(); const show = scrollspy || active; - const shouldRender = inited.value || scrollspy || !lazyRender; - const Content = shouldRender ? slots.default?.() : null; - - if (animated) { + if (animated || swipeable) { return ( -
-
{Content}
-
+
{slots.default?.()}
+ ); } + const shouldRender = inited.value || scrollspy || !lazyRender; + const Content = shouldRender ? slots.default?.() : null; + return ( -
+
{Content}
); diff --git a/src/tabs/TabsContent.tsx b/src/tabs/TabsContent.tsx index 086cca35b..66b9a633c 100644 --- a/src/tabs/TabsContent.tsx +++ b/src/tabs/TabsContent.tsx @@ -1,14 +1,16 @@ +import { ref, watch } from 'vue'; import { createNamespace } from '../utils'; -import { useTouch } from '../composition/use-touch'; +import Swipe from '../swipe'; const [createComponent, bem] = createNamespace('tabs'); -const MIN_SWIPE_DISTANCE = 50; export default createComponent({ props: { + inited: Boolean, duration: [Number, String], animated: Boolean, swipeable: Boolean, + lazyRender: Boolean, count: { type: Number, required: true, @@ -22,60 +24,52 @@ export default createComponent({ emits: ['change'], setup(props, { emit, slots }) { - const touch = useTouch(); + const swipeRef = ref(); - const onTouchEnd = () => { - const { deltaX, offsetX } = touch; - const { currentIndex } = props; - - /* istanbul ignore else */ - if (touch.isHorizontal() && offsetX.value >= MIN_SWIPE_DISTANCE) { - /* istanbul ignore else */ - if (deltaX.value > 0 && currentIndex !== 0) { - emit('change', currentIndex - 1); - } else if (deltaX.value < 0 && currentIndex !== props.count - 1) { - emit('change', currentIndex + 1); - } - } + const onChange = (index: number) => { + emit('change', index); }; const renderChildren = () => { const Content = slots.default?.(); - if (props.animated) { - const style = { - transform: `translate3d(${-1 * props.currentIndex * 100}%, 0, 0)`, - transitionDuration: `${props.duration}s`, - }; - + if (props.animated || props.swipeable) { return ( -
+ {Content} -
+ ); } return Content; }; - return () => { - const listeners = props.swipeable - ? { - onTouchstart: touch.start, - onTouchmove: touch.move, - onTouchend: onTouchEnd, - onTouchcancel: onTouchEnd, - } - : null; + watch( + () => props.currentIndex, + (index) => { + const swipe = swipeRef.value; + if (swipe && swipe.state.active !== index) { + swipe.swipeTo(index, { immediate: !props.inited }); + } + } + ); - return ( -
- {renderChildren()} -
- ); - }; + return () => ( +
+ {renderChildren()} +
+ ); }, }); diff --git a/src/tabs/index.js b/src/tabs/index.js index ff90b6933..32e0fb94a 100644 --- a/src/tabs/index.js +++ b/src/tabs/index.js @@ -91,7 +91,6 @@ export default createComponent({ emits: ['click', 'change', 'scroll', 'disabled', 'rendered', 'update:active'], setup(props, { emit, slots }) { - let inited; let tabHeight; let lockScroll; let stickyFixed; @@ -106,6 +105,7 @@ export default createComponent({ const { children, linkChildren } = useChildren(TABS_KEY); const state = reactive({ + inited: false, position: '', currentIndex: -1, lineStyle: { @@ -159,7 +159,7 @@ export default createComponent({ const init = () => { nextTick(() => { - inited = true; + state.inited = true; tabHeight = getVisibleHeight(wrapRef.value); scrollIntoView(true); }); @@ -167,7 +167,7 @@ export default createComponent({ // update nav bar style const setLine = () => { - const shouldAnimate = inited; + const shouldAnimate = state.inited; nextTick(() => { const titles = titleRefs.value; @@ -436,9 +436,11 @@ export default createComponent({ )}