Vue——图片轮播组件

灰太狼 2022-03-01 02:38 997阅读 0赞

Notices: 这是我一个项目中的一个子组件,要展示的数据、图片地址等的都在父组件data中。所以后面的讲述都是基于从父组件获取的参数进行处理。(如需将这个SlideShow写成一个单独的主组件,将本文使用的data写在这个组件的data中)

必备知识:

  1. 写轮播页面:HTML+CSS
  2. vue-cli:创建项目
  3. Vue基础:模板语法、计算属性、侦听器、渲染方式(条件渲染、列表渲染)、组件
  4. 深入组件:组件注册、父子组件的交互方式、自定义事件
  5. vue过渡:进入、离开过渡
  6. CSS动画:CSS3 transfrom 属性

效果图:

20190321152246492.gif

组件构成:

  • 利用Html 和 CSS 写一个基本的图片轮播页面

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

  1. <!-- 布局 -->
  2. <template>
  3. <div class="slide-show">
  4. <div class="slide-img" >
  5. <a href="" >
  6. <img src="" alt="">
  7. </a>
  8. </div>
  9. <h3>{
  10. { title }}</h3>
  11. <ul class="slide-page" >
  12. <li><</li>
  13. <li>
  14. <a href="">1</a>
  15. <a href="">2</a>
  16. <a href="">3</a>
  17. </li>
  18. <li>></li>
  19. </ul>
  20. </div>
  21. </template>
  • 加入响应式的数据驱动

(1)引入数据:

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

我们父组件中的数据:

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

  1. data(){
  2. return{
  3. slides:[
  4. {
  5. src:require('../assets/slide1.jpg'),
  6. title:"男人帮特色",
  7. href:'detail/****'
  8. },
  9. {
  10. src:require('../assets/slide2.jpg'),
  11. title:"女神养成计划",
  12. href:'detail/###'
  13. },
  14. {
  15. src:require('../assets/slide3.jpg'),
  16. title:"有腔调的品味",
  17. href:'detail/###'
  18. }
  19. ]
  20. }

(2)数据驱动

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

随着nowIndex的动态变化显示不同的图片,在nowIndex初始化为0

watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzI3ODU1MjE5_size_16_color_FFFFFF_t_70

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

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

  1. goto(index){
  2. this.nowIndex = index
  3. }

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

20190321173716566.png

  1. computed:{
  2. preIndex(){
  3. if(this.nowIndex == 0){
  4. return this.slides.length-1
  5. }else{
  6. return this.nowIndex - 1
  7. }
  8. },
  9. nextIndex(){
  10. if(this.nowIndex == this.slides.length-1){
  11. return 0
  12. }else{
  13. return this.nowIndex + 1
  14. }
  15. }
  16. }

(4)图片自动轮播

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

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

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

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

  1. props:{
  2. slides:{
  3. type:Array,
  4. default:[]//初始值为空
  5. },
  6. inv:{//父级传递
  7. type:Number,
  8. default:1000
  9. }
  10. },
  11. methods:{
  12. //幻灯片自动切换
  13. runInv(){
  14. this.invId = setInterval(()=>{
  15. this.goto(this.nextIndex)
  16. },this.inv)
  17. },
  18. clearInv(){
  19. clearInterval(this.invId)
  20. }
  21. },
  22. mounted(){
  23. this.runInv()
  24. }
  • 定义动画

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

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

  1. <!-- 动画 -->
  2. <transition name="slide-trans">
  3. <img v-if="isShow" :src="slides[nowIndex].src" alt="slides[nowIndex].title">
  4. </transition>
  5. <transition name="slide-trans-old">
  6. <img v-if="!isShow" :src="slides[nowIndex].src" alt="slides[nowIndex].title">
  7. </transition>
  8. .slide-trans-enter-active{
  9. transition: all 1s;
  10. }
  11. .slide-trans-enter{
  12. transform: translateX(1200px);
  13. }
  14. .slide-trans-old-leave-active{
  15. transition: all 1s;
  16. transform: translateX(-1200px);
  17. }

vue组件完整代码:

  1. <!-- 布局 -->
  2. <template>
  3. <div class="slide-show" @mouseover="clearInv" @mouseout="runInv">
  4. <!-- v-for="item in slides" -->
  5. <div class="slide-img" >
  6. <a :href="slides[nowIndex].href" >
  7. <!-- 动画 -->
  8. <transition name="slide-trans">
  9. <img v-if="isShow" :src="slides[nowIndex].src" alt="slides[nowIndex].title">
  10. </transition>
  11. <transition name="slide-trans-old">
  12. <img v-if="!isShow" :src="slides[nowIndex].src" alt="slides[nowIndex].title">
  13. </transition>
  14. </a>
  15. </div>
  16. <h3>{
  17. { slides[nowIndex].title }}</h3>
  18. <ul class="slide-page" >
  19. <li @click="goto(preIndex)"><</li>
  20. <li v-for="(item,index) in slides" @click="goto(index)">
  21. <a href="" :class="{on:index == nowIndex}">{
  22. {index + 1}}</a>
  23. </li>
  24. <li @click="goto(nextIndex)">></li>
  25. </ul>
  26. </div>
  27. </template>
  28. <script>
  29. export default {
  30. // props:子组件接受的什么属性
  31. props:{
  32. slides:{
  33. type:Array,
  34. default:[]//初始值为空
  35. },
  36. inv:{//父级传递
  37. type:Number,
  38. default:1000
  39. }
  40. },
  41. data(){
  42. return{
  43. nowIndex:1,
  44. isShow:true
  45. }
  46. },
  47. computed:{
  48. preIndex(){
  49. if(this.nowIndex == 0){
  50. return this.slides.length-1
  51. }else{
  52. return this.nowIndex - 1
  53. }
  54. },
  55. nextIndex(){
  56. if(this.nowIndex == this.slides.length-1){
  57. return 0
  58. }else{
  59. return this.nowIndex + 1
  60. }
  61. }
  62. },
  63. methods:{
  64. goto(index){
  65. this.isShow = false
  66. setTimeout(()=>{
  67. this.isShow = true
  68. this.nowIndex = index
  69. //index传给父组件,实现交互
  70. // this.$emit('onchange',index)
  71. //
  72. },10)
  73. },
  74. //幻灯片自动切换
  75. runInv(){
  76. this.invId = setInterval(()=>{
  77. this.goto(this.nextIndex)
  78. },this.inv)
  79. },
  80. clearInv(){
  81. clearInterval(this.invId)
  82. }
  83. },
  84. mounted(){
  85. this.runInv()
  86. }
  87. }
  88. </script>
  89. <style scoped>
  90. .slide-trans-enter-active{
  91. transition: all 1s;
  92. }
  93. .slide-trans-enter{
  94. transform: translateX(1200px);
  95. }
  96. .slide-trans-old-leave-active{
  97. transition: all 1s;
  98. transform: translateX(-1200px);
  99. }
  100. /* 淘宝css初始化 */
  101. body, h1, h2, h3, h4, h5, h6, hr, p, blockquote, dl, dt, dd, ul, ol, li, pre, form, fieldset, legend, button,
  102. input, textarea, th, td { margin:0; padding:0; }
  103. body, button, input, select, textarea { font:12px/1.5tahoma, arial, \5b8b\4f53; }
  104. h1, h2, h3, h4, h5, h6{ font-size:100%; }
  105. address, cite, dfn, em, var { font-style:normal; }
  106. code, kbd, pre, samp { font-family:couriernew, courier, monospace; }
  107. small{ font-size:12px; }
  108. ul, ol { list-style:none; }
  109. a { text-decoration:none; }
  110. a:hover { text-decoration:underline; }
  111. sup { vertical-align:text-top; }
  112. sub{ vertical-align:text-bottom; }
  113. legend { color:#000; }
  114. fieldset, img { border:0; }
  115. button, input, select, textarea { font-size:100%; }
  116. table { border-collapse:collapse; border-spacing:0; }
  117. .slide-show{
  118. height: 400px;
  119. width: 1200px;
  120. position: relative;
  121. overflow: hidden;
  122. }
  123. .slide-show h3{
  124. width: 100%;
  125. position: absolute;
  126. color: #fff;
  127. background-color: #000;
  128. opacity: 0.7;
  129. bottom: 0px;
  130. padding: 10px 0px;
  131. text-indent: 20px;
  132. font-weight: 500;
  133. }
  134. .slide-img img{
  135. width: 1200px;
  136. position: absolute;
  137. top: 0;
  138. }
  139. .slide-page{
  140. right: 15px;
  141. bottom: 0px;
  142. position: absolute;
  143. }
  144. .slide-page .on{
  145. text-decoration: underline;
  146. }
  147. .slide-page li{
  148. list-style: none;
  149. float: left;
  150. display: inline-block;
  151. padding: 0 10px;
  152. cursor: pointer;
  153. color: #fff;
  154. font-size: 14px;
  155. height: 32px;
  156. }
  157. .slide-page li a{
  158. display: block;
  159. float:left;
  160. color: #fff;
  161. text-decoration: none;
  162. }
  163. .slide-page li:hover{
  164. color: #1fdd88;
  165. }
  166. .slide-page a:hover{
  167. color: #1fdd88;
  168. }
  169. </style>

发表评论

表情:
评论列表 (有 0 条评论,997人围观)

还没有评论,来说两句吧...

相关阅读

    相关 vue组件

    写轮播组件的思路: 1、确定传入的参数:轮播图的数据(图片地址,跳转href,图片ID,标题等基础数据)、轮询时间 2、写好轮播图的基本样式,父组件传入参数,动态加载进

    相关 Vue——图片组件

    Notices: 这是我一个项目中的一个子组件,要展示的数据、图片地址等的都在父组件data中。所以后面的讲述都是基于从父组件获取的参数进行处理。(如需将这个SlideShow