123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188 |
- <template>
- <div class="banner-container">
- <swiper :style="{width: '100vw', height: '682rpx'}"
- :autoplay="swiperConfig.autoplay"
- :interval="swiperConfig.interval"
- :duration="swiperConfig.duration"
- :circular="swiperConfig.circular"
- :previous-margin="swiperConfig.previousMargin"
- :next-margin="swiperConfig.nextMargin"
- @change="swiperChange"
- @animationfinish="animationfinish">
- <swiper-item v-for="(item, i) in bannerList" :key="i">
- <!-- 1.当前展示为第1项时,bannerList最后一项和第二项的justifyContent值分别为flex-end和flex-start,其余项值为center -->
- <!-- 2.当前展示为最后一项时,bannerList倒数第2项和第1项的justifyContent值分别为flex-end和flex-start,其余项值为center -->
- <!-- 3.当前展示为其他项(非第1和最后1项)时,bannerList当前项的前1项和后1项的justifyContent值分别为flex-end和flex-start,其余项值为center -->
- <!-- 4.padding值也需要根据不同项设定不同值,但理同justifyContent -->
- <div class="image-container"
- :class="[curIndex===0?((i===listLen-1)?'item-left':(i===1?'item-right':'item-center')):(curIndex===listLen-1?(i===0?'item-right':(i===listLen-2?'item-left':'item-center')):(i===curIndex-1?'item-left':(i===curIndex+1?'item-right':'item-center')))]">
- <image :src="item.picture"
- class="slide-image"
- :style="{
- transform: curIndex===i?'scale(' + scaleX + ',' + scaleY + ')':'scale(1,1)',
- transitionDuration: '.3s',
- transitionTimingFunction: 'ease'
- }"
- @click="selectBanner(i)"/>
- </div>
- </swiper-item>
- </swiper>
- <div class="desc-wrap" :class="[isDescAnimating?'hideAndShowDesc':'']">
- <div class="btn" @click="selectBanner(descIndex)">一键购买</div>
- </div>
- </div>
- </template>
- <script>
- export default {
- props: {
- bannerList: {
- type: Array,
- default () {
- return []
- }
- },
- swiperConfig: {
- type: Object,
- default () {
- return {
- indicatorDots: true,
- indicatorColor: 'rgba(255, 255, 255, .4)',
- indicatorActiveColor: 'rgba(255, 255, 255, 1)',
- autoplay: false,
- interval: 3000,
- duration: 300,
- circular: true,
- previousMargin: '58rpx',
- nextMargin: '58rpx'
- }
- }
- },
- scaleX: {
- type: String,
- default: (634 / 550).toFixed(4)
- },
- scaleY: {
- type: String,
- default: (378 / 328).toFixed(4)
- }
- },
- computed:{
- listLen () {
- return this.bannerList.length
- }
- },
- data () {
- return {
- curIndex: 0,
- descIndex: 0,
- isDescAnimating: false
- }
- },
- methods: {
- swiperChange (e) {
- const that = this
- this.curIndex = e.mp.detail.current
- this.isDescAnimating = true
- let timer = setTimeout(function () {
- that.descIndex = e.mp.detail.current
- clearTimeout(timer)
- }, 150)
- },
- animationfinish (e) {
- this.isDescAnimating = false
- },
- selectBanner(index) {
- this.$emit("selectBanner",this.bannerList[index]);
- }
- }
- }
- </script>
- <style lang="scss" scoped>
- .banner-container {
- width: 100vw;
- height: 662rpx;
- position: relative;
- .image-container {
- box-sizing: border-box;
- width: 100%;
- height: 100%;
- display: flex;
- .slide-image {
- width: 550rpx;
- height: 550rpx;
- z-index: 200;
- border-radius: 15rpx;
- }
- }
- .item-left {
- justify-content: flex-end;
- padding: 56rpx 26rpx 0 0;
- }
- .item-right {
- justify-content: flex-start;
- padding: 56rpx 0 0 26rpx;
- }
- .item-center {
- justify-content: center;
- padding: 56rpx 0 0 0;
- }
- .desc-wrap {
- position: absolute;
- bottom:-10rpx;
- left:0rpx;
- width: 100%;
- display: flex;
- align-items: center;
- justify-content: center;
- box-sizing: border-box;
- .btn {
- background-image: linear-gradient(#ff4545,red);
- padding: 15rpx 30rpx;
- border-radius: 30rpx;
- background-color: red;
- color: #fff;
- font-size: 30rpx;
- font-family: 'PingFangTC-Regular';
- font-weight: 600;
- }
- }
- @keyframes descAnimation {
- 0% {
- opacity: 1;
- }
- 25% {
- opacity: .5;
- }
- 50% {
- opacity: 0;
- }
- 75% {
- opacity: .5;
- }
- 100% {
- opacity: 1;
- }
- }
- @-webkit-keyframes descAnimation {
- 0% {
- opacity: 1;
- }
- 25% {
- opacity: .5;
- }
- 50% {
- opacity: 0;
- }
- 75% {
- opacity: .5;
- }
- 100% {
- opacity: 1;
- }
- }
- .hideAndShowDesc {
- animation: descAnimation .3s ease 1;
- -webkit-animation: descAnimation .3s ease 1;
- }
- }
- </style>
|