Vue手写横向轮播图的实例

目录
  • Vue手写横向轮播图
  • Vue常见的轮播图

Vue手写横向轮播图

前提:自己封装的轮播图,暂时没测出bug~

效果如下图,一行三个,点击上一张/下一张 向前或向后移动一格,窗口缩放会适当变形,不影响切换

<template>
  <div class="swiper-template">
    <div class="my-swiper-page">
      <div class="page-left">
        <span>{{ activeIndex + 1 }}</span
        >/{{ swiperList.length }}
      </div>
    </div>
    <div class="my-swiper-container" v-show="swiperList.length">
      <div class="my-swiper-wapper">
        <div class="arrow imgLeft" @click="clickLeft">
          <span class="el-icon-arrow-left"></span>
        </div>
        <div class="arrow imgRight" @click="clickRight">
          <span class="el-icon-arrow-right"></span>
        </div>
        <div ref="swiperDom" class="my-swiper-content">
          <ul ref="swiperDomUI" :style="ulStyle">
            <li
              v-for="(item, index) in swiperList"
              :key="item.id"
              class=""
              :style="{ width: liWidth + 'px' }"
              ref="liDom"
              @click="changeIndex(item, index)"
            >
              <div
                class="introduce-li-box"
                :class="index === activeIndex ? 'active' : ''"
              >
                <div class="introduce-img"><img :src="item.url" /></div>
                <div class="introduce-name">{{ item.name }}</div>
              </div>
            </li>
          </ul>
        </div>
      </div>
    </div>
  </div>
</template>
<script>
export default {
  props: {
    swiperList: {
      type: Array,
      default: () => [
        {
          name: 'test1',
          url: 'https://alifei04.cfp.cn/creative/vcg/veer/1600water/veer-130182553.jpg',
          path: '/detail'
        },
        {
          name: 'test2',
          url: 'https://alifei04.cfp.cn/creative/vcg/veer/1600water/veer-130182553.jpg',
          path: '/detail'
        },
        {
          name: 'test3',
          url: 'https://alifei04.cfp.cn/creative/vcg/veer/1600water/veer-130182553.jpg',
          path: '/detail'
        },
        {
          name: 'test4',
          url: 'https://alifei04.cfp.cn/creative/vcg/veer/1600water/veer-130182553.jpg',
          path: '/detail'
        }
      ]
    }
  },
  data() {
    return {
      activeIndex: 0, // 当前移动图片的索引值
      boxWidth: 0,
      liWidth: 0,
      ulStyle: { left: 0 }
    }
  },
  computed: {},
  created() {},
  mounted() {
    this.getWidth()
    window.addEventListener('resize', this.getWidth)
  },
  methods: {
    changeIndex(item, index) {
      this.activeIndex = index
      this.$router.push(item.path)
    },
    getWidth() {
      this.boxWidth = this.$refs.swiperDom.offsetWidth
      this.liWidth = this.boxWidth / 3
      if (this.activeIndex * this.liWidth > this.boxWidth) {
        this.ulStyle = {
          left: -this.activeIndex * this.liWidth + 'px'
        }
      }
    },
    clickLeft() {
      if (this.activeIndex > 0) {
        this.activeIndex-- // 索引值-1
        let offsetLeft = this.activeIndex * this.liWidth + this.liWidth

        let ulLeft = this.$refs.swiperDomUI.offsetLeft
        let distance = 0

        if (ulLeft < 0) {
          if (offsetLeft <= this.boxWidth) {
            if (-ulLeft > this.boxWidth) {
              distance = Math.abs(ulLeft + this.boxWidth)
            } else {
              distance = -ulLeft
            }
          } else {
            distance = offsetLeft - this.boxWidth
            if (distance >= this.liWidth) {
              distance = this.liWidth
            } else {
              distance = distance
            }
          }

          let index = 0
          let temp = window.setInterval(() => {
            if (index < distance && ulLeft < 0) {
              index += 2 // 每次向右移动的距离
              this.ulStyle = { left: ulLeft + index + 'px' }
            } else {
              window.clearInterval(temp)
            }
          }, 10)
        }
      }
    },
    clickRight() {
      if (this.activeIndex < this.swiperList.length - 1) {
        this.activeIndex++
        let offsetLeft = this.activeIndex * this.liWidth + this.liWidth
        if (offsetLeft > this.boxWidth) {
          let ulLeft = Math.abs(this.$refs.swiperDomUI.offsetLeft)
          let distance = offsetLeft - this.boxWidth - ulLeft
          let index = 0
          let temp = window.setInterval(() => {
            if (index < distance) {
              index += 2 // 每次向右移动的距离
              this.ulStyle = { left: -(ulLeft + index) + 'px' }
            } else {
              window.clearInterval(temp)
            }
          }, 10)
        }
      }
    }
  },
  destroyed() {
    window.removeEventListener('resize', this.getWidth)
  }
}
</script>
<style lang="scss" scoped>
.swiper-template {
  .my-swiper-page {
    font-size: 16px;
    color: #bababa;
    width: 100%;
    margin: 50px auto;
    justify-content: space-around;
    .page-left {
      text-align: left;
      width: 50%;
      padding-left: 30px;
      box-sizing: border-box;
      span {
        font-size: 24px;
        color: #000000;
      }
    }
  }
  .my-swiper-container {
    width: 100%;
    height: 405px;
    .my-swiper-wapper {
      width: 100%;
      height: 100%;
      position: relative;
      padding: 0 30px;
      font-size: 16px;
      box-sizing: border-box;
      .arrow {
        display: inline-block;
        cursor: pointer;
        background: #fff;
        padding: 7px;
        &:hover {
          background: #c09d7b;
          color: #fff;
        }
      }
      .imgLeft {
        text-align: left;
        position: absolute;
        left: 0;
        top: 50%;
        transform: translateY(-50%);
      }
      .imgRight {
        text-align: right;
        position: absolute;
        right: 0;
        top: 50%;
        transform: translateY(-50%);
      }
      .my-swiper-content {
        width: 100%;
        height: 100%;
        position: relative;
        overflow: hidden;
        ul {
          width: auto;
          white-space: nowrap;
          position: absolute;
          left: 0;
          li {
            display: inline-block;
            padding: 0 8px;
            box-sizing: border-box;
            .introduce-li-box {
              width: 100%;
              height: 405px;
              box-sizing: border-box;
              cursor: pointer;
              text-align: center;
              .introduce-img {
                width: 100%;
                height: 360px;
                overflow: hidden;
                img {
                  height: 100%;
                  -webkit-transition: all 0.61s;
                  transition: all 0.6s;
                  &:hover {
                    transform: scale(1.2);
                    -webkit-transform: scale(1.2);
                  }
                }
              }
              .introduce-name {
                width: 100%;
                height: 45px;
                line-height: 45px;
                font-size: 16px;
                color: #1f1205;
                background: #ffffff;
              }
              &:hover {
                .introduce-name {
                  background: #c09d7b;
                  color: #fff;
                }
              }
              &.active {
                .introduce-name {
                  // background: #c09d7b;
                  // color: #fff;
                }
              }
            }
          }
        }
      }
    }
  }
}
</style>

Vue常见的轮播图

很多页面里,项目里,轮播图几乎是无处不在,今天我们就来说说轮播图的写法

在轮播图数组list中,定义一个变量listIndex = 0表示第一张图片,默认渲染第一张图片即list[listIndex],然后获取每张图片的下标。点击切换图片时把当前图片的下标赋值给listIndex即可实现图片切换显示。

展示代码

<template>
  <div class="home">
    <div class="box" @mouseout="out" @mouseover="over">
      <img
        v-for="(item, index) in list"
        v-show="listIndex === index"
        :key="index"
        :src="item"
        alt=""
      />
      <p class="left" @click="changePage(prevIndex)">&lt;</p>
      <ul>
        <li
          :class="{ color: index == listIndex }"
          v-for="(item, index) in list"
          @click="changePage(index)"
          :key="index"
        ></li>
      </ul>
      <p class="right" @click="changePage(nextIndex)">&gt;</p>
    </div>
  </div>
</template>
<script>
export default {
  components: {},
  props: {},
  data() {
    return {
      list: [
        require("../../public/image/1.jpg"),
        require("../../public/image/2.jpg"),
        require("../../public/image/3.jpg"),
        require("../../public/image/4.jpg"),
      ],
      listIndex: 0, //默认显示第几张图片
      timer: null, //定时器
    };
  },
  computed: {
    //上一张
    prevIndex() {
      if (this.listIndex == 0) {
        return this.list.length - 1;
      } else {
        return this.listIndex - 1;
      }
    },
    //下一张
    nextIndex() {
      if (this.listIndex == this.list.length - 1) {
        return 0;
      } else {
        return this.listIndex + 1;
      }
    },
  },
  methods: {

    changePage(index) {
      this.listIndex = index;
    },
    //移除
    out() {
      this.setTimer();
    },
    //移入
    over() {
      clearInterval(this.timer);
    },
    //1秒切图
    setTimer() {
      this.timer = setInterval(() => {
        this.listIndex++;
        if (this.listIndex == this.list.length) {
          this.listIndex = 0;
        }
      }, 1000);
    },
  },
  created() {
    //定时器
    this.setTimer();
  },
  mounted() {},
};
</script>
<style scoped lang="less">
.home {
  width: 100%;
  height: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
  .box {
    position: relative;
    width: 500px;
    height: 500px;
    img {
      width: 100%;
      height: 100%;
      z-index: 100;
    }
    p {
      cursor: pointer;
      color: white;
      font-size: 28px;
      display: flex;
      justify-content: center;
      align-items: center;
      width: 50px;
      height: 50px;
      background: rgba(0, 0, 0, 0.5);
    }
    .left {
      position: absolute;
      top: 50%;
      left: 0;
    }
    .right {
      position: absolute;
      top: 50%;
      right: 0;
    }
    ul {
      list-style: none;
      display: flex;
      justify-content: space-around;
      align-items: center;
      position: absolute;
      width: 150px;
      height: 20px;
      top: 90%;
      right: 35%;
      .color {
        background: red;
        color: red;
      }
      li {
        cursor: pointer;
        width: 10px;
        height: 10px;
        background: white;
        border-radius: 50%;
      }
    }
  }
}
</style>

以上为个人经验,希望能给大家一个参考,也希望大家多多支持我们。

(0)

相关推荐

  • vue实现轮播图片

    本文实例为大家分享了vue实现轮播图片的具体代码,供大家参考,具体内容如下 1.效果图 2.案例 <template>        <section class="body">            <section class="wrap">                <swiper :options="swiperOption" class="swiper-wrap"  re

  • Vue使用Swiper封装轮播图组件的方法详解

    目录 Swiper 为什么要封装组件 开始封装 1.下载安装Swiper 2.引入css样式文件 3.引入js文件 4.把官网使用方法中的HTML结构复制粘贴过来 5.初始化Swiper 自定义效果 完整代码 效果展示 Swiper Swiper是一个很常用的用于实现各种滑动效果的插件,PC端和移动端都能很好的适配. 官网地址:www.swiper.com.cn/ 目前最新版本是Swiper7,但众所周知最新版本通常不稳定,所以这里使用Swiper6来封装. Swiper各版本区别: 为什么要封

  • vue如何实现无缝轮播图

    目录 vue实现无缝轮播图 轮播图的思路 无缝轮播(跑马灯效果) vue实现无缝轮播图 轮播图的思路 一组图片进行不停地循环,如果循环到最后一张图片,就从第一张开始,不停循环,我们可以设置图片切换的时间. 1.首先我们先把我们需要用到的数据以数组的方式定义在data中,再定义一个当前显示在页面的图片的值,默认为0.   data() {     return {       v:0,       imglist:[         {"id":0,img:"/pics/pic

  • vue下的elementui轮播图自适应高度问题

    目录 elementui轮播图自适应高度 elementui轮播图自适应的最简单实现 效果如下 拉伸一下 elementui轮播图自适应高度 翻了下api 没有找到对应的属性,所以这里用自定义方法来实现 <el-carousel :interval="5000" arrow="never" :height="autoHeight">      <el-carousel-item v-for="(banner, inde

  • vue3+Pinia+TypeScript 实现封装轮播图组件

    目录 为什么封装? 静态结构 后面再进行更改 请求数据都存放在pinia里面 类型检测 页面级组件 全局组件 为什么封装? 迎合es6模块化开发思想 注册为全局组件,可以更好地复用,需要用到的地方,直接使用标签即可 静态结构 后面再进行更改 <script lang="ts" setup name="XtxCarousel"> defineProps() </script> <template> <div class=&qu

  • vue中使用swiper轮播图的正确姿势(亲测有效)

    目录 前言 1.新建vue项目 2.装swiper的包 3.使用swiper 总结 前言 网上搜了一大堆在vue中如何使用swiper,结果搜出来一堆垃圾,也不知道从哪里复制的,吐槽完毕.假设你是个新手,我从新建项目开始跟你讲,以下是步骤. 1.新建vue项目 vue create 项目名 然后选最下面那一个(键盘上下键操作)然后回车 选择Bable,Router,Vuex,Css-Processords四个,其他的不要选中(空格键是选中和取消选中) 剩下的步骤按这张图来进行选择,然后项目就创建

  • Vue手写横向轮播图的实例

    目录 Vue手写横向轮播图 Vue常见的轮播图 Vue手写横向轮播图 前提:自己封装的轮播图,暂时没测出bug~ 效果如下图,一行三个,点击上一张/下一张 向前或向后移动一格,窗口缩放会适当变形,不影响切换 <template> <div class="swiper-template"> <div class="my-swiper-page"> <div class="page-left"> <

  • vue利用better-scroll实现轮播图与页面滚动详解

    前言 better-scroll 也很强大,不仅可以做普通的滚动列表,还可以做轮播图.picker 等等...所以本文主要给大家介绍了关于vue用better-scroll实现轮播图与页面滚动的相关内容,分享出来供大家参考学习,下面话不多说了,来一起看看详细的介绍吧. 1.安装better-scroll 在根目录中package.json的dependencies中添加: "better-scroll": "^0.1.15" 然后 npm i 安装. 2.封装代码

  • vue仿携程轮播图效果(滑动轮播,下方高度自适应)

    先看案例,使用vue+swiper实现,slide不同高度时,动态计算盒子高度,让其下方高度自适应的效果 首先搭建vue项目,这里不做过多说明,然后安装swiper npm install swiper --save-dev 1. js部分:初始化swiper组件,vue要在mounted生命周期中进行初始化,代码如下: import Swiper from 'swiper' import { TweenMax, Power2 } from 'gsap' 初始化时调用resize函数,计算屏幕容

  • Vue Echarts实现图表轮播图以及图表组件封装和节流函数优化讲解

    目录 一.为什么要优雅的使用echarts 二.最初的表格组件 三.初步的封装 四.性能优化 一.为什么要优雅的使用echarts 为了提高代码的规范性.复用性,vue中最常用的就是将具有某些功能的代码封装到一个插件.如果没有对插件进行封装,在后期使用插件的时候效率会十分低下也不便于后期对程序的维护拓展,在优雅的使用echarts时,首先,我们考虑到多个地方需要用到echarts,就需要封装一个组件出来,由于每一个图中的属性均由配置项option进行控制,所以我们可以将option选项提取出来,

  • 纯JavaScript手写图片轮播代码

    废话不多说了,直接给大家贴js代码实现手写图片轮播的代码了,代码非常简单,具体代码如下所示: <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>js图片轮播切换</title> <style type="text/css"> .imgCon{width: 400px;height: 400px;border: 2p

  • JS实现横向轮播图(初级版)

    本文实例为大家分享了JS实现横向轮播图的具体代码,供大家参考,具体内容如下 描述: 轮播图,初级,横向buton或者底部数字控制轮播,可以实现自动轮播(注释了,使用的话将其注释消掉),核心知识是数据驱动图像的位移达到效果. 效果: 代码: js文件: /* * 工厂模式 * */ var Method=(function () { return { loadImage:function (arr,callback) { var img=new Image(); img.arr=arr; img.

  • JS实现横向轮播图(中级版)

    本文实例为大家分享了JS实现横向轮播图的具体代码,供大家参考,具体内容如下 描述: 轮播图,中级,横向buton或者底部数字控制轮播,可以实现自动轮播(注释了,使用的话将其注释消掉),解决了初级版本的点1再点5时多张图片滑动的问题,核心只有两张图在切换,加入了图片加载. 效果: 代码: js文件: /* * 工厂模式 * */ var Method=(function () { return { loadImage:function (arr,callback) { var img=new Im

  • JavaScript实现PC端横向轮播图

    本文实例为大家分享了JavaScript实现PC端横向轮播图的具体代码,供大家参考,具体内容如下 步骤: 第一步:先实现右侧按钮点击图片动起来: 1.每次点击图片走的距离: 2.起始位置已知,计算定时器每走一小步的距离: 第二步:判断点击按钮一次图片移动的距离,停止定时器: 第三步:左边按钮逻辑和右侧按钮几乎一致: 1.因此封装函数move(flag),函数传参是Boolean则是左右按钮方向 第四步:无缝轮播:html结构修改,在当前结构分别加第一张图和最后一张图: 1.判断图片位置,设置相应

随机推荐