Taro3 Vue3 Swiper 高度自适应内部图片


<template>
  <view class="swiper-box">
    <image class="fix-height-with-me" mode="widthFix" :src="props.items[0]" />
    <swiper
      class="swiper"
      :previousMargin="state.margin"
      :nextMargin="state.margin"
      :current="state.current"
      @change="onChange"
      circular
    >
      <swiper-item v-for="(item, i) in props.items" :key="i" class="item">
        <view
          class="img"
          :class="{
            active: i === state.current,
            left: i < state.current,
            right: i > state.current
          }"
          :style="{
            backgroundImage: `url(${item})`
          }"
        >
          <view class="mask"></view>
        </view>
      </swiper-item>
    </swiper>
  </view>
</template>

<script setup lang="ts">
  import Taro from '@tarojs/taro'
  import { reactive, onMounted } from 'vue'

  const props = defineProps<{
    // 图片地址列表
    items: string[]
    // 当前激活的
    current?: number
  }>()

  const state = reactive({
    current: props?.current ?? 1,
    margin: '30px'
  })

  const onChange = ({ detail }) => {
    state.current = detail.current
  }

  const getSwiperItemHeight = () => {
    const q = Taro.createSelectorQuery()
    q.select('.fix-height-with-me').boundingClientRect()

    q.exec((res) => {
      // 计算出卡片距离两边宽度的一半作为缩进
      state.margin = `${(375 - res[0].width) / 2 + 10}px`
    })
  }

  onMounted(() => {
    getSwiperItemHeight()
  })
</script>

<style lang="scss">
  .swiper-box {
    position: relative;
    height: auto;
    width: 100%;
    .fix-height-with-me {
      position: relative;
      top: 0;
      left: 0;
      width: 200px;
      z-index: 10;
      opacity: 0;
    }
    .swiper {
      position: absolute;
      top: 0;
      left: 0;
      height: 100%;
      width: 100%;
      z-index: 20;
      .item {
        display: flex;
        justify-content: center;
      }
      .img {
        position: relative;
        width: 200px;
        height: 300px;
        border-radius: 16px;
        background-size: cover;
        overflow: hidden;
        .mask {
          position: absolute;
          width: 100%;
          height: 100%;
          background-color: #000;
          opacity: 0.5;
          transition: opacity 0.3s;
        }
        &.active {
          .mask {
            opacity: 0;
          }
        }
      }
    }
  }
</style>

效果:

声明:八零秘林|版权所有,违者必究|如未注明,均为原创|本网站采用BY-NC-SA协议进行授权

转载:转载请注明原文链接 - Taro3 Vue3 Swiper 高度自适应内部图片


记忆碎片 · 精神拾荒