实现swiper 3d 轮播效果

先上个效果图,代码可以直接拿~
image.png

安装swiper和vue-awesome-swiper

因为项目用的是nuxt2,所以考虑到swiper的兼容问题,选择的是"swiper": “^5.2.0”

首先是安装swiper和vue-awesome-swiper,并指定版本

npm install swiper@5.2.0 --save

npm install vue-awesome-swiper@4.1.1 --save

然后引入,在nuxt.config.js中引入

css: [
    'swiper/css/swiper.css'
],
plugins: [
    { src: '@/plugins/vue-swiper', ssr: false }
],

基本用法

在plugins下新建一个vue-swiper.js

import Vue from 'vue'
import VueAwesomeSwiper from 'vue-awesome-swiper'
Vue.use(VueAwesomeSwiper)

在components下新建一个VueSwiper.vue

<template>
  <div v-if="initStatus" v-swiper:mySwiper="swiperOption" class="swiper mySwiper swiperBox">
    <div class="swiper-wrapper">
      <div class="swiper-slide" v-for="(item, index) in list.value" :key="index">
        <div class="pr">
          <div class="swiper-slide-imgbox uf uf-ac uf-jc">
            <img :src="item.imageUrl" />
          </div>
          <div class="font12 c8 txt-box">{{ item.title }}</div>
        </div>
      </div>
    </div>
    <div class="swiper-button-prev"></div>
    <div class="swiper-button-next"></div>
  </div>
</template>
<script>
export default {
  props: {
    list: {//banner数组
      type: Object,
      default: function () {
        return {}
      }
    },
    slidesPerView: {//一页显示几个
      type: Number,
      default: 1
    }
  },
  data() {
    return {
      initStatus: false,//初始化状态
      swiperOption: {},//swiper参数
    }
  },
  mounted() {
    let self = this;
    this.$nextTick(() => {
      this.swiperOption = {
        loop: true,
        loopAdditionalSlides: 3,
        coverflowEffect: {
          rotate: 60, //侧转角度(正值凹陷)
          stretch: -80,//每个slide之间拉伸值(正值紧贴)
          depth: 100,  //值越大为远景(可负值)
          modifier: 1, //depth和rotate和stretch的倍率
          shadows: false
       },
        centeredSlides: true,
        initialSlide: 1,
        slidesPerView: self.slidesPerView,//一页显示几个
        spaceBetween: 10,//间隔
        updateOnWindowResize: true,
        watchSlidesProgress: true,//
        noSwiping: true,//
        effect: 'coverflow', //设置Slide的切换效果,默认为"slide"(普通位移切换),还可设置为"fade"(淡入)、"cube"(方块)、"coverflow"(3d流)、"flip"(3d翻转)、"cards"(卡片式)、"creative"(创意性)。
        freeMode: 1,
        autoplay: {//自动轮播//
          delay: 3000, //
          disableOnInteraction: false,//操作swiper后 自动轮播不会停止//
        },
        navigation: {
          nextEl: '.swiper-button-next',
          prevEl: '.swiper-button-prev',
        },
      }
      this.initStatus = true //渲染swiper
    })
  },
}
</script>
<style lang="scss" scoped>
.swiper {
  margin-left: auto;
  margin-right: auto;
  position: relative;
  box-sizing: border-box;
}
.swiper-wraper {
  width: 100%;
  height: 100%;
  z-index: 1;
  display: flex;
  box-sizing: content-box;
}
.swiper-slide {
  flex-shrink: 0;
  width: 100%;
  height: 100%;
}
.swiper-slide-imgbox{
  width: 315px;
  height: 302px;
  opacity: 1;
  background: rgba(255, 255, 255, 1);
  padding: 20px;
  box-sizing: border-box;
}
.pr{
  position: relative;
}
.txt-box{
  position: absolute;
  bottom: -40px;
  left: 0;
  right: 0;
  margin: 0 auto;
}
</style>

在plugins下引入

// 引入vue 及 组件
import Vue from 'vue'
import VueSwiper from '@/components/VueSwiper'

// 全局注册组件
Vue.component('VueSwiper', VueSwiper)

然后是使用这个组件,在pages下新建一个honor.vue

<template>
  <div class="main-container">
    <PageHeader />

    <!-- banner -->
    <div class="banner-box">
      <div class="font48 weight700 c3">资质与荣誉</div>
      <div class="font16 weight400 c7 op7 mt30">Qualifications and Honors</div>
    </div>

    <div class="content-box" v-for="(honorItem, index) in honorTypes" :key="index">
      <div class="font36 pt100 mb40 vc" v-if="honorInfo[index] && honorInfo[index].value && honorInfo[index].value.length">{{ honorItem.title }}</div>
      <div class="review-content" v-if="honorInfo[index] && honorInfo[index].value && honorInfo[index].value.length">
        <vue-swiper :list="honorInfo[index]" :slidesPerView="3"></vue-swiper>
      </div>
    </div>

    <PageFooter />
  </div>
</template>

<script>
import { shareToWechat } from "../../utils/format";
export default {
  name: "Honor",

  data() {
    return {
      showType: "honor",
      honorTypes: [],
      honors: [],
      honorInfo: []
    };
  },

  methods:{
    async findHonorTypeData() {
      let _params = {
        order: 'sort'
      }
      this.loading = true;
      const res = await this.$axios.$get("/certType", { params: _params });
      this.loading = false;
      let _this = this
      if (res && res.status === 0) {
        this.honorTypes = res.result
        res.result.forEach((item, i) => {
          _this.findHonorsData(item.title)
        })
      } else {
        this.$message.error(res.message);
      }
    },

    async findHonorsData(certType) {
      let _params = {
        order: 'sort',
        certType: certType,
        pageNum: 1,
        pageSize: 30
      }
      this.loading = true;
      const res = await this.$axios.$get("/certList", { params: _params });
      this.loading = false;
      let _this = this
      if (res && res.status === 0) {
        res.result.rows.forEach((item, i) => {
          item.imageUrl = `/images${item.imageUrl}`
        })
        let _obj = {
          name: certType,
          value: res.result.rows
        }
        _this.honorInfo.push(_obj)
      } else {
        this.$message.error(res.message);
      }
    },
  },

  mounted () {
    this.findHonorTypeData()
  }
};
</script>

<style lang="scss" scoped>
.content-box{
  background-color: rgba(239, 241, 244, 1);
  padding-bottom: 100px;
}
.review-content {
  width: 100%;
  height: 302px;
  position: relative;
  margin: 0 auto;
  .swiperBox {
    height: 360px;
    width: 100%;
    position: static;
    padding-top: 20px;
    & /deep/ {
      .swiper-slide {
        text-align: center;
        font-size: 18px;
        background: #fff;
        width: 315px !important;
        height: 302px;/* Center slide text vertically */
        display: -webkit-box;
        display: -ms-flexbox;
        display: -webkit-flex;
        display: flex;
        -webkit-box-pack: center;
        -ms-flex-pack: center;
        -webkit-justify-content: center;
        justify-content: center;
        -webkit-box-align: center;
        -ms-flex-align: center;
        -webkit-align-items: center;
        align-items: center;
        transition-property: all;
        img {
          max-width: 295px;
          height: auto;
          max-height: 282px;
          border-radius: 2px;
        }
        .swiper-slide-shadow-left{
          background-image: none
        }
        .swiper-slide-shadow-right{
          background-image: none
        }
      }
      .swiper-slide-active {
        .mask {
          display: none;
        }
      }
      .swiper-button-prev,.swiper-button-next {
        position: absolute;
        width: 34px;
        height: 64px;
        line-height: 64px;
        border-radius: 6px;
        font-size:30px;
        color: #00A2FF;
        top: 50%;
      }
      .swiper-button-prev:after,.swiper-button-next:after {
        font-size: 30px;
        &:hover{
          background-color: none;
        }
      }
      .swiper-button-prev {
        left: 0px;
      }
      .swiper-button-next {
        right: 0px;
      }
      .swiper-button-prev:hover,.swiper-button-next:hover {
        background: rgba(209, 209, 209, 0.5);
        color: rgba(255, 255, 255, 0.5);
      }
    }
  }
}
.banner-box {
  height: 370px;
  opacity: 1;
  padding: 172px 120px 0 120px;
  box-sizing: border-box;
  background: url(/images/productImages/honor.png) right 120px bottom 20px / 320px auto no-repeat,linear-gradient(90deg, rgba(137, 247, 254, 1) 0%, rgba(84, 156, 252, 1) 100%);;
}
.honor-box {
  max-width: 990px;
  padding-bottom: 82px;
  margin: 0 auto;
  & .honor-card {
    width: 300px;
    margin: 0 15px 48px;
    box-shadow: 0px 4px 8px rgba(0, 0, 0, 0.16);
    border-radius: 4px;
    background-clip: content-box;
    background-color: rgba(255, 255, 255, 1);
    background-position: center center;
    background-size: 100% auto;
    background-repeat: no-repeat;
    &.large {
      padding: 32px;
    }
    &.small {
      padding: 19px 15px;
    }
  }
}
@media screen and (max-width: 768px) {
  .banner-box {
    height: 260px;
    background-position: center top 100px, left top;
    background-size: auto 80px, auto 100%;
    & .banner-content {
      top: 260px;
      width: 100%;
    }
  }
  .honor-box {
    justify-content: center;
    padding: 0 30px 20px;
    & .honor-card {
      width: 300px;
      margin: 0 15px 20px;
    }
  }
}
</style>

出现空白页的bug

使用了swiper的coverflowEffect效果,设置了同时显示3个,同时开启了loop模式。

当切换到倒数第二张时没有新的slider生成,导致最后一张的右边是空白的,只有切换到最后一张时才会再在后面复制新的slider,怎么让它在显示倒数第二张时就生成新的slider?

image.png

最后发现slidesPerView设置为auto,就正常了

然后调整coverflowEffect里的stretch和depth来弄就没问题了

VueSwiper.vue

<template>
  <div v-if="initStatus" v-swiper:mySwiper="swiperOption" class="swiper mySwiper swiperBox">
    <div class="swiper-wrapper">
      <div class="swiper-slide" v-for="(item, index) in list.value" :key="index">
        <div class="pr">
          <div class="swiper-slide-imgbox uf uf-ac uf-jc">
            <img :src="item.imageUrl" />
          </div>
          <div class="font12 c8 txt-box">{{ item.title }}</div>
        </div>
      </div>
    </div>
    <div class="swiper-button-prev"></div>
    <div class="swiper-button-next"></div>
  </div>
</template>
<script>
export default {
  props: {
    list: {//banner数组
      type: Object,
      default: function () {
        return {}
      }
    }
  },
  data() {
    return {
      initStatus: false,//初始化状态
      swiperOption: {},//swiper参数
    }
  },
  mounted() {
    let self = this;
    this.$nextTick(() => {
      this.swiperOption = {
        loop: true,
        loopAdditionalSlides: 3,
        coverflowEffect: {
          rotate: 50, //侧转角度(正值凹陷)
          stretch: -110,//每个slide之间拉伸值(正值紧贴)
          depth: 100,  //值越大为远景(可负值)
          modifier: 1, //depth和rotate和stretch的倍率
          shadows: false
       },
        centeredSlides: true,
        initialSlide: 1,
        slidesPerView: 'auto',//一页显示几个
        spaceBetween: 10,//间隔
        updateOnWindowResize: true,
        watchSlidesProgress: true,//
        noSwiping: true,//
        effect: 'coverflow', //设置Slide的切换效果,默认为"slide"(普通位移切换),还可设置为"fade"(淡入)、"cube"(方块)、"coverflow"(3d流)、"flip"(3d翻转)、"cards"(卡片式)、"creative"(创意性)。
        freeMode: 1,
        autoplay: {//自动轮播//
          delay: 3000, //
          disableOnInteraction: false,//操作swiper后 自动轮播不会停止//
        },
        navigation: {
          nextEl: '.swiper-button-next',
          prevEl: '.swiper-button-prev',
        },
      }
      this.initStatus = true //渲染swiper
    })
  },
}
</script>
<style lang="scss" scoped>
.swiper {
  margin-left: auto;
  margin-right: auto;
  position: relative;
  box-sizing: border-box;
}
.swiper-wraper {
  width: 100%;
  height: 100%;
  z-index: 1;
  display: flex;
  box-sizing: content-box;
}
.swiper-slide {
  flex-shrink: 0;
  width: 100%;
  height: 100%;
}
.swiper-slide-imgbox{
  width: 315px;
  height: 302px;
  opacity: 1;
  background: rgba(255, 255, 255, 1);
  padding: 20px;
  box-sizing: border-box;
}
.pr{
  position: relative;
}
.txt-box{
  position: absolute;
  bottom: -40px;
  left: 0;
  right: 0;
  margin: 0 auto;
}
</style>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/435856.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

在 SpringBoot3 中使用 Mybatis-Plus 报错

在 SpringBoot3 中使用 Mybatis-Plus 报错 Property ‘sqlSessionFactory’ or ‘sqlSessionTemplate’ are required Caused by: java.lang.IllegalArgumentException: Property sqlSessionFactory or sqlSessionTemplate are requiredat org.springframework.util.Assert.no…

C语言如何设置随机数

本期介绍&#x1f356; 主要介绍&#xff1a;在C语言中如何创建一个随机数。 文章目录 1. rand函数2. srand函数3. time函数4. 设置随机数的范围 1. rand函数 想要生成随机数&#xff0c;就需要用到C语言提供的一个库函数叫rand&#xff0c;这个函数可以生成0~32767范围内的随机…

Ubuntu/Linux系统下Redis的基本操作命令

版本查询 redis-server --version # 或者redis-server -v 如上图所示&#xff0c;redis-server的版本为6.0.9,证明redis已经安装完成。 启动Redis服务 启动命令如下&#xff1a; redis-server启动成功如下所示&#xff1a; 启动过程中遇到如下问题时&#xff0c;杀死指定端…

可调恒定电流稳压器NSI50150ADT4G车规级LED驱动器 提供专业的汽车级照明解决方案

NSI50150ADT4G产品概述&#xff1a; NSI50150ADT4G可调恒定电流稳压器 (CCR) &#xff0c;是一款简单、经济和耐用的器件&#xff0c;适用于为 LED 中的调节电流提供成本高效的方案&#xff08;与恒定电流二极管 CCD 类似&#xff09;。该 (CCR) 基于自偏置晶体管 (SBT) 技术&…

波奇学Linux:信号的发送和保存

信号的发送的对象是pcb task_struct{ int signal; //0000 0000 .... 0001 进程pcb中存在int型的signal来保存信号&#xff0c;用位图的方式&#xff0c;比特位的0&#xff0c;1表示是否收到信号 比特位位置表示信号的编号。 发信号的本质就是修改task_struct的信号位图对应的…

Android 日志原理解析

一、Logcat 二、Dumpsys C:\Users\pengcheng.ding>adb shell dumpsys --help usage: dumpsysTo dump all services. or:dumpsys [-t TIMEOUT] [--priority LEVEL] [--clients] [--dump] [--pid] [--thread] [--help | -l | --skip SERVICES | SERVICE [ARGS]]--help: show…

学生护眼台灯哪种好?揭秘央视公认好用的护眼台灯

现在近视已经成为了普遍的现象&#xff0c;尤其是学生群体&#xff0c;究其原因主要还是长期是电子设备、长时间的用眼疲劳以及不合适的用光环境&#xff0c;很多时候我们不经意的错误习惯都会导致不知不觉中近视。尤其是桌面上的那一盏台灯&#xff0c;如果台灯的质量太差也是…

Java批量操作文件系统

一、实验内容 编写一个文件管理器&#xff0c;实现文件的批量操作。文件管理器具体功能要求如下&#xff1a; 1、用户输入指令1&#xff0c;代表“指定关键字检索文件”&#xff0c;此时需要用户输入检索的目录和关键字&#xff0c;系统在用户指定的目录下检索出文件名中包含…

DataGrip(IDEA 内置)连接 SQL Server

原文&#xff1a;https://blog.iyatt.com/?p14265 测试环境&#xff1a; IDEA 2023.1SQL Server 2022 首先打开 SQL Server 配置管理工具 启用 TCP/IP 打开 Windows 服务管理 在服务列表中找到 SQL Server&#xff08;MSSQLSERVER&#xff09;&#xff0c;右键重新启…

PostgreSQL 安装部署

文章目录 一、PostgreSQL部署方式1.Yum方式部署2.RPM方式部署3.源码方式部署4.二进制方式部署5.Docker方式部署 二、PostgreSQL部署1.Yum方式部署1.1.部署数据库1.2.连接数据库 2.RPM方式部署2.1.部署数据库2.2.连接数据库 3.源码方式部署3.1.准备工作3.2.编译安装3.3.配置数据…

Android视角看鸿蒙第一课(工程目录)

Android视角看鸿蒙第一课&#xff08;工程目录&#xff09; 导读 鸿蒙马上就来了&#xff0c;这个工作很有可能落到Android开发的头上&#xff0c;既是机遇也是挑战&#xff0c;希望能跟上时代的浪潮&#xff0c;迫不得已开始学习鸿蒙开发&#xff0c;顺带分享记录下 我的学…

新书速览|PyTorch语音识别实战(人工智能技术丛书)

实战语音唤醒、音频特征抽取、语音情绪分类、Whisper语音转换、鸟叫多标签分类、多模态语音文字转换 01 本书内容 《PyTorch语音识别实战》使用PyTorch 2.0作为语音识别的基本框架&#xff0c;循序渐进地引导读者从搭建环境开始&#xff0c;逐步深入到语音识别基本理论、算法以…

解决QMYSQL driver not loaded问题

前言 之前都是在Qt5.51上开发&#xff0c;连接mysql数据库一直没有问题&#xff0c;换到5.15.2后一直报错 一查才发现\5.15.2\msvc2019_64\plugins\sqldrivers目录下没有qsqlmysql了&#xff0c;5.5.1是有的&#xff0c;5.15.2是要自己编译的。。。 下载源码 安装qt的时候没…

阿里云游戏访问与下载加速解决方案

随着全球化的发展&#xff0c;越来越多的企业开始将业务扩展到海外市场。然而&#xff0c;海外市场的挑战也是显而易见的。例如在游戏企业进军海外市场的过程中&#xff0c;网络延迟是一个常见的问题。由于地理位置的限制&#xff0c;海外用户登录访问游戏和游玩时&#xff0c;…

阿里云服务器Ngnix配置SSL证书开启HTTPS访问

文章目录 前言一、SSL证书是什么&#xff1f;二、如何获取免费SSL证书三、Ngnix配置SSL证书总结 前言 很多童鞋的网站默认访问都是通过80端口的Http服务进行访问&#xff0c;往往都会提示不安全&#xff0c;很多人以为Https有多么高大上&#xff0c;实际不然&#xff0c;他只是…

虚拟机时间同步主机

1.查看是否设置同步 2.查看时区 date -R 0800 表示时区东八区 明显不对 执行指令&#xff1a; tzselect &#xff1b;找到亚洲-中国-北京 3.覆盖一下文件 复制文件到 /etc/localtime 目录下&#xff1a;#sudo cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime 4.重现查…

html css 导航栏 2

鼠标划过会向上移动改变颜色 html文件 <!DOCTYPE html> <html><head><meta charset"UTF-8"><title>导航栏</title><link rel"stylesheet" href"css/dhl1.css" /></head><body><div …

MongoDB系列之索引

索引 一、创建1、普通索引2、唯一索引3、复合索引二、查看三、删除四、执行计划explain五、TTL索引存在一张articles集合 一、创建 1、普通索引 db.articles.ensureIndex({name:1}) // 普通索引,1代表升序,-1代表倒序_id是默认索引 2、唯一索引 db.articles.ensureInde…

【JavaEE】_Spring MVC 项目单个及多个参数传参

目录 1. 传递单个参数 1.1 关于参数名的问题 2. 传递多个参数 2.1 关于参数顺序的问题 2.2 关于基本类型与包装类的问题 1. 传递单个参数 现创建Spring MVC项目&#xff0c;.java文件内容如下&#xff1a; package com.example.demo.controller;import org.springframewo…

NFTScan :什么是 ERC-404?深入解读 NFT 协议的未来

上月初&#xff0c;ERC-404 成为最首要热门的话题&#xff0c;ERC-404 是由 Pandora 团队在 2 月初为创作者和开发者等开源的实验性代币标准&#xff0c;其混合 ERC-20 / ERC-721 实现&#xff0c;具有原生流动性和碎片化等特点。伴随着早期的发展&#xff0c;越来越多参与者开…