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}
);
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({
)}