diff --git a/src/tabs/Content.js b/src/tabs/Content.js
deleted file mode 100644
index a6b9eceb4..000000000
--- a/src/tabs/Content.js
+++ /dev/null
@@ -1,82 +0,0 @@
-import { createNamespace } from '../utils';
-import { TouchMixin } from '../mixins/touch';
-
-const [createComponent, bem] = createNamespace('tabs');
-const MIN_SWIPE_DISTANCE = 50;
-
-export default createComponent({
- mixins: [TouchMixin],
-
- props: {
- count: Number,
- duration: [Number, String],
- animated: Boolean,
- swipeable: Boolean,
- currentIndex: Number,
- },
-
- emits: ['change'],
-
- computed: {
- style() {
- if (this.animated) {
- return {
- transform: `translate3d(${-1 * this.currentIndex * 100}%, 0, 0)`,
- transitionDuration: `${this.duration}s`,
- };
- }
- },
-
- listeners() {
- if (this.swipeable) {
- return {
- onTouchstart: this.touchStart,
- onTouchmove: this.touchMove,
- onTouchend: this.onTouchEnd,
- onTouchcancel: this.onTouchEnd,
- };
- }
- },
- },
-
- methods: {
- // watch swipe touch end
- onTouchEnd() {
- const { direction, deltaX, currentIndex } = this;
-
- /* istanbul ignore else */
- if (direction === 'horizontal' && this.offsetX >= MIN_SWIPE_DISTANCE) {
- /* istanbul ignore else */
- if (deltaX > 0 && currentIndex !== 0) {
- this.$emit('change', currentIndex - 1);
- } else if (deltaX < 0 && currentIndex !== this.count - 1) {
- this.$emit('change', currentIndex + 1);
- }
- }
- },
-
- genChildren() {
- const Content = this.$slots.default?.();
- if (this.animated) {
- return (
-
- {Content}
-
- );
- }
-
- return Content;
- },
- },
-
- render() {
- return (
-
- {this.genChildren()}
-
- );
- },
-});
diff --git a/src/tabs/TabsContent.tsx b/src/tabs/TabsContent.tsx
new file mode 100644
index 000000000..086cca35b
--- /dev/null
+++ b/src/tabs/TabsContent.tsx
@@ -0,0 +1,81 @@
+import { createNamespace } from '../utils';
+import { useTouch } from '../composition/use-touch';
+
+const [createComponent, bem] = createNamespace('tabs');
+const MIN_SWIPE_DISTANCE = 50;
+
+export default createComponent({
+ props: {
+ duration: [Number, String],
+ animated: Boolean,
+ swipeable: Boolean,
+ count: {
+ type: Number,
+ required: true,
+ },
+ currentIndex: {
+ type: Number,
+ required: true,
+ },
+ },
+
+ emits: ['change'],
+
+ setup(props, { emit, slots }) {
+ const touch = useTouch();
+
+ 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 renderChildren = () => {
+ const Content = slots.default?.();
+
+ if (props.animated) {
+ const style = {
+ transform: `translate3d(${-1 * props.currentIndex * 100}%, 0, 0)`,
+ transitionDuration: `${props.duration}s`,
+ };
+
+ return (
+
+ {Content}
+
+ );
+ }
+
+ return Content;
+ };
+
+ return () => {
+ const listeners = props.swipeable
+ ? {
+ onTouchstart: touch.start,
+ onTouchmove: touch.move,
+ onTouchend: onTouchEnd,
+ onTouchcancel: onTouchEnd,
+ }
+ : null;
+
+ return (
+
+ {renderChildren()}
+
+ );
+ };
+ },
+});
diff --git a/src/tabs/index.js b/src/tabs/index.js
index b396a726b..ffcc9b7a2 100644
--- a/src/tabs/index.js
+++ b/src/tabs/index.js
@@ -22,7 +22,7 @@ import { BindEventMixin } from '../mixins/bind-event';
// Components
import Title from './Title';
import Sticky from '../sticky';
-import Content from './Content';
+import TabsContent from './TabsContent';
const [createComponent, bem] = createNamespace('tabs');
@@ -92,7 +92,7 @@ export default createComponent({
return {
position: '',
- currentIndex: null,
+ currentIndex: -1,
lineStyle: {
backgroundColor: this.color,
},
@@ -421,7 +421,7 @@ export default createComponent({
) : (
Wrap
)}
-
{this.$slots.default?.()}
-
+
);
},