Swiper10.1.0图片轮播效果

1、swiper安装10.1.0版本:https://blog.csdn.net/Y1914960928/article/details/132583878

Swiper10.1.0图片轮播效果_第1张图片

2、swiper使用:

① 模板使用:

Swiper10.1.0图片轮播效果_第2张图片

② ts中引入组件:

Swiper10.1.0图片轮播效果_第3张图片

③ 组件使用:

声明
Swiper10.1.0图片轮播效果_第4张图片
变量配置
Swiper10.1.0图片轮播效果_第5张图片
样式编写
Swiper10.1.0图片轮播效果_第6张图片

3、图片显示顺序问题:

Swiper10.1.0图片轮播效果_第7张图片

4、完整代码:

<template>
  <div class="pic-module">
    <!-- tab以及上传图片按钮 -->
    <div class="pic-module__top">
      <div class="left-box">
        <div class="tab-box" @click="changeTab">
          <div
            v-for="(item, index) in tabList"
            :key="index"
            :class="item.className"
          >
            {{ item.name }}
          </div>
        </div>
        <div v-if="uploadSettingVisiable" class="upload-box" @click="uploadDialogVisiable">
          <span class="upload-box__img"></span>
          <span class="upload-box__text">上传图片</span>
        </div>
      </div>
      <DateTime />
    </div>
    <!-- 轮播图需求:鼠标移入左侧或者右侧的固定区域,上下翻页的按钮进行显示 -->
    <a-spin tip="Loading..." :spinning="spinning">
      <div class="active-content">
        <swiper
          :modules="modules"
          :slides-per-view="1"
          :scrollbar="{ draggable: false }"
          :loop="true"
          :pagination="{clickable: false}"
          :navigation="navigation"
          class="swiper-content"
          @slideChange="onSlideChange"
          >
          <!-- 这里是轮播的图片,一定要循环多个,不然渲染会失败 -->
          <swiper-slide v-for="(item, index) in links" :key="index">
            <img :src="item" alt="" class="pic" />
          </swiper-slide>
          <!-- 这里是对于tab1有工具按钮的特殊配置 -->
          <div v-if="activeTab === 'tab1'" class="tool-box" @click="(event) => handleTool(event)">
            <img src="@/assets/images/fullScreen.png" alt="" class="pic-dialog" />
            <img src="@/assets/images/enlarge.png" alt="" class="pic-enlarge" />
            <img src="@/assets/images/shrink.png" alt="" class="pic-shrink" />
          </div>
          <!-- 这里是左翻页的固定框,类名自定义 -->
          <div class="preBox">
            <!-- 这里是左翻页,类名是自己定义的,需要在配置中进行赋值 -->
            <div class="swiper-button-prev"></div>
          </div>
          <!-- 这里是右翻页的固定框,类名自定义 -->
          <div class="nextBox">
            <!-- 这里右左翻页,类名是自己定义的,需要在配置中进行赋值 -->
            <div class="swiper-button-next"></div>
          </div>
        </swiper>
      </div>
    </a-spin>
  </div>
  <!-- 这个是tab1工具按钮点击后的弹窗 -->
  <Dialog
    :showDialog="showDialog"
    :imgUrl="imgUrl"
    @closeDialog="dialogVisible"
  />
  <!-- 这个是上传图片按钮点击后的的弹窗 -->
  <UploadDialog
    v-if="showUploadDialog"
    :showUploadDialog="!!showUploadDialog"
    :activeTab="activeTab"
    :imgUrl="links"
    :qyStoreId="qyStoreId"
    @closeDialog="uploadDialogVisiable"
    @submitDialog="submitDialog"
  />
</template>

<script lang="ts">
import { defineComponent, reactive, toRefs, watch} from 'vue'
// 引入时间组件
import DateTime from '@/components/DateTime.vue'
// 引入提示框
import { message } from 'ant-design-vue'
// 引入图片放大的弹窗
import Dialog from '@/components/Dialog/index.vue'
// 引入设置图片的弹窗
import UploadDialog from '@/components/UploadDialog/index.vue'
// 引入请求
import G from '@/request/G'
import { useStore } from 'vuex'
// 引入swiper组件
import { Swiper, SwiperSlide } from "swiper/vue";
import "swiper/css/pagination"; // 轮播图底面的小圆点
import "swiper/css/navigation"; // 轮播图两边的左右箭头
// 引入swiper核心和所需模块
import { Navigation,Pagination } from "swiper/modules";

export default defineComponent({
  name: 'PicModule',
  components: {
    DateTime,
    Dialog,
    UploadDialog,
    Swiper,
    SwiperSlide
  },
  props: {
    storeId: { // 拿到的机构Id
      type: String,
      default: ''
    }
  },
  setup (props) {
    const store = useStore()
    const data = reactive({
      spinning: true, // 是否处于加载中
      tabList: [
        {
          name: 'tab0',
          className: 'common-tab active-tab'
        },
        {
          name: 'tab1',
          className: 'common-tab'
        }
      ], // tab的样式
      activeTab: 'tab0', // 当前活跃的tab
      scaleNumber: 1, // tab1的放大缩小基数
      showDialog: false, // 当前的图片是否要放大
      imgUrl: '', // 当前图片的地址
      qyStoreId: '', // 企业的storeId
      showUploadDialog: false,
      uploadSettingVisiable: false,
      modules: [Pagination, Navigation],
      links: [] as string[],
      currentPage: 0, // 默认是第一张,这个变量主要用于tab1的工具按钮进行区分
      navigation: { // 这里就是自定义分页器的配置
        nextEl: ".swiper-button-next",
        prevEl: ".swiper-button-prev",
      }
    })
    // 初始化图表
    const init = (val:string) => {
      data.imgUrl = ''
      data.links = []
      let params = {
        _api: 'XXXX',
        storeId: val,
        drawType: data.activeTab === 'tab0' ? 1 : 2,
        _v: '1.0'
      } as any
      params = G.buildInputs(params)
      G.baseAjax({
        type: 'POST',
        data: G.param(params) + '&_at=' + G.buildAt(params)
      }).then((res:any) => {
        const { success, model } = res
        if (success) {
          if (model) {
          	// 给图片赋值
            data.links = model.split(',')
          }
        } else {
          message.error(res.msgInfo)
        }
        data.spinning = false
      })
    }

    // tab切换
    const changeTab = (event: MouseEvent) => {
      data.spinning = true
      const target = event.target as HTMLElement
      const value = target.innerText
      data.activeTab = value
      data.tabList.forEach((item) => {
        item.className = 'common-tab'
        if (item.name === value) {
          item.className = 'common-tab active-tab'
        }
      })
      const picDom: any = document.getElementsByClassName('pic')
      if (picDom && picDom.length) {
        for (let i = 0; i < picDom.length; i++) {
          picDom[i].style.transform = `scale(1)`
        }
      }
      init(data.qyStoreId)
    }

    // 点击图表工具中的弹窗全屏、放大、缩小
    const handleTool = (event: MouseEvent) => {
      const target = event.target as HTMLElement
      const value = target.className
      const picDom: any = document.getElementsByClassName('pic')[data.currentPage]
      if (value === 'pic-dialog') {
        data.imgUrl = picDom.getAttribute('src')
        // 弹窗全屏
        dialogVisible(true)
      } else if (value === 'pic-enlarge') {
        // 放大
        data.scaleNumber += 0.2
        picDom.style.transform = `scale(${data.scaleNumber})`
      } else if (value === 'pic-shrink') {
        // 缩小
        data.scaleNumber -= 0.2
        if (data.scaleNumber > 0.2) {
          picDom.style.transform = `scale(${data.scaleNumber})`
        } else {
          message.error('不能缩小了!')
        }
      }
    }

    // 是否显示tab1的弹窗
    const dialogVisible = (val: boolean) => {
      data.showDialog = val
    }

    // 上传图片弹窗
    const uploadDialogVisiable = (val: boolean) => {
      data.showUploadDialog = val
    }

    const submitDialog = (val: {cqImgUrl:string[];nyImgUrl:string[]}) => {
      if (data.activeTab === 'tab0') {
        data.links = val.cqImgUrl
      }
      if (data.activeTab === 'tab1') {
        data.links = val.nyImgUrl
      }
      uploadDialogVisiable(false)
    }

    // 监听当前的storeId
    watch(
      () => props.storeId,
      (val: string) => {
        if (val) {
          data.qyStoreId = val
          // 请求当前的图表
          init(val)
          data.uploadSettingVisiable = parseInt(store.state.userInfo.userRole) === 100
        }
      },
      {
        immediate: true,
        deep: true
      }
    )

    const onSlideChange = (swiper:any) => {
      data.currentPage = swiper.activeIndex
    }

    return {
      ...toRefs(data),
      changeTab,
      handleTool,
      dialogVisible,
      uploadDialogVisiable,
      submitDialog,
      onSlideChange
    }
  }
})
</script>

<style lang="scss" scoped>
.pic-module {
  &__top {
    display: flex;
    justify-content: space-between;
    flex-wrap: nowrap;
    height: 121px;
  }
  .tab-box {
    display: flex;
    flex-wrap: nowrap;
    .common-tab {
      cursor: pointer;
      position: relative;
      width: 280px;
      height: 96px;
      text-align: center;
      font-size: 44px;
      font-weight: 600;
      color: #cbccce;
      line-height: 96px;
      &::after {
        content: "";
        position: absolute;
        right: -20px;
        width: 2px;
        height: 96px;
        background: linear-gradient(
          180deg,
          rgba(46, 139, 234, 0) 0%,
          #2e8bea 50%,
          rgba(46, 139, 234, 0) 100%
        );
      }
      &:last-of-type {
        left: 40px;
        &:after {
          background: none;
        }
      }
    }
    .active-tab {
      background: url("@/assets/images/tab_active_bg.png") no-repeat;
      background-size: 100% 100%;
      color: #fff;
    }
  }
  .active-content {
    position: relative;
    height: 1115px;
    // height: 1079px;
    margin: 40px 0 44px;
    .pic {
      object-fit: contain;
      width: 100%;
      height: 1115px;
      transform: scale(1);
    }
    .tool-box {
      display: flex;
      flex-direction: column;
      position: absolute;
      right: 4px;
      bottom: 0;
      z-index: 200;
      .pic-dialog,
      .pic-enlarge,
      .pic-shrink {
        cursor: pointer;
        display: inline-block;
        margin-bottom: 24px;
      }
    }
  }
  .left-box {
    display: flex;
    align-items: center;
  }
  .upload-box {
    cursor: pointer;
    display: flex;
    align-items: center;
    margin-left: 60px;
    &__img {
      display: inline-block;
      width: 32px;
      height: 32px;
      background: url("@/assets/images/uploadImg.png") no-repeat;
      background-size: 100% 100%;
      margin-right: 10px;
    }
    &__text {
      font-size: 32px;
      color: #589CFD;
    }
  }
}
</style>

<style lang="scss">
  .swiper-pagination-bullet {
    display: inline-block;
    width: 16px;
    height: 16px;
    background: rgba(255,255,255,0.25);
    margin-right: 24px!important;
  }
  .swiper-pagination-bullet-active {
    background: #3196FA;
  }
  .swiper-button-prev {
    display: none;
    position: relative;
    width: 80px;
    height: 80px;
    background: url("@/assets/images/prev.png") no-repeat;
    background-size: 100% 100%;
  }
  .swiper-button-next {
    display: none;
    width: 80px;
    height: 80px;
    background: url("@/assets/images/next.png") no-repeat;
    background-size: 100% 100%;
  }
  .swiper-button-prev:after,.swiper-button-next:after {
    display: none;
  }
  .preBox {
    z-index: 100;
    position: absolute;
    top: 0;
    left: 0;
    display: inline-block;
    width: 120px;
    height: 1100px;
    &:hover {
      .swiper-button-prev {
        display: inline-block;
      }
    }
  }
  .nextBox {
    z-index: 100;
    position: absolute;
    top: 0;
    right: 0;
    display: inline-block;
    width: 120px;
    height: 1100px;
    &:hover {
      .swiper-button-next {
        display: inline-block;
      }
    }
  }
</style>

5、效果图:

6、遇到的问题及解决:

① 分页器不显示:

换版本

本来一开始用的swiper7.4.1,但是分页器一直不出来,元素审查都没有找到对应的代码,所以换了版本。

增加下面的代码

import Swiper, {Navigation, Pagination} from "swiper";
// 新版Swiper默认只导出核心部分,需要如导航、分页等组件的话需要另外导入,并使用Swiper.use()添加
Swiper.use([Navigation, Pagination]);

② 鼠标移入左侧或者右侧的固定区域,上下翻页的按钮进行显示,否则不显示,也不会一起显示:

给上下翻页的按钮套个壳子,然后更改图层的权重
Swiper10.1.0图片轮播效果_第8张图片
Swiper10.1.0图片轮播效果_第9张图片

你可能感兴趣的:(vue,前端)