first commit
This commit is contained in:
193
uni_modules/tdesign-uniapp/components/swiper/swiper.vue
Normal file
193
uni_modules/tdesign-uniapp/components/swiper/swiper.vue
Normal file
@@ -0,0 +1,193 @@
|
||||
<template>
|
||||
<view
|
||||
:class="classPrefix + ' ' + tClass"
|
||||
:style="tools._style([customStyle])"
|
||||
>
|
||||
<swiper
|
||||
:class="classPrefix + '-host'"
|
||||
:autoplay="autoplay"
|
||||
:current="current"
|
||||
:interval="interval"
|
||||
:duration="duration"
|
||||
:circular="loop"
|
||||
:vertical="direction == 'vertical'"
|
||||
:easing-function="easingFunction"
|
||||
:previous-margin="tools.addUnit(previousMargin)"
|
||||
:next-margin="tools.addUnit(nextMargin)"
|
||||
:snap-to-edge="snapToEdge"
|
||||
:display-multiple-items="displayMultipleItems"
|
||||
:style="'height: ' + tools.addUnit(height)"
|
||||
@change="onChange"
|
||||
@animationfinish="onAnimationFinish"
|
||||
>
|
||||
<swiper-item
|
||||
v-for="(item, index) in list"
|
||||
:key="index"
|
||||
:class="
|
||||
tools.cls(classPrefix + '__item', [
|
||||
['preview', isPrev(navCurrent, index, list)],
|
||||
['next', isNext(navCurrent, index, list)]
|
||||
])
|
||||
"
|
||||
:data-index="index"
|
||||
:aria-hidden="navCurrent !== index"
|
||||
aria-role="image"
|
||||
:aria-label="tools.isObject(item) ? item.ariaLabel : ''"
|
||||
@click="onTap($event, { index })"
|
||||
>
|
||||
<t-image
|
||||
:t-class="getImageClass(prefix, navCurrent, index, list, tClassImage, tClassPrevImage, tClassNextImage)"
|
||||
:custom-style="'height: ' + tools.addUnit(height) || ''"
|
||||
:error="imageProps.error || 'default'"
|
||||
:lazy="imageProps.lazy || false"
|
||||
:loading="imageProps.loading || 'default'"
|
||||
:shape="imageProps.shape || 'square'"
|
||||
:src="tools.isObject(item) ? item.value : item"
|
||||
:mode="imageProps.mode || 'aspectFill'"
|
||||
:webp="imageProps.webp || false"
|
||||
:show-menu-by-longpress="imageProps.showMenuByLongpress || false"
|
||||
@load="onImageLoad($event, { custom: index || null })"
|
||||
/>
|
||||
</swiper-item>
|
||||
</swiper>
|
||||
<t-swiper-nav
|
||||
v-if="navigation"
|
||||
:t-class="tClassNav"
|
||||
:type="navigation.type || 'dots'"
|
||||
:current="navCurrent || 0"
|
||||
:total="list.length || 0"
|
||||
:direction="direction || 'horizontal'"
|
||||
:pagination-position="paginationPosition || 'bottom'"
|
||||
:min-show-num="navigation.minShowNum || 2"
|
||||
:show-controls="navigation.showControls || false"
|
||||
@nav-btn-change="onNavBtnChange"
|
||||
/>
|
||||
<slot name="navigation" />
|
||||
<slot name="nav" />
|
||||
</view>
|
||||
</template>
|
||||
<script>
|
||||
import TSwiperNav from '../swiper-nav/swiper-nav';
|
||||
import TImage from '../image/image';
|
||||
import { uniComponent } from '../common/src/index';
|
||||
import { prefix } from '../common/config';
|
||||
import props from './props';
|
||||
import tools from '../common/utils.wxs';
|
||||
import { isPrev, isNext, getImageClass } from './computed.js';
|
||||
import { ParentMixin, RELATION_MAP } from '../common/relation';
|
||||
|
||||
const name = `${prefix}-swiper`;
|
||||
|
||||
export default uniComponent({
|
||||
name,
|
||||
options: {
|
||||
multipleSlots: true,
|
||||
styleIsolation: 'shared',
|
||||
},
|
||||
externalClasses: [`${prefix}-class`, `${prefix}-class-nav`, `${prefix}-class-image`, `${prefix}-class-prev-image`, `${prefix}-class-next-image`],
|
||||
mixins: [ParentMixin(RELATION_MAP.SwiperNav)],
|
||||
components: {
|
||||
TSwiperNav,
|
||||
TImage,
|
||||
},
|
||||
props: {
|
||||
...props,
|
||||
},
|
||||
emits: [
|
||||
'click',
|
||||
'change',
|
||||
'animationfinish',
|
||||
'image-load',
|
||||
],
|
||||
data() {
|
||||
return {
|
||||
prefix,
|
||||
classPrefix: name,
|
||||
tools,
|
||||
navCurrent: 0,
|
||||
};
|
||||
},
|
||||
watch: {
|
||||
navCurrent(t) {
|
||||
this.updateNav(t);
|
||||
},
|
||||
},
|
||||
|
||||
mounted() {
|
||||
this.navCurrent = this.current;
|
||||
},
|
||||
|
||||
methods: {
|
||||
isPrev,
|
||||
isNext,
|
||||
getImageClass,
|
||||
|
||||
updateNav(currentValue) {
|
||||
if (this.navigation) return;
|
||||
const $nav = this.getRelationNodes('./swiper-nav')?.[0];
|
||||
if (!$nav) return;
|
||||
const { direction, paginationPosition, list } = this;
|
||||
|
||||
this.current = currentValue;
|
||||
this.total = list.length;
|
||||
this.direction = direction;
|
||||
this.paginationPosition = paginationPosition;
|
||||
},
|
||||
|
||||
onTap(e, dataset) {
|
||||
const { index } = dataset;
|
||||
this.$emit('click', { index });
|
||||
},
|
||||
|
||||
onChange(e) {
|
||||
const { current, source } = e.detail;
|
||||
|
||||
if (!source) return;
|
||||
|
||||
this.navCurrent = current;
|
||||
this.triggerSource = source;
|
||||
|
||||
this.$emit('change', { current, source });
|
||||
},
|
||||
|
||||
onAnimationFinish(e) {
|
||||
const { current, source } = e.detail;
|
||||
|
||||
this.$emit('animationfinish', { current, source: source || this.triggerSource });
|
||||
},
|
||||
|
||||
onNavBtnChange(e) {
|
||||
const { dir, source } = e;
|
||||
|
||||
this.doNavBtnChange(dir, source);
|
||||
},
|
||||
|
||||
doNavBtnChange(dir, source) {
|
||||
const { current, list, loop, navCurrent } = this;
|
||||
const count = list.length;
|
||||
let nextPos = dir === 'next' ? current + 1 : current - 1;
|
||||
|
||||
if (loop) {
|
||||
nextPos = dir === 'next' ? (current + 1) % count : (current - 1 + count) % count;
|
||||
} else {
|
||||
nextPos = nextPos < 0 || nextPos >= count ? current : nextPos;
|
||||
}
|
||||
|
||||
if (nextPos === navCurrent) return;
|
||||
|
||||
this.navCurrent = nextPos;
|
||||
this.triggerSource = source;
|
||||
|
||||
this.$emit('change', { current: nextPos, source });
|
||||
},
|
||||
|
||||
onImageLoad(e, dataset) {
|
||||
this.$emit('image-load', { index: dataset.custom });
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
</script>
|
||||
<style scoped>
|
||||
@import './swiper.css';
|
||||
</style>
|
||||
Reference in New Issue
Block a user