mirror of
https://gitee.com/vant-contrib/vant.git
synced 2025-04-06 03:57:59 +08:00
refactor(TabsContent): refactor with composition api
This commit is contained in:
parent
92aac941fc
commit
8ca7219acc
@ -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 (
|
|
||||||
<div class={bem('track')} style={this.style}>
|
|
||||||
{Content}
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
return Content;
|
|
||||||
},
|
|
||||||
},
|
|
||||||
|
|
||||||
render() {
|
|
||||||
return (
|
|
||||||
<div
|
|
||||||
class={bem('content', { animated: this.animated })}
|
|
||||||
{...this.listeners}
|
|
||||||
>
|
|
||||||
{this.genChildren()}
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
},
|
|
||||||
});
|
|
81
src/tabs/TabsContent.tsx
Normal file
81
src/tabs/TabsContent.tsx
Normal file
@ -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 (
|
||||||
|
<div class={bem('track')} style={style}>
|
||||||
|
{Content}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return Content;
|
||||||
|
};
|
||||||
|
|
||||||
|
return () => {
|
||||||
|
const listeners = props.swipeable
|
||||||
|
? {
|
||||||
|
onTouchstart: touch.start,
|
||||||
|
onTouchmove: touch.move,
|
||||||
|
onTouchend: onTouchEnd,
|
||||||
|
onTouchcancel: onTouchEnd,
|
||||||
|
}
|
||||||
|
: null;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
class={bem('content', { animated: props.animated })}
|
||||||
|
{...listeners}
|
||||||
|
>
|
||||||
|
{renderChildren()}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
},
|
||||||
|
});
|
@ -22,7 +22,7 @@ import { BindEventMixin } from '../mixins/bind-event';
|
|||||||
// Components
|
// Components
|
||||||
import Title from './Title';
|
import Title from './Title';
|
||||||
import Sticky from '../sticky';
|
import Sticky from '../sticky';
|
||||||
import Content from './Content';
|
import TabsContent from './TabsContent';
|
||||||
|
|
||||||
const [createComponent, bem] = createNamespace('tabs');
|
const [createComponent, bem] = createNamespace('tabs');
|
||||||
|
|
||||||
@ -92,7 +92,7 @@ export default createComponent({
|
|||||||
|
|
||||||
return {
|
return {
|
||||||
position: '',
|
position: '',
|
||||||
currentIndex: null,
|
currentIndex: -1,
|
||||||
lineStyle: {
|
lineStyle: {
|
||||||
backgroundColor: this.color,
|
backgroundColor: this.color,
|
||||||
},
|
},
|
||||||
@ -421,7 +421,7 @@ export default createComponent({
|
|||||||
) : (
|
) : (
|
||||||
Wrap
|
Wrap
|
||||||
)}
|
)}
|
||||||
<Content
|
<TabsContent
|
||||||
count={this.children.length}
|
count={this.children.length}
|
||||||
animated={animated}
|
animated={animated}
|
||||||
duration={this.duration}
|
duration={this.duration}
|
||||||
@ -430,7 +430,7 @@ export default createComponent({
|
|||||||
onChange={this.setCurrentIndex}
|
onChange={this.setCurrentIndex}
|
||||||
>
|
>
|
||||||
{this.$slots.default?.()}
|
{this.$slots.default?.()}
|
||||||
</Content>
|
</TabsContent>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
Loading…
x
Reference in New Issue
Block a user