首页 > 其他分享 >《VUE》走马灯组件

《VUE》走马灯组件

时间:2023-09-13 15:34:20浏览次数:30  
标签:style VUE indicator transform 组件 let 走马灯 carouselDom type

<template>
  <!-- 走马灯 -->
  <div class="box">
    <div class="carousel">
      <div class="item" v-for="(v,i) in list" :key="i" @click="open(v)">
        <img :src="v.img" alt="">
        <!-- 走马灯图中自定义内容 -->
        <slot :current="current"></slot>
      </div>
    </div>
    <div class="indicator" v-if="isIndicator">
      <span :class="{'active': current == i}" v-for="(v,i) in list" :key="i" @click="indicatorCheck(i)"></span>
    </div>
    <template v-if="isArrow">
      <div class="arrow_left" @click="arrowNext(1)"></div>
      <div class="arrow_right" @click="arrowNext(2)"></div>
    </template>
  </div>
</template>

 

<script>
  export default {
    props: {
      // 走马灯列表
      list: {
        type: Array,
        required: true,
        default: () => []
        // { img: require(''), link: '' }
      },
      // 是否显示下方指示点
      isIndicator: {
        type: Boolean,
        default: false
      },
      // 是否显示左右箭头
      isArrow: {
        type: Boolean,
        default: false
      },
      // 自动切换的时间间隔,单位为毫秒
      interval: {
        type: Number,
        default: 3000
      }
    },
    data() {
      return {
        current: 0,   // 当前在第几张图
        indicator: 1,
        timer: null,
      }
    },
    mounted() {
      this.init()
      this.autoRun()
    },
    destroyed() {
      clearInterval(this.timer)
    },
    methods: {
      // 初始化走马灯列表
      init() {
        let carouselDom = document.querySelector('.carousel')
        // 复制第一张图
        let first = carouselDom.firstElementChild.cloneNode(true)
        // 复制最后一张图
        let last = carouselDom.lastElementChild.cloneNode(true)
        // 将第一张图放在末尾
        carouselDom.appendChild(first)
        // 将最后一张图放在第一张
        carouselDom.insertBefore(last, carouselDom.firstElementChild)
        // 设置最后一张复制图为绝对定位
        last.style.position = "absolute"
        last.style.transform = "translateX(-100%)"
      },
      // 走马灯自动运行
      autoRun() {
        const _this = this
        if(_this.indicator >= _this.list.length) {
          _this.indicator = 0
        }
        this.timer = setInterval(() => {
          this.arrowNext(2)
          _this.indicator++
          if(_this.indicator >= _this.list.length) {
            _this.indicator = 0
          }
        }, this.interval)
      },
      // 下方指示器事件
      indicatorCheck(index) {
        let carouselDom = document.querySelector('.carousel')
        let count = this.list.length
        // 当前在最后一张图时,无缝切换到第一页
        if(this.current === count-1 && index === 0) {
          carouselDom.style.transform = "translateX(100%)"
          carouselDom.style.transition = 'none'
          carouselDom.clientHeight   // 强制渲染
          this.moveTo(0, 'move')
        } else {
          this.moveTo(index, 'move')
        }
      },
      // 走马灯左右箭头事件
      arrowNext(type) {
        let carouselDom = document.querySelector('.carousel')
        let count = this.list.length
        // 左箭头
        if(type==1) {
          // 当前是否在第一张图,无缝切换
          if(this.current === 0) {
            carouselDom.style.transform = `translateX(-${count}00%)`
            carouselDom.style.transition = 'none'
            carouselDom.clientHeight   // 强制渲染
            this.moveTo(count-1, 'move')
          } else {
            this.moveTo(this.current-1, 'move')
          }
        }
        // 右箭头
        if(type==2) {
          // 当前是否在最后一张图,无缝切换
          if(this.current === count-1) {
            carouselDom.style.transform = "translateX(100%)"
            carouselDom.style.transition = 'none'
            carouselDom.clientHeight   // 强制渲染
            this.moveTo(0, 'move')
          } else {
            this.moveTo(this.current+1, 'move')
          }
        }
      },
      moveTo(index, type) {
        if(type=='move') {
          clearInterval(this.timer)
          this.indicator = index+1
          this.autoRun()
        }
        this.current = index
        let carouselDom = document.querySelector('.carousel')
        carouselDom.style.transform = `translateX(-${index}00%)`
        carouselDom.style.transition = '.5s'
      },
      // 跳转
      open(v) {
        if(v.link) {
          window.open(v.link)
        }
      }
    }
  }
</script>

 

<style scoped lang="scss">
  .box{
    width: 100%;
    height: 700px;
    margin: 0 auto;
    overflow: hidden;
    position: relative;
    .carousel{
      width: 100%;
      display: flex;
      transform: translateX(-0%);
      .item{
        width: 100%;
        position: relative;
        > img{
          width: calc(100vw - 4px);
          // height: 700px;
          display: block;
        }
      }
    }
    .indicator{
      position: absolute;
      bottom: 200px;
      left: 50%;
      transform: translateX(-50%);
      display: flex;
      justify-content: center;
      span{
        display: block;
        width: 20px;
        height: 20px;
        border: 1px solid #ddd;
        border-radius: 50%;
        margin: 0 4px;
        cursor: pointer;
        &.active{
          background-color: #fff;
          border-color: #fff;
        }
      }
    }
    .arrow_left,
    .arrow_right{
      width: 30px;
      height: 30px;
      background-color: #ccc;
      position: absolute;
      top: 50%;
      transform: translateY(-50%);
      cursor: pointer;
    }
    .arrow_left{
      left: 300px;
    }
    .arrow_right{
      right: 300px;
    }
}
</style>

 

标签:style,VUE,indicator,transform,组件,let,走马灯,carouselDom,type
From: https://www.cnblogs.com/chensv/p/17699814.html

相关文章

  • application 'vueApp' died in status NOT_MOUNTED: [qiankun]: Target container wit
    这是第一次微前端很常见的提示,尤其是第一次写前端的时候碰到的解决1:主应用的 App.vue标签上的id="app"去掉,这是报错的根本解决2://在子应用挂在的时候处理functionrender(props={}){const{container}=props;instance=newVue({render:h=>h......
  • 【Vue】带你进入七彩缤纷的世界
    hello,我是小索奇,Vue.js精心准备撰写了文章,其中进行多次修改给读者更好的学习进程,涵盖Vue2和Vue3,让大家用最通俗的方式来学会Vue,本系列会考虑到新手,将由浅入深进行讲解,即使你是老玩家,也可以收藏备用,其中有很多已经踩过的坑为大家铺垫平滑的道路~若您有任何问题,欢迎沟通,共同进......
  • nvm、node、vue安装、vue项目创建打包
    nvm、node、vue安装、创建vue项目nvm作用:可以管理多个版本的node,切换node版本,下载node。前情提要参考:https://zhuanlan.zhihu.com/p/519270555下载地址:https://github.com/coreybutler/nvm-windows/releases一、常用命令1、nvm查看安装了的nodenvmlsnvml......
  • vue导出带样式的excel
    示例说明实现导出excel不同块的颜色templatea标签仅做文件名称调整,默认为隐藏状态;<template><div><button@click="exportExcel">导出</button><aref="export_a"/></div></template>scriptexportdefault{name......
  • Vue3语法基本使用
    1、watch使用watch(监听数据源,执行函数,[配置参数])//配置参数:立即执行深度监听{immediate:true,deep:true}1.1监听基本数据类型单一数据源<scriptsetup>import{ref,watch}from'vue'letname=ref('张麻子')//监听器watch(name,(new......
  • 解决vue中watch监听对象变化获取不到旧数据的问题
    解决vue中watch监听对象变化获取不到旧数据的问题1.问题代码watch:{pageInfo:{handler(newVal,oldVal){console.log(newVal,oldVal);},}}结果:打印出来newVal和oldVal输出内容一样console.log(newVal===oldVal)//true发现这......
  • Vue.set和splice方法有什么区别?
    Vue.set方法和splice方法在Vue中用于修改数组的行为有一些区别。一:Vue.set(obj,key,value):用途:Vue.set是Vue提供的全局方法,用于向响应式对象中添加新的响应式属性,并确保这个新属性是响应式的。参数:obj:要修改的目标对象。key:要添加的属性键名。value:要添加的属性值。示......
  • 从零开始使用vue2+element搭建后台管理系统(实现导出excel表格的功能)
    首先参阅了以下文档:https://panjiachen.gitee.io/vue-element-admin-site/zh/feature/component/excel.html#excel-%E5%AF%BC%E5%87%BAhttps://blog.csdn.net/weixin_42028153/article/details/124804841核心思想:抄一下vue-element-admin这个很棒的开源集成后台管理系统中所提......
  • VUE2教程-基础-Class 与 Style 绑定
    Class与Style绑定操作元素的class列表和内联样式是数据绑定的一个常见需求。因为它们都是attribute,所以我们可以用 v-bind 处理它们:只需要通过表达式计算出字符串结果即可。不过,字符串拼接麻烦且易错。因此,在将 v-bind 用于 class 和 style 时,Vue.js做了专门的增强......
  • VUE2基础-Vue实例
    Vue实例创建一个Vue实例 每个Vue应用都是通过用 Vue 函数创建一个新的 Vue实例开始的:varvm=newVue({//选项})虽然没有完全遵循 MVVM模型,但是Vue的设计也受到了它的启发。因此在文档中经常会使用 vm (ViewModel的缩写)这个变量名表示Vue实例。当创建......