模仿element-ui Carousel组件 用vue写一个卡片化Carousel 已达到类似效果
时间: 2024-05-19 21:11:06 浏览: 164
以下是一个基于Vue实现的卡片化Carousel组件示例:
```html
<template>
<div class="card-carousel">
<div class="card-carousel-wrapper">
<div class="card-carousel-content" :style="'transform: translateX(' + translateX + 'px)'">
<div v-for="(item, index) in list" :key="index" class="card-carousel-item">
<div class="card-carousel-item-inner">
<div class="card-carousel-item-image">
<img :src="item.image" alt="">
</div>
<div class="card-carousel-item-title">{{ item.title }}</div>
<div class="card-carousel-item-desc">{{ item.desc }}</div>
</div>
</div>
</div>
</div>
<div class="card-carousel-controls">
<span class="card-carousel-control" @click="prev"><i class="iconfont icon-arrow-left"></i></span>
<span class="card-carousel-control" @click="next"><i class="iconfont icon-arrow-right"></i></span>
</div>
</div>
</template>
<script>
export default {
name: 'CardCarousel',
props: {
list: {
type: Array,
default: () => []
},
visibleCount: {
type: Number,
default: 3
},
spacing: {
type: Number,
default: 20
}
},
data() {
return {
currentIndex: 0,
translateX: 0
}
},
computed: {
itemWidth() {
const wrapperWidth = this.$el.querySelector('.card-carousel-wrapper').offsetWidth
return (wrapperWidth - (this.visibleCount - 1) * this.spacing) / this.visibleCount
},
totalWidth() {
return this.list.length * (this.itemWidth + this.spacing)
}
},
methods: {
prev() {
if (this.currentIndex === 0) {
return
}
this.currentIndex--
this.translateX = -this.currentIndex * (this.itemWidth + this.spacing)
},
next() {
if (this.currentIndex === this.list.length - this.visibleCount) {
return
}
this.currentIndex++
this.translateX = -this.currentIndex * (this.itemWidth + this.spacing)
}
}
}
</script>
<style scoped>
.card-carousel {
position: relative;
width: 100%;
overflow: hidden;
}
.card-carousel-wrapper {
position: relative;
overflow: hidden;
}
.card-carousel-content {
display: flex;
transition: transform .3s ease;
}
.card-carousel-item {
width: 270px;
height: 350px;
margin-right: 20px;
background-color: #fff;
border: 1px solid #eaeaea;
border-radius: 8px;
box-shadow: 0 2px 6px rgba(0, 0, 0, .1);
}
.card-carousel-item:last-child {
margin-right: 0;
}
.card-carousel-item-image {
width: 100%;
height: 200px;
overflow: hidden;
border-radius: 8px 8px 0 0;
}
.card-carousel-item-image img {
display: block;
width: 100%;
height: 100%;
object-fit: cover;
}
.card-carousel-item-title {
margin: 20px;
font-size: 16px;
font-weight: bold;
}
.card-carousel-item-desc {
margin: 0 20px 20px;
font-size: 14px;
color: #666;
}
.card-carousel-controls {
position: absolute;
top: 50%;
transform: translateY(-50%);
display: flex;
justify-content: space-between;
width: 60px;
height: 60px;
background-color: rgba(255, 255, 255, .5);
border-radius: 50%;
cursor: pointer;
z-index: 1;
}
.card-carousel-control {
display: flex;
justify-content: center;
align-items: center;
font-size: 24px;
color: #999;
transition: color .3s ease;
}
.card-carousel-control:hover {
color: #333;
}
</style>
```
使用方法:
```html
<template>
<card-carousel :list="list" :visible-count="3" :spacing="20"></card-carousel>
</template>
<script>
import CardCarousel from './CardCarousel'
export default {
name: 'App',
components: {
CardCarousel
},
data() {
return {
list: [
{
image: 'https://picsum.photos/id/1012/400/300',
title: 'Lorem ipsum dolor sit amet',
desc: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed ut felis vel sapien consequat tincidunt.'
},
{
image: 'https://picsum.photos/id/1015/400/300',
title: 'Nulla nec tellus a justo',
desc: 'Nulla nec tellus a justo sagittis iaculis eget vitae enim. In hac habitasse platea dictumst.'
},
{
image: 'https://picsum.photos/id/1020/400/300',
title: 'Vivamus vel sapien ut libero',
desc: 'Vivamus vel sapien ut libero luctus bibendum. Proin fringilla id urna in fermentum. '
},
{
image: 'https://picsum.photos/id/1038/400/300',
title: 'Quisque in mauris mauris',
desc: 'Quisque in mauris mauris, efficitur dapibus leo. Praesent eget tellus massa.'
},
{
image: 'https://picsum.photos/id/1042/400/300',
title: 'Donec ut ligula in nulla',
desc: 'Donec ut ligula in nulla molestie interdum eu ac purus. In euismod enim ut bibendum.'
},
{
image: 'https://picsum.photos/id/1045/400/300',
title: 'Maecenas quis quam dignissim',
desc: 'Maecenas quis quam dignissim, rhoncus velit nec, dignissim ipsum. Sed eget elit in lacus.'
},
{
image: 'https://picsum.photos/id/1050/400/300',
title: 'Cras euismod mauris eu nulla',
desc: 'Cras euismod mauris eu nulla interdum, sit amet tempor massa maximus. Donec in commodo lectus.'
}
]
}
}
}
</script>
```
效果如下图所示:

阅读全文
相关推荐


















