uniapp 卡片式轮播

269 阅读1分钟

效果

image.png

代码

<template>
	<swiper
		:display-multiple-items="showNum"
		:circular="true"
		:autoplay="false"
		:interval="100"
		:duration="100"
		easing-function="linear"
		:style="{ width: '100%', height: cardHeigth + 'px' }"
		:next-margin="-props.spacing + 'rpx'"
		v-if="props.list.length >= showNum"
	>
		<swiper-item v-for="(card, index) in props.list" :key="index">
			<div class="card-item" :style="{ 'margin-right': `${props.spacing}rpx` }">
				<slot name="card" :data="card" :index="index"></slot>
			</div>
		</swiper-item>
	</swiper>
	<div class="card-box" :style="{ gap: spacing + 'rpx' }" v-else>
		<div v-for="(card, index) in props.list" :key="index">
			<div class="card-item">
				<slot name="card" :data="card" :index="index"></slot>
			</div>
		</div>
	</div>
</template>

<script setup>
	import {
		ref,
		onMounted,
		computed,
		watch,
		getCurrentInstance,
		nextTick,
	} from 'vue';
	import { onLoad } from '@dcloudio/uni-app';

	const { proxy } = getCurrentInstance();

	const props = defineProps({
		list: {
			type: Array,
			required: true,
		},
		spacing: {
			type: Number,
			default: 10,
		},
		showNum: {
			type: Number,
			required: true,
		},
	});
	let showNum = ref(0);
	watch(
		[() => props.list, () => props.showNum],
		async () => {
			showNum.value = props.showNum;
			await nextTick();
			await nextTick();
			getCardHeight();
		},
		{ immediate: true, deep: true }
	);

	let cardHeigth = ref(0);
	// 获取卡片高度
	async function getCardHeight() {
		await nextTick();
		const query = uni.createSelectorQuery().in(proxy);
		query
			.selectAll('.card-item')
			.boundingClientRect((rects) => {
				if (rects && rects.length > 0) {
					// 取第一个非0的高度,或者最大高度
					const heights = rects.map((r) => r.height).filter((h) => h > 0);
					cardHeigth.value = heights.length > 0 ? Math.max(...heights) : 200; // 给个兜底高度
				} else {
					cardHeigth.value = 200; // 兜底
				}
			})
			.exec();
	}
</script>

<style lang="scss" scoped>
	.card-box {
		display: flex;
		align-items: center;
	}
</style>

页面使用

<carouselCard :list="cardList" :showNum="3"> 
    <template #card="{ data: item, index }"></template>
</carouselCard>

import carouselCard from './carouselCard.vue';
	let cardList = ref([]);