ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

Vue图片轮播组件实例代码

2021-04-16 12:32:46  阅读:170  来源: 互联网

标签:index Vue return 轮播 slide nowIndex 组件


必备知识:http://github.crmeb.net/u/defu

写轮播页面:HTML+CSS
vue-cli:创建项目
Vue基础:模板语法、计算属性、侦听器、渲染方式(条件渲染、列表渲染)、组件
深入组件:组件注册、父子组件的交互方式、自定义事件
vue过渡:进入、离开过渡
CSS动画:CSS3 transfrom 属性
效果图:
在这里插入图片描述

组件构成:

利用Html 和 CSS 写一个基本的图片轮播页面
这部分很简单吧,常规的显示图片及轮播数字下标。CSS按照自己喜欢的样式随便调整。(最后面会给出我写的完整的CSS样式)

<!-- 布局 -->
<template>
  <div class="slide-show">
    <div class="slide-img" >
      <a href="" >
          <img src="" alt="">
      </a>
    </div>
    <h3>{{ title }}</h3>
    <ul class="slide-page" >
      <li>&lt;</li>
      <li>
        <a href="">1</a>
        <a href="">2</a>
        <a href="">3</a>
      </li>
      <li>&gt;</li>
    </ul>
  </div>
</template>

加入响应式的数据驱动
(1)引入数据:

我这里轮播了三张图,需要多一点轮播的,直接加在data中。将轮播的三组数据放在sildes数组中。

我们父组件中的数据:

Tips: 这里加载图片的路径必须使用require引入,方便webpack打包。

  data(){  
    return{
      slides:[
        {
          src:require('../assets/slide1.jpg'),
          title:"男人帮特色",
          href:'detail/****'
        },
        {
          src:require('../assets/slide2.jpg'),
          title:"女神养成计划",
          href:'detail/###'
        },
        {
          src:require('../assets/slide3.jpg'),
          title:"有腔调的品味",
          href:'detail/###'
        }
      ]
}

(2)数据驱动

依据slide数组,利用v-for列表渲染,v-bind绑定img的src等

随着nowIndex的动态变化显示不同的图片,在nowIndex初始化为0
在这里插入图片描述

(3)添加点击翻页等事件:左右箭头点击上下翻页、点击数字切换到相应的图片

在methods中定义跳转方法goto(index),跳转到index索引图片页

 goto(index){
     this.nowIndex = index
    }

所以 上翻页只需要修改传入的参为preIndex,依据当前的index决定上翻页的Index,(第一页的上翻页为最后一页,考虑循环),所以这里利用计算属性computed;同理,下翻页。
在这里插入图片描述

computed:{
    preIndex(){
      if(this.nowIndex == 0){
        return this.slides.length-1
      }else{
        return this.nowIndex - 1
      }
    },
    nextIndex(){
      if(this.nowIndex == this.slides.length-1){
        return 0
      }else{
        return this.nowIndex + 1
      }
    }
  }

(4)图片自动轮播

使用javascript的setInterval方法实现间隔10ms自动轮播 。指定的时间间隔重复执行代码。(鼠标放在图片上,需要停止动画效果,所以需要利用clearInterval()清除效果)

事件间隔在父级组件指定(v-bind绑定),利用props接收来自父级的数据

runInv需要在加载后调用,利用生命周期中的mounted实现调用

mounted:在模板渲染成html后调用,通常是初始化页面完成后,再对html的dom节点进行一些需要的操作。

  props:{
    slides:{
      type:Array,
      default:[]//初始值为空
    },
    inv:{//父级传递
      type:Number,
      default:1000
    }
  },
methods:{
    //幻灯片自动切换
    runInv(){
      this.invId = setInterval(()=>{
        this.goto(this.nextIndex)
      },this.inv)
    },
    clearInv(){
      clearInterval(this.invId)
    }
  },
  mounted(){
    this.runInv()
  }

定义动画
上面的轮播有点生硬,所以我们加上vue过渡效果。

有某一时刻是同时存在两张照片的(CSS中利用overflow:hidden隐藏溢出的图片),所以有两个标签,利用v-if条件渲染让只有一个图片出现

<transition name="slide-trans">
  <img v-if="isShow" :src="slides[nowIndex].src" alt="slides[nowIndex].title">
</transition>
<transition name="slide-trans-old">
  <img v-if="!isShow" :src="slides[nowIndex].src" alt="slides[nowIndex].title">
</transition>
.slide-trans-enter-active{
  transition: all 1s;
}
.slide-trans-enter{
  transform: translateX(1200px);
}
.slide-trans-old-leave-active{
    transition: all 1s;
    transform: translateX(-1200px);
}

vue组件完整代码:

<!-- 布局 -->
<template>
  <div class="slide-show" @mouseover="clearInv" @mouseout="runInv">
    <!-- v-for="item in slides" -->
    <div class="slide-img" >
      <a :href="slides[nowIndex].href" >
 
        <!-- 动画 -->
        <transition name="slide-trans">
          <img v-if="isShow" :src="slides[nowIndex].src" alt="slides[nowIndex].title">
        </transition>
        <transition name="slide-trans-old">
          <img v-if="!isShow" :src="slides[nowIndex].src" alt="slides[nowIndex].title">
        </transition>
 
        
      </a>
    </div>
    <h3>{{ slides[nowIndex].title }}</h3>
 
    <ul class="slide-page" >
      <li @click="goto(preIndex)">&lt;</li>
      <li v-for="(item,index) in slides" @click="goto(index)">
        <a href="" :class="{on:index == nowIndex}">{{index + 1}}</a>
      </li>
      <li @click="goto(nextIndex)">&gt;</li>
    </ul>
  </div>
</template>
<script>
export default {
  // props:子组件接受的什么属性
  props:{
    slides:{
      type:Array,
      default:[]//初始值为空
    },
    inv:{//父级传递
      type:Number,
      default:1000
    }
  },
  data(){
    return{
      nowIndex:1,
      isShow:true
    }
  },
  computed:{
    preIndex(){
      if(this.nowIndex == 0){
        return this.slides.length-1
      }else{
        return this.nowIndex - 1
      }
    },
    nextIndex(){
      if(this.nowIndex == this.slides.length-1){
        return 0
      }else{
        return this.nowIndex + 1
      }
    }
  },
  methods:{
    goto(index){
      this.isShow = false
      setTimeout(()=>{
        this.isShow = true
        this.nowIndex = index
        //index传给父组件,实现交互
        // this.$emit('onchange',index)
        //
      },10)
    },
    //幻灯片自动切换
    runInv(){
      this.invId = setInterval(()=>{
        this.goto(this.nextIndex)
      },this.inv)
    },
    clearInv(){
      clearInterval(this.invId)
    }
  },
  mounted(){
    this.runInv()
  }
}
</script>
<style scoped>
.slide-trans-enter-active{
  transition: all 1s;
}
.slide-trans-enter{
  transform: translateX(1200px);
}
.slide-trans-old-leave-active{
    transition: all 1s;
    transform: translateX(-1200px);
}
/* 淘宝css初始化 */
body, h1, h2, h3, h4, h5, h6, hr, p, blockquote, dl, dt, dd, ul, ol, li, pre, form, fieldset, legend, button,
  input, textarea, th, td { margin:0; padding:0; }
  body, button, input, select, textarea { font:12px/1.5tahoma, arial, \5b8b\4f53; }
  h1, h2, h3, h4, h5, h6{ font-size:100%; }
  address, cite, dfn, em, var { font-style:normal; }
  code, kbd, pre, samp { font-family:couriernew, courier, monospace; }
  small{ font-size:12px; }
  ul, ol { list-style:none; }
  a { text-decoration:none; }
  a:hover { text-decoration:underline; }
  sup { vertical-align:text-top; }
  sub{ vertical-align:text-bottom; }
  legend { color:#000; }
  fieldset, img { border:0; }
  button, input, select, textarea { font-size:100%; }
  table { border-collapse:collapse; border-spacing:0; }
 
 
.slide-show{
  height: 400px;
  width: 1200px;
  position: relative;
  overflow: hidden;
}
.slide-show h3{
  width: 100%;
  position: absolute;
  color: #fff;
  background-color: #000;
  opacity: 0.7;
  bottom: 0px;
  padding: 10px 0px;
  text-indent: 20px;
  font-weight: 500;
}
.slide-img img{
  width: 1200px;
  position: absolute;
  top: 0;
}
.slide-page{
  right: 15px;
  bottom: 0px;
  position: absolute;
}
.slide-page .on{
  text-decoration: underline;
}
.slide-page li{
  list-style: none;
  float: left;
  display: inline-block;
  padding: 0 10px;
  cursor: pointer;
  color: #fff;
  font-size: 14px;
  height: 32px;
}
.slide-page li a{
 
  display: block;
  float:left;
  color: #fff;
  text-decoration: none;
}
.slide-page li:hover{
  color: #1fdd88;
}
.slide-page a:hover{
  color: #1fdd88;
}
</style>

标签:index,Vue,return,轮播,slide,nowIndex,组件
来源: https://blog.csdn.net/qq_39221436/article/details/115754178

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有