本文主要是介绍二次封装el-carousel,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
我们创建了一个名为MyCarousel
的组件,它接受el-carousel
的一些常用属性作为props,并默认提供了一些值。我们还通过setup
函数返回了所有props,以便它们可以在模板中被使用。
1.MyCarousel.vue
组件
<!-- 轮播图片 -->
<template><div class="carousel" :class="[{ twoBox: isTwo }, { elseBox: !isTwo }]"><el-carouselloopindicator-position="outside"class="carouselBox":arrow="carouselListData.length === 1 ? 'never' : 'hover'"@change="changeItem"ref="carouse"><el-carousel-item:width="props.width + 'px'"v-for="(item, index) in carouselListData":key="index"@click="goHomepage(item)"><img:src="item.imageUrl":style="{width: props.widthImage + '%',height: props.heightImage + '%',cursor: item.posterLink || props.activeTab ? 'pointer' : ''}"alt="轮播图图片"/></el-carousel-item></el-carousel></div>
</template><!-- 轮播图 -->
<script setup lang="ts" name="CustomCarousel">import { QueryPosterInfoListOutput } from '@/api/home/types';import _ from 'lodash';const isTwo = ref(false); // 判断是不是两条数据const carouse = ref();const emit = defineEmits({ clickGoPage: null, changeItem: null });const props = defineProps({// 轮播图宽度width: {type: Number,default: 0},// 轮播图高度height: {type: String,default: '400'},type: {type: String,default: 'card'},// 相邻两张图片切换的间隔时间interval: {type: Number,default: 4000},//图片宽widthImage: {type: Number,default: 100},//图片高heightImage: {type: Number,default: 100},// 轮播图路径数组carouselList: {type: Array<QueryPosterInfoListOutput>,default: () => []},// 点击不同的tab切换对应的轮播图activeTab: {type: Number,default: 0}});const activeIndex = ref(0);const carouselListData = ref<QueryPosterInfoListOutput[]>([]);watch(() => props.carouselList,(newVal) => {fu(newVal);});// 针对阶梯套餐的特殊处理watch(() => props.activeTab,(newVal) => {// console.log(activeIndex.value, 'newVal======', newVal);// 因为是element-ui组件的一个bug两张图片的需要单独特殊处理,目的是避免切换tab的时候,轮播图切换到上一张,轮播方向错误if (isTwo.value) {// 上一个的tab值const prev = carouselListData.value[activeIndex.value];// 如果上一个的值和当前点击的的一样,不做改变if (prev.id === newVal) {return;} else {let index = _.findIndex(carouselListData.value, (item, i) => {return item.id === newVal && i > activeIndex.value;});// 如果是最后一张图的时候需要回来到第一张图片if (index === -1) {index = 0;}// 重新设置选中的默认值carouse.value.setActiveItem(index);}} else {const index = _.findIndex(carouselListData.value, (item) => {return item.id === newVal;});carouse.value.setActiveItem(index);}});// 点击进入链接,发起方法调用const goHomepage = (value: QueryPosterInfoListOutput) => {emit('clickGoPage', value);if (value.posterLink) {window.open(value.posterLink, '_blank');}};const changeItem = (val: any) => {const value = carouselListData.value[val];activeIndex.value = val;// console.log('index-----------', val);emit('changeItem', value);};onMounted(() => {fu(props.carouselList);});/*** 重新处理,el-carousel-item数量为2时,组件循环方向一左一右的问题** 思路:如果为2时,复制一次,使其成为长度length为4的数组,然后将Carousel组件的indicators(下标显示器)多复制的给隐藏(原本长度为2,现在为4,就隐藏第3个和第4个)* @param data*/const fu = (data: QueryPosterInfoListOutput[]) => {if (data) {if (data.length === 2) {isTwo.value = true;//将2条数据复制一份为4条数据carouselListData.value = data.concat(data);} else {isTwo.value = false;//其他时候正常赋值carouselListData.value = data;}}};
</script><style scoped lang="scss">.twoBox {width: 100%;height: 100%;.carouselBox {width: 100%;//将复制出来的数据的下标隐藏:deep(.el-carousel__indicators) {& > li:nth-child(3),& > li:nth-child(4) {display: none;}}}}.elseBox {width: 100%;height: 100%;.carouselBox {width: 100%;}}.carousel {:deep {.el-carousel__indicators--outside .is-active button {background-color: var(--el-color-primary);width: 20px;height: 3px;}.el-carousel__indicators--outside button {// background-color: #e1e1e1;width: 9px;}.el-carousel__arrow {background-color: #8b8b8b;}.el-carousel__arrow--left {left: 16.1%;opacity: 40%;}.el-carousel__arrow--right {right: 16.1%;opacity: 40%;}.el-carousel__arrow--right:active,.el-carousel__arrow--left:active {opacity: 80%;}.el-carousel__container {margin-bottom: 7px;position: relative;width: 100%;height: auto;// aspect-ratio: 1440/600img {position: absolute;top: 0;left: 0;width: 100%;height: 100%;}}}}
</style>
2.使用:
基础用法:
<template><my-carouselv-if="bannerImgsList.length":height="'582'":carouselList="bannerImgsList"@clickGoPage="clickGoPage"/>
</template><script setup lang="ts">
import { QueryPosterInfoListOutput } from '@/api/home/types';
const bannerImgsList = ref<QueryPosterInfoListOutput[]>([]);const clickGoPage = (value: IcarouselList) => {console.log('=====', value);// router.push("/home");
};
</script>
需要结合tab来动态联动的用法:
<template><div class="step-package margin-top40" v-if="ladderPackageList && ladderPackageList.length"><!-- 切换的tab --><div class="flex-center margin-top20"><divv-for="item in ladderPackageList":key="item.id"class="step-package-tabs":class="{ 'step-package-tabs-active': activeTab == item.id }"><el-button class="img-button" @click="clickSelectTab(item)">{{ item.posterName }}</el-button></div></div><!-- 轮播图 --><div class="margin-top30 step-carousel"><my-carousel:height="'422'":width="1000":carouselList="ladderPackageList"@changeItem="changeItem"@clickGoPage="clickGoPage":activeTab="activeTab"/></div></div>
</template>
<script setup lang="ts">import { ref } from 'vue'import { useRouter } from 'vue-router';import { queryFrontLadderPackageFront } from '@/api/ladderPackage';import { QueryLadderPackageOutput } from '@/api/ladderPackage/types';const router = useRouter();const ladderPackageList = ref();const activeTab = ref<number>(0);onMounted(() => {getData ();});const getData = async () => {const result = await 接口;if (result && result.length) {ladderPackageList.value = result;activeTab.value = result[0].id;}};const clickSelectTab = (item: QueryLadderPackageOutput) => {activeTab.value = item.id;};const clickGoPage = (val: any) => {console.log('val', val);};const changeItem = (val: any) => {activeTab.value = val.id;};
</script>
<style lang="scss" scoped>.step-package {height: 100%;width: 100%;.step-package-content {width: 70%;margin: 0 auto;}.step-carousel {:deep {.el-carousel__container {aspect-ratio: 1440/420;}}}.step-package-tabs {margin: 0 3em;cursor: pointer;border-radius: 16px;.img-button {border: 0;border-radius: 16px;}}.step-package-tabs-active {margin: 0 3em;background-color: var(--el-color-primary);color: #fff;.img-button {background-color: var(--el-color-primary);border-color: var(--el-color-primary);color: #fff;}}}
</style>
3.效果图:
最后,同个点击上面的tab切换到不同的图片上,同理,切换不同的轮播图,上面的tab也会跟着动,双向的联动。
这篇关于二次封装el-carousel的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!