swiper在vue项目中实现两小一大

如果你已经写的差不多了(项目中已经用上了),就是两小一大布局怼不出来,建议点击跳到这

最终效果

swiper在vue项目中实现两小一大

Vue中使用Swiper

api文档

安装(以前用过4,就拿4过来用了 Swiper各版本比较

swiper在vue项目中实现两小一大

npm i swiper@4.5.1

在main.js 中,引入

import Swiper from 'swiper';
import 'swiper/dist/css/swiper.css';
window.Swiper = Swiper;

页面组件中使用

两大一小实现

封装成组件了

轮播图组件

原先使用el-carousel css 样式没删干净,要用的自己删 不过不影响
.cover_a 元素下的元素自己改成需要的
paly、arrow_left、arrow_right 得用你自己的 在asssets里换

// 尚未特殊处理 1台和2台设备的特殊情况
// 小屏适配未搞
/**
 * 已解决
 * 1. 两大一小布局
 * 2. slide 穿透按钮 给.swiper-container 包了个.swiper-container-container
 * 3. 数据更新刷新swiper loop异常 vue更新的问题 通过 v-if或 改key 重新刷swiper
 * 4. pagination bullets , dynamicBullets: true 好像不支持无限滚动(loop: true)
 *    或许可以通过api type: 'custom',和renderCustom() 自定义 ,而且pagination 也要改样式
 *    太麻烦了,我直接 type: "fraction"
 * 5. 由于解决第二个问题 改给#qx_swiper 加 事件鼠标移入移除开关 autoplay
 */

components/qx_swiper.vue

<template>
  <!-- 使用Swiper -->
  <div id="qx_swiper" :key="mySwiperKey" ref="qx_swiper">
    <div class="swiper-container-container">
      <div ref="swiper-container" class="swiper-container">
        <div class="swiper-wrapper">
          <div class="swiper-slide" v-for="item in list" :key="item.id">
            <template>
              <a
                class="cover_a"
                href="javascript:void(0);"
                @click="openVideo(item.puid, item.idx, item.status)"
              >
                <!-- <router-link class="cover_a" :to="{name:'HomeVideo',query: {'puid': item.puid,'idx': item.idx,'status': item.status}}"  target="_blank"> -->
                <div class="cover">
                  <h3 style="z-index: 300" textEps :title="item.name">
                    {{ item.name }}
                  </h3>
                  <div
                    class="block"
                    style="width: 100%; height: 100%; background-color: #000"
                  >
                    <el-image :src="'http://' + url + item.images">
                      <div slot="error" class="image-slot"></div>
                    </el-image>
                  </div>
                  <i class="tri" />
                </div>
                <!-- </router-link> -->
              </a>
            </template>
          </div>
        </div>
      </div>
      <!-- 如果需要分页器 -->
      <div class="swiper-pagination"></div>
      <!-- 如果需要滚动条 -->
      <div class="swiper-scrollbar"></div>
    </div>
    <!-- 如果需要导航按钮 -->
    <div class="swiper-button-prev"></div>
    <div class="swiper-button-next"></div>
  </div>
</template>

<script>

export default {
  name: "QxSwiper",
  data() {
    return {
      mySwiper: null,
      mySwiperKey: "_" + Date.now() + Math.random(),
    };
  },
  props: {
    list: {
      type: Array,
      required: true,
    },
    url: {
      type: String,
      required: true,
    },
  },
  methods: {
    // 屏幕响应式
    initSwiper() {
      const self = this;
      let domEl = self.$refs["swiper-container"]; // .swiper-container
      self.mySwiper = new window.Swiper(domEl, {
        direction: "horizontal", // 默认水平horizontal 垂直 vertical
        // autoHeight: true, // 自动高度。设置为true时,wrapper和container会随着当前slide的高度而发生变化。
        loop: true, // 循环模式选项 设置为true 则开启loop模式。loop模式:会在原本slide前后复制若干个slide(默认一个)并在合适的时候切换,让Swiper看起来是循环的。
        autoplay: {
          delay: 3000,
          stopOnLastSlide: false, // 如果设置为true,当切换到最后一个slide时停止自动切换。(loop模式下无效)。
          disableOnInteraction: false, // 用户操作swiper之后,是否禁止autoplay。默认为true:停止
        },

        // slidesPerView: 3, // 设置slider容器能够同时显示的slides数量(carousel模式)。"auto"
        slidesPerView: 3,
        // loopedSlides: 5, //在loop模式下使用slidesPerview:'auto',还需使用该参数设置所要用到的loop个数(一般设置大于可视slide个数2个即可)。
        centeredSlides: true, // 设定为true时,active slide会居中,而不是默认状态下的居左。
        centerInsufficientSlides: false, // 开启这个参数,当slides的总数小于slidesPerView时,slides居中。不适用于loop模式和slidesPerColumn
        // centeredSlidesBounds: true, // 当设置了Active Slide居中后,还可以配合设置此参数,使得第一个和最后一个Slide 始终贴合边缘。
        spaceBetween: 10, //在slide之间设置距离(单位px)。

        mousewheel: true, // 开启鼠标滚轮控制Swiper切换。可设置鼠标选项,或true使用默认值。

        // paginationClickable: true,
        // 如果需要分页器
        pagination: {
          // type: "bullets", // 分页器样式类型,可选 ‘bullets’  圆点(默认) ‘fraction’  分式  ‘progressbar’  进度条 ‘custom’ 自定义
          type: "fraction",
          el: ".swiper-pagination",
          clickable: true,
          dynamicBullets: true, // 动态分页器,当你的slide很多时,开启后,分页器小点的数量会部分隐藏。
          dynamicMainBullets: 1, //动态分页器的主指示点的数量
        },
        watchSlidesProgress: true, // https://www.swiper.com.cn/api/progress/191.html Progress(进度、进程)分为swiper的progress 和每个slide单独的progress。 开启这个参数来计算每个slide的progress,Swiper的progress无需设置即开启。
        // api 不一致 progress,setTransition,slideChangeStart 只有一个参数 或者是版本问题

        observer: true, //启动动态检查器(OB/观众/观看者),当改变swiper的样式(例如隐藏/显示)或者修改swiper的子元素时,自动初始化swiper。默认false,不开启,可以使用update()方法更新。
        observeParents: true, //将observe应用于Swiper的父元素。当Swiper的父元素变化时,例如window.resize,Swiper更新。响应式
        observeSlideChildren: true, //子slide更新时,swiper是否更新。默认为false不更新。
        // onProgress: function (swiper, progress) {
        //   console.log("onProgress:", swiper, progress);
        //   for (let i = 0; i < swiper.slides.length; i++) {
        //     //因为活动的就是0
        //     swiper.slides[i].style.transform =
        //       "scale(" + (swiper.slides[i].progress + 1) + ")";
        //   }
        // },
        // 如果需要前进后退按钮
        navigation: {
          nextEl: ".swiper-button-next",
          prevEl: ".swiper-button-prev",
        },

        // 如果需要滚动条
        // scrollbar: {
        //   el: ".swiper-scrollbar",
        // },
      });
      // console.log(self.mySwiper);
      //鼠标滑过pagination控制swiper切换 // 不适合dynamicBullets动态分页器 省略小圆点
      // for (let i = 0; i < self.mySwiper.pagination.bullets.length; i++) {
      //   console.log('listens');
      //   self.mySwiper.pagination.bullets[i].onmouseover = function () {
      //     this.click();
      //   };
      // }
      //鼠标覆盖停止自动切换
      // self.mySwiper.el.onmouseover = function () {
      //   self.mySwiper.autoplay.stop();
      // };
      self.$refs["qx_swiper"].onmouseover = function () {
        self.mySwiper.autoplay.stop();
      };

      //鼠标离开始自动切换
      // self.mySwiper.el.onmouseout = function () {
      //   self.mySwiper.autoplay.start();
      // };
      self.$refs["qx_swiper"].onmouseout = function () {
        self.mySwiper.autoplay.start();
      };
    },
    // 新窗口打开视频播放页面
    openVideo(puid, idx, status) {
      const self = this;
      var routeUrl = self.$router.resolve({
        name: "HomeVideo",
        query: {
          puid: puid,
          idx: idx,
          status: status,
        },
      });
      window.open(routeUrl.href, "_blank");
    },
  },
  mounted() {
    const self = this;
    // self.initSwiper();
  },
  watch: {
    list: {
      deep: true,
      immediate: true,
      handler(val) {
        const self = this;
        if (val && val.length > 0) {
          self.mySwiperKey = "_" + Date.now() + Math.random();
          self.$nextTick(() => {
            self.initSwiper();
          });
        }
      },
    },
  },
};
</script>

<style lang="scss" scoped>
/deep/.swiper-pagination-bullet {
  width: 12px;
  height: 12px;
  outline: none;
}
#qx_swiper {
  // background: red;
  position: absolute;
  z-index: 300;
  // width: 1204px;
  width: calc(460px + 320px * 2 + 4 * 10px + 32px * 2);
  // max-height: 375px;
  bottom: 0px;
  left: 50%;
  transform: translateX(-50%);
  .swiper-container-container {
    margin-left: 42px;
    width: calc(460px + 320px * 2 + 2 * 10px);
    overflow: hidden;
    padding-bottom: 20px;
  }
  .swiper-container {
    margin-left: -140px;
    // 分页器样式
    height: 220px;
    width: calc(460px * 3 + 2 * 10px);
    // width: calc(100% - 84px);
    // padding: 0 42px;
    --swiper-theme-color: #ff6600;
    --swiper-pagination-color: #00ff33; /* 两种都可以 */
  }

  .swiper-pagination-fraction,
  .swiper-pagination-custom,
  .swiper-container-horizontal > .swiper-pagination-bullets {
    // bottom: -6px;
    bottom: 0px;
  }
  .swiper-pagination {
    left: 50%;
    // bottom: -6px;
    bottom: 0px;
    transform: translateX(-50%);
  }

  .swiper-slide {
    // background: yellow;
    height: 100%;
    width: 460px !important;
    .cover_a {
      display: block;
      width: 100%;
      height: 100%;
      .cover {
        height: 100%;
        position: relative;
        h3 {
          position: absolute;
          top: 9px;
          left: 10px;
          width: 300px;
          height: 20px;
          font-size: 18px;
          font-family: MicrosoftYaHei-Bold, MicrosoftYaHei;
          font-weight: bold;
          color: rgba(255, 255, 255, 1);
          line-height: 20px;
        }
        .tri {
          position: absolute;
          display: block;
          width: 75px;
          height: 88px;
          background: url("../assets/img/play.png") no-repeat;
          top: 0;
          left: 0;
          right: 0;
          bottom: 0;
          margin: auto;
          &:hover {
            opacity: 0.8;
            transform: scale(1.2);
            transition: 0.3s;
          }
        }
      }
    }
  }

  // .swiper-slide-active,
  // .swiper-slide-duplicate-active {
  //   // transform: scale(1.2);
  //   width: 320px !important;
  // }

  .swiper-slide-prev {
    // width: 320px !important;
    .cover_a {
      margin-left: 140px;
      width: 320px;
    }
  }
  .swiper-slide-next {
    // width: 320px !important;
    .cover_a {
      width: 320px;
    }
  }

  .swiper-button-prev {
    top: 0;
    margin-top: 0;
    left: 0px;
    width: 32px;
    height: 220px;
    outline: none;
    background: rgba(216, 216, 216, 0.1) url("../assets/img/arrow_left.svg")
      no-repeat 50% 50%;
  }
  .swiper-button-next {
    top: 0;
    margin-top: 0;
    right: 0px;
    width: 32px;
    height: 220px;
    outline: none;
    background: rgba(216, 216, 216, 0.1) url("../assets/img/arrow_right.svg")
      no-repeat 50% 50%;
  }

  .el-carousel {
    .is-in-stage {
      height: 220px;
      padding: 0 10px;
      width: 340px;
      // transform: translateX(832px) scale(1) !important;
      transform: translateX(32px) scale(1) !important;
    }
    // .el-carousel__item:not(.is-active) + .is-in-stage {
    //   transform: translateX(32px) scale(1) !important;
    // }
    .el-carousel__item--card.is-active.is-in-stage {
      padding: 0;
      width: 460px;
      transform: translateX(372px) scale(1) !important;
    }
    // div.el-carousel__item:has(+ .is-active) {
    //   transform: translateX(32px) scale(1) !important;
    // }
    .el-carousel__item--card.is-active + .is-in-stage {
      transform: translateX(832px) scale(1) !important;
    }
    // .el-carousel__item:nth-of-type(1).is-in-stage + :not(.is-active) {
    //   transform: translateX(832px) scale(1) !important;
    // }
    img {
      width: 100%;
    }
  }
}

// .hack_first_img {
//   transform: translateX(832px) scale(1) !important;
// }
@media screen and (min-width: 1360px) and (max-width: 1400px) {
  // .hack_first_img {
  //   transform: translateX(605px) scale(1) !important;
  // }
  .qx_carousel {
    position: absolute;
    z-index: 300;
    bottom: -10px;
    left: 50%;
    margin-left: -437.5px;
    // 23x2+233x2+7x4+335
    width: 875px;
    .cover_a {
      display: block;
      width: 100%;
      height: 100%;
      .cover {
        height: 100%;
        position: relative;
        h3 {
          position: absolute;
          top: 7px;
          left: 7px;
          width: 300px;
          height: 16px;
          font-size: 14px;
          font-family: MicrosoftYaHei-Bold, MicrosoftYaHei;
          font-weight: bold;
          color: rgba(255, 255, 255, 1);
          line-height: 16px;
        }
        .tri {
          position: absolute;
          display: block;
          width: 53px;
          height: 61px;
          background-position: center center;
          background-size: 53px;
          background-image: url("../assets/img/play.png");
          background-repeat: no-repeat;
          top: 0;
          left: 0;
          right: 0;
          bottom: 0;
          margin: auto;
          &:hover {
            opacity: 0.8;
            transform: scale(1.2);
            transition: 0.3s;
          }
        }
      }
    }
    .el-carousel--horizontal {
      height: 190px;
      overflow: hidden;
    }
    .el-carousel {
      /deep/.el-carousel__container {
        height: 160px;
      }
      /deep/.el-carousel__arrow {
        width: 23px;
        height: 160px;
        border-radius: 0;
        ::before {
          content: "";
        }
        &.el-carousel__arrow--left {
          background: rgba(216, 216, 216, 0.1)
            url("../assets/img/arrow_left.svg") no-repeat 50% 50%;
          left: 0;
        }
        &.el-carousel__arrow--right {
          right: 0;
          background: rgba(216, 216, 216, 0.1)
            url("../assets/img/arrow_right.svg") no-repeat 50% 50%;
        }
      }
      .el-carousel__item--card.is-active {
        padding: 0;
        width: 335px;
        // 23+7+233+7
        transform: translateX(270px) scale(1) !important;
      }
      /deep/.el-carousel__mask {
        background: none;
      }
      .is-in-stage {
        height: 160px;
        padding: 0 7px;
        width: 247px;
        // 23
        transform: translateX(23px) scale(1) !important;
      }
      .el-carousel__item--card.is-active + .is-in-stage {
        // 23+7+233+7+335+7-7(padding)
        transform: translateX(605px) scale(1) !important;
      }
      img {
        width: 100%;
      }
    }
  }
}

@media screen and (max-width: 1360px) {
  // .hack_first_img {
  //   transform: translateX(590px) scale(1) !important;
  // }
  .qx_carousel {
    position: absolute;
    z-index: 300;
    bottom: -10px;
    left: 50%;
    margin-left: -427px;
    // 23x2+7x4+227x2+326
    width: 854px;
    .cover_a {
      display: block;
      width: 100%;
      height: 100%;
      .cover {
        height: 100%;
        position: relative;
        h3 {
          position: absolute;
          top: 7px;
          left: 7px;
          width: 300px;
          height: 16px;
          font-size: 14px;
          font-family: MicrosoftYaHei-Bold, MicrosoftYaHei;
          font-weight: bold;
          color: rgba(255, 255, 255, 1);
          line-height: 16px;
        }
        .tri {
          position: absolute;
          display: block;
          width: 53px;
          height: 61px;
          background-position: center center;
          background-size: 53px;
          background-image: url("../assets/img/play.png");
          background-repeat: no-repeat;
          top: 0;
          left: 0;
          right: 0;
          bottom: 0;
          margin: auto;
          &:hover {
            opacity: 0.8;
            transform: scale(1.2);
            transition: 0.3s;
          }
        }
      }
    }
    .el-carousel--horizontal {
      // 156+30
      height: 186px;
      overflow: hidden;
    }
    .el-carousel {
      /deep/.el-carousel__container {
        height: 156px;
      }
      /deep/.el-carousel__arrow {
        width: 23px;
        height: 156px;
        border-radius: 0;
        ::before {
          content: "";
        }
        &.el-carousel__arrow--left {
          background: rgba(216, 216, 216, 0.1)
            url("../assets/img/arrow_left.svg") no-repeat 50% 50%;
          left: 0;
        }
        &.el-carousel__arrow--right {
          right: 0;
          background: rgba(216, 216, 216, 0.1)
            url("../assets/img/arrow_right.svg") no-repeat 50% 50%;
        }
      }
      .el-carousel__item--card.is-active {
        padding: 0;
        width: 326px;
        // 23+7+227+7
        transform: translateX(264px) scale(1) !important;
      }
      /deep/.el-carousel__mask {
        background: none;
      }
      .is-in-stage {
        height: 156px;
        padding: 0 7px;
        // 227+14
        width: 241px;
        // 23
        transform: translateX(23px) scale(1) !important;
      }
      .el-carousel__item--card.is-active + .is-in-stage {
        // 23+7+227+7+326+7-7(padding)
        transform: translateX(590px) scale(1) !important;
      }
      img {
        width: 100%;
      }
    }
  }
}
</style>

溢出隐藏样式(扔到全局样式 或 上面文件里的<style></style> 里)

[textEps]{
  
  max-width: 100%;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

如果那个名称你想用el-tooltip ,可以给 需要溢出隐藏的元素转行内块

display: inline-block;

页面中使用

prop url 是轮播图用到的图片地址
deviceList 设备还有 puid、idx、status模拟数据我没写 建议直接自己模拟全 或 将.cover_a元素下的东西删掉 放个img
qx-swiper v-if 是为了防止它提前渲染了,不过我 watch也判了下,如果要显隐 可以再加个 v-show

views/home/index.vue

<template>
  <el-container class="home">
    <el-main>
      <qx-swiper
        v-if="proUrl.url && deviceList.length"
        :url="proUrl.url"
        :list="deviceList"
      ></qx-swiper>
    </el-main>
  </el-container>
</template>
<script>
import qxSwiper from "../../components/qx_swiper.js"
export default {
  name: "Home",
  components: {
    qxSwiper
  },
  data(){
    return {
      deviceList: [{
          name: "蜀山森林公园001",
          id: "1",
          images: "test.jpg",
        },
        {
          name: "蜀山森林公园002",
          id: "2",
          images: "test.jpg",
        },
        {
          name: "蜀山森林公园003",
          id: "3",
          images: "test.jpg",
        },
        {
          name: "蜀山森林公园004",
          id: "4",
          images: "test.jpg",
        },
        {
          name: "蜀山森林公园005",
          id: "5",
          images: "test.jpg",
        },
        {
          name: "蜀山森林公园006",
          id: "6",
          images: "test.jpg",
        },],
      proUrl: {
        host: '127.0.0.1',
        port: 9583,
        url: '127.0.0.1:9583'
      },
    }
  }
}
<script>

解决过程中遇到的问题

目标效果

swiper在vue项目中实现两小一大

1920 * 1080 设计图, 两个小盒 320 * 220 中间大的460 * 220,上一页、下一页 32 * 220, 间距都为10px 底部 20px

怪就怪在小图高和大图高一样,(对了,我那个图直接塞会变形的,不过没要求,你们可以缩放裁剪 或 背景图

一开始陷入思维误区

html结构

<div id="qx_swiper" ref="qx_swiper">
  <div ref="swiper-container" class="swiper-container">
    <div class="swiper-wrapper">
      <div class="swiper-slide">1</div>
      <div class="swiper-slide">2</div>
      <div class="swiper-slide">3</div>
    </div>
  </div>
    <!-- 如果需要分页器 -->
  <div class="swiper-pagination"></div>
  <!-- 如果需要滚动条 -->
  <div class="swiper-scrollbar"></div>
  <!-- 如果需要导航按钮 -->
  <div class="swiper-button-prev"></div>
  <div class="swiper-button-next"></div>
</div>
#qx_swiper{
  width: calc(460px + 320px * 2 + 4 * 10px + 32px * 2);
  .swiper-container{
    width: 100%;
  }
  .swiper-slide {
    width: 320px !important;
  }

  .swiper-slide-active,
  .swiper-slide-duplicate-active {
    // transform: scale(1.2);
    width: 460px !important;
  }

  // .swiper-slide-prev {
  //   width: 320px !important;
  // }
  // .swiper-slide-next {
  //   width: 320px !important;
  // }
}

反正不管是把当前的放大 或 前一个和后一个缩小,切换翻页就会有问题
原来用 el-carousel,是还要改前一个和后一个的translateX,然后最后一个切第一个的时候有问题,手动从倒数第二个直接切到第一个。。。就缺个css选择 前一个兄弟元素
然后换了这个Swiper我就是觉得原来的解决方法有问题,肯定不会再像那样搞,不过陷入这个思维误区,我想Swiper都是可控的,那改他的translateX 相关代码 ,然后就经历了 onProgress api不生效、on:{progress(swiper, progress) } api文档错误(明明说4版本以后支持的,根本没第二个参数 ,只有一个参数 progress)、swiper拿不到找半天才反应过来可以通过 this.swiper 拿到、dom7改元素transform属性不生效(放弃的原因)、以及动态修正transform不会搞 (不会改progress,咋改,改成啥值)

转机

写的过程一直在找相关博客,但他们写的都差不多,都是 两边小的宽高都缩放的,我一开始没太细看这个,主要搜 vue swiper 两大一小
重点找那种自定义切换过程的,然后就经历了上面的过程,也有可能是版本问题,但我不想切版本

由于上面的最后两步卡死了,我就想 凭啥他们宽高都缩都可以实现,为啥我就改个宽就实现不了,然后我又细看了一篇文档发现

.swiper-slide-prev{
  img{
    width: xxx;
  }
}
.swiper-slide-next {
  img{
    width: xxx;
  }
}

淦!!! 原来改的是**.swiper-slide里面的元素**!! 修正个毛 transform: translateX(xxx);!!

让我想明白的那篇文章我是不会放链的!! [/生气] (为什么没人博文里写 不要改.swiper-slide宽度

–> 最终结构点这里<–

其实想明白了,其实就很简单的。我们最终想要的轮播图宽度,并“不是”实际.swiper-container的宽度

结构图解
swiper在vue项目中实现两小一大
<div id="qx_swiper" ref="qx_swiper">
  <div ref="swiper-container" class="swiper-container">
    <div class="swiper-wrapper">
      <div class="swiper-slide">
        <a class="list-item-cover">
          1
        </a>
      </div>
      <div class="swiper-slide">
        <a class="list-item-cover">
          2
        </a>
      </div>
      <div class="swiper-slide">
        <a class="list-item-cover">
          3
        </a>
      </div>
    </div>
  </div>
    <!-- 如果需要分页器 -->
  <div class="swiper-pagination"></div>
  <!-- 如果需要滚动条 -->
  <div class="swiper-scrollbar"></div>
  <!-- 如果需要导航按钮 -->
  <div class="swiper-button-prev"></div>
  <div class="swiper-button-next"></div>
</div>
#qx_swiper{
  position: absolute;
  // z-index: 300;
  width: calc(460px + 320px * 2 + 4 * 10px + 32px * 2);
  bottom: 0px;
  left: 50%;
  transform: translateX(-50%);
  padding-bottom: 20px;
  overflow: hidden;
  .swiper-container{
    margin-left: -140px;
    height: 220px;
    width: calc(460px * 3 + 4 * 10px);
  }
  .swiper-slide {
    width: 460px !important;
    .list-item-cover{
      display: block;
      width: 100%;
      height: 100%;
    }
  }

  // .swiper-slide-active,
  // .swiper-slide-duplicate-active {
  //   width: 640px !important;
  // }

  .swiper-slide-prev {
    // width: 320px !important;
    .list-item-cover{
      margin-left: 140px;
      width: 320px;
    }
  }
  .swiper-slide-next {
    // width: 320px !important;
    .list-item-cover{
      width: 320px;
    }
  }
  .swiper-pagination {
    left: 50%;
    // bottom: -6px;
    bottom: 0px;
    transform: translateX(-50%);
  }
  .swiper-button-prev {
    top: 0;
    margin-top: 0;
    left: 0px;
    width: 32px;
    height: 220px;
    outline: none;
    // background: rgba(216, 216, 216, 0.1) url("../assets/img/arrow_left.svg") no-repeat 50% 50%;
  }
  .swiper-button-next {
    top: 0;
    margin-top: 0;
    right: 0px;
    width: 32px;
    height: 220px;
    outline: none;
    // background: rgba(216, 216, 216, 0.1) url("../assets/img/arrow_right.svg") no-repeat 50% 50%;
  }
}

**!!!**会发现 由于需要把swiper超出的部分隐藏,设了#qx_swiper overflow: hidden,左右两个按钮基于#qx_swiper定位 需要效果在两侧,如果将#qx_swiper width改为calc(320px * 2 + 460px + 2 * 10px) ,不包含翻页按钮和那两个间隙32px * 2 + 10px * 2 ,通过定位,定出去是看不见得;如果将#qx_swiper width改为calc(320px * 2 + 460px + 4 * 10px + 32px * 2) ,包含翻页按钮和那两个间隙,但是我那个翻页按钮是自定义的,有一定的透明度,就会看到轮播图从按钮下面穿过(对了,上面的css我是照最终css删改的,prev和next不好还原,你如果按钮不是透明的,就想像这样写,微调下 leftright就行了)。。。针对这个问题,我是通过给.swiper-container包个父元素.swiper-container-container 让它来搞溢出隐藏就ok啦

最终解决方案

<div id="qx_swiper" ref="qx_swiper">
  <!-- 搞个swiper-container-container包一下 start -->
  <div class="swiper-container-container">
    <div ref="swiper-container" class="swiper-container">
      <div class="swiper-wrapper">
        <div class="swiper-slide">
          <a class="list-item-cover">
            1
          </a>
        </div>
        <div class="swiper-slide">
          <a class="list-item-cover">
            2
          </a>
        </div>
        <div class="swiper-slide">
          <a class="list-item-cover">
            3
          </a>
        </div>
      </div>
    </div>
  </div>
  <!-- 搞个swiper-container-container包一下 end -->

  <!-- 如果需要分页器 -->
  <div class="swiper-pagination"></div>
  <!-- 如果需要滚动条 -->
  <div class="swiper-scrollbar"></div>
  <!-- 如果需要导航按钮 -->
  <div class="swiper-button-prev"></div>
  <div class="swiper-button-next"></div>
</div>

这个地方不要改,还是 .swiper-container,我只是拿 swiper-container-container包一下

const self = this;
let domEl = self.$refs["swiper-container"]; // .swiper-container
self.mySwiper = new window.Swiper(domEl, {...});
#qx_swiper{
  position: absolute;
  // z-index: 300;
  width: calc(460px + 320px * 2 + 4 * 10px + 32px * 2);
  bottom: 0px;
  left: 50%;
  transform: translateX(-50%);

  .swiper-container-container {
    margin-left: 42px;
    width: calc(460px + 320px * 2 + 2 * 10px);
    overflow: hidden;
    padding-bottom: 20px;
  }
  .swiper-container{
    margin-left: -140px;
    height: 220px;
    width: calc(460px * 3 + 4 * 10px);
  }
  .swiper-slide {
    width: 460px !important;
    .list-item-cover{
      display: block;
      width: 100%;
      height: 100%;
    }
  }

  // .swiper-slide-active,
  // .swiper-slide-duplicate-active {
  //   width: 640px !important;
  // }

  .swiper-slide-prev {
    // width: 320px !important;
    .list-item-cover{
      margin-left: 140px;
      width: 320px;
    }
  }
  .swiper-slide-next {
    // width: 320px !important;
    .list-item-cover{
      width: 320px;
    }
  }
  .swiper-pagination {
    left: 50%;
    // bottom: -6px;
    bottom: 0px;
    transform: translateX(-50%);
  }
  .swiper-button-prev {
    top: 0;
    margin-top: 0;
    left: 0px;
    width: 32px;
    height: 220px;
    outline: none;
    // background: rgba(216, 216, 216, 0.1) url("../assets/img/arrow_left.svg") no-repeat 50% 50%;
  }
  .swiper-button-next {
    top: 0;
    margin-top: 0;
    right: 0px;
    width: 32px;
    height: 220px;
    outline: none;
    // background: rgba(216, 216, 216, 0.1) url("../assets/img/arrow_right.svg") no-repeat 50% 50%;
  }
}

上面就是解决问题的方法,相信两小一大布局 万变变化皆可借鉴

上面解决方法理解了,如果我博文中写错的应该会改,想看实际我项目中使用的代码 GO

csdn博文 锚点跳转初次使用,参考GO

上一篇:vue轮播插件vue-awesome-swiper


下一篇:Vue2.5 去哪儿App项目学习【一】