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?.()} - + ); },