当前位置:   article > 正文

用Vue实现一个简单的图片轮播_实现图片竖直方向的轮播,要求:包含控制移动方向的按钮,点击按钮移动方向发生对应

实现图片竖直方向的轮播,要求:包含控制移动方向的按钮,点击按钮移动方向发生对应

本文已收录至https://github.com/likekk/studyBlog欢迎大家star,共同学习,共同进步。如果文章有错误的地方,欢迎大家指出。后期将在将GitHub上规划前端学习的路线和资源分享。

写在前面

每一篇文章都希望您有所收获,每一篇文章都希望您能静下心来浏览、阅读。每一篇文章都是作者精心打磨的作品。

如果您觉得杨戬这个小白还有点东西的话,杨戬希望正在看文章的您可以帮忙点亮那个点赞的按钮(效果更加),对于杨戬这个暖男来说,真的真的非常重要,这将是我持续写作的动力。

前言

写这篇文章的目的主要是将以前所学的知识结合起来,进一步巩固一下自己的记忆,防止遗忘(主要是害怕老年痴呆),当然更重要的是学以致用,毕竟学过的东西不拿来用的话就会很容易忘记,永远不要太相信自己的记忆,编程这东西,几天不弄,忘的就很快,回过头再看,心里想着:这是我写的代码吗?本篇博客也是秉着这样的初心去写的。

整体分析

在我看来,我觉得做每一件事情都必须弄清楚这件事情的前因后果,当然了如果有是实在不太了解的,姑且可以先实现效果。

然后再返回去慢慢理解,不过我一般比较喜欢先分析整体结构,然后一步一步去实现,有些事情不可能做到尽善尽美的,不是吗?先上效果图吧!

这张图打了一波广告,我想你们应该不会介意的吧!不过说实话这里面的老师讲课真的是特别优秀,感兴趣的读者可以去尝试一下,毕竟暖男戬是不会骗人的。

本来想着弄一下轮播图的动态效果的,奈何不会弄,所以放弃了,静态的凑合看吧!

分析第一步

布局的话,一个是显示图片,另一个是显示小圆点,图片切换的时候,小圆点也随着切换,当切换到最后一张的时候图片重从第一张开始重新轮播。

分析第二步

我们需要明确哪些数据是需要通过外部传输,哪些数据是我们自己可以控制,从效果图分析主要的话是图片,当然控制小圆点也是可以的,我们知道vue是可以实现组件的复用的,那么对于轮播图而言,也可以实现其复用性。

例如:在其它地方我们也需要用到轮播图,但是轮播的图片不一样,轮播的速度不一样等等。

总结:分析哪些数据是可控的,哪些数据是不可控的。

分析第三步

这里主要是轮播整体的实现,鼠标经过,轮播停止,鼠标移出,轮播继续,点击小圆点,实现轮播。

涉及知识点

文章中轮播图的实现涉及的知识点我整理了一下,如果有知识点不太清楚的读者可以去了解相关的内容。

  • vue的父子组件通信
  • 静态资源的导入
  • v-if和v-for的使用
  • 事件处理
  • class和sytle绑定
  • Vue的生命周期
  • 组件的校验

轮播的实现

将步骤分析和涉及的知识点整理之后,一切应该都是游刃有余吧!那么我们一步一步实现轮播的效果。

界面布局

1、全局css样式引入

全局css样式,我已经会搭建准备好了,一个是reset.css,一个是global.css,静态图片资源放在了github上,大家可以自行下载

reset.css

  1/* http://meyerweb.com/eric/tools/css/reset/ 
2   v2.0 | 20110126
3   License: none (public domain)
4*/

5
6html,
7body,
8div,
9span,
10applet,
11object,
12iframe,
13h1,
14h2,
15h3,
16h4,
17h5,
18h6,
19p,
20blockquote,
21pre,
22a,
23abbr,
24acronym,
25address,
26big,
27cite,
28code,
29del,
30dfn,
31em,
32img,
33ins,
34kbd,
35q,
36s,
37samp,
38small,
39strike,
40strong,
41sub,
42sup,
43tt,
44var,
45b,
46u,
47i,
48center,
49dl,
50dt,
51dd,
52ol,
53ul,
54li,
55fieldset,
56form,
57label,
58legend,
59table,
60caption,
61tbody,
62tfoot,
63thead,
64tr,
65th,
66td,
67article,
68aside,
69canvas,
70details,
71embed,
72figure,
73figcaption,
74footer,
75header,
76hgroup,
77menu,
78nav,
79output,
80ruby,
81section,
82summary,
83time,
84mark,
85audio,
86video {
87  margin0;
88  padding0;
89  border0;
90  font-size100%;
91  font: inherit;
92  vertical-align: baseline;
93}
94/* HTML5 display-role reset for older browsers */
95article,
96aside,
97details,
98figcaption,
99figure,
100footer,
101header,
102hgroup,
103menu,
104nav,
105section {
106  display: block;
107}
108body {
109  line-height1;
110}
111ol,
112ul {
113  list-style: none;
114}
115blockquote,
116q {
117  quotes: none;
118}
119blockquote:before,
120blockquote:after,
121q:before,
122q:after {
123  content"";
124  content: none;
125}
126table {
127  border-collapse: collapse;
128  border-spacing0;
129}
  • 1

global.css

 1@import "//at.alicdn.com/t/font_1811699_2hvkwp7upcz.css";
2
3a {
4  color#409eff;
5  text-decoration: none;
6}
7a:hover{
8  color#66b1ff;
9}
10* {
11  box-sizing: border-box;
12}
13
14.container {
15  width1080px;
16  margin0 auto;
17}
18
19input {
20  background-color#fff;
21  background-image: none;
22  border-radius4px;
23  border1px solid #dcdfe6;
24  color#606266;
25  display: inline-block;
26  font-size: inherit;
27  height40px;
28  line-height40px;
29  outline: none;
30  padding0 15px;
31  transition: border-color 0.2s cubic-bezier(0.645, 0.045, 0.355, 1);
32}
33input:focus {
34  outline: none;
35  border-color#409eff;
36}
37
38body {
39  min-width1100px;
40  line-height1.5;
41  color#333;
42}
43
44button {
45  outline: none;
46  border: none;
47  width170px;
48  font-size: inherit;
49  color#fff;
50  background-color#409eff;
51  border-color#409eff;
52  line-height1;
53  white-space: nowrap;
54  cursor: pointer;
55  transition0.1s;
56  font-weight500;
57  font-size14px;
58  border-radius4px;
59  padding12px;
60}
61button:hover {
62  background#66b1ff;
63  border-color#66b1ff;
64}
  • 1

全局导入

main.js

 1// The Vue build version to load with the `import` command
2// (runtime-only or standalone) has been set in webpack.base.conf with an alias.
3import Vue from 'vue'
4import "./assets/css/reset.css"
5import "./assets/css/global.css"
6import router from './router'
7import store from "./store/index"
8import Vuex from "vuex"
9Vue.use(Vuex)
10Vue.config.productionTip = false
11
12/* eslint-disable no-new */
13new Vue({
14  el'#app',
15  router,
16  store,
17  components: {},
18  template''
19})
  • 1

2、在components/slider文件夹下新建Slider.vue和sliderIndex.vue这两个组件

Slider.vue

 1<template>
2    <div class="banner-container">
3      <ul class="images">
4        <li><a href=""><img src="../../assets/img/banner/banner1.jpeg" alt=""></a></li>
5        <li><a href=""><img src="../../assets/img/banner/banner2.jpeg" alt=""></a></li>
6        <li><a href=""><img src="../../assets/img/banner/banner3.jpeg" alt=""></a></li>
7      </ul>
8      <ul class="dots">
9        <li class="active"></li>
10        <li></li>
11        <li></li>
12      </ul>
13    </div>
14</template>
15
16<script>
17    export default {
18        name: "Slider",
19    }
20</script>
21
22<style scoped>
23  /* 样式 */
24  .banner-container {
25    height: 350px;
26    position: relative;
27    overflow: hidden;
28  }
29  .banner-container li {
30    display: block;
31    width: 1080px;
32    height: 100%;
33    float: left;
34  }
35  .images {
36    height: 100%;
37    transition: 0.5s;
38  }
39  .banner-container img {
40    width: 1080px;
41    height: 100%;
42  }
43  .dots {
44    position: absolute;
45    bottom: 10px;
46    right: 10px;
47    display: flex;
48  }
49  .dots li {
50    width: 10px;
51    cursor: pointer;
52    height: 10px;
53    margin: 0 3px;
54    border-radius: 50%;
55    border: 1px solid;
56    color: #fff;
57  }
58  .dots li.active {
59    background: #fff;
60  }
61</style>

    SliderIndex.vue

     1<template>
    2    <div style="width:1080px;margin: 0 auto ">
    3      <slider></slider>
    4    </div>
    5</template>
    6<script>
    7  import slider from "./Slider"
    8    export default {
    9        name: "SliderIndex",
    10        components:{
    11          slider:slider
    12        },
    13    }
    14</script>
    15
    16<style scoped>
    17
    18</style>

      这样,整体的布局效果就已经出来了。这里就不进行截图了。

      组件通信和静态资源导入

      在Slider.vue这个组件中,我们是将图片直接写死的,上面分析也提到过,哪些数据是可控的,哪些数据是不可控的,图片的话,我们动态引入。

      资源导入

      资源导入有两种方式,一种是import,另一种是require导入。

      • import 导入
      1  import banner1 from "../../assets/img/banner/banner1.jpeg"
      2  import banner2 from "../../assets/img/banner/banner2.jpeg"
      3  import banner3 from "../../assets/img/banner/banner3.jpeg"
      • 1
      • require导入
      1require("./../../assets/img/banner/banner1.jpeg")
      2require("./../../assets/img/banner/banner2.jpeg")
      3require("./../../assets/img/banner/banner3.jpeg")
      • 1

      这两种方式都可以,

      SliderIndex.vue

       1<template>
      2    <div style="width:1080px;margin: 0 auto ">
      3      <slider :sliderArray="sliderArray"></slider>
      4    </div>
      5</template>
      6<script>
      7  import slider from "./Slider"
      8  import banner1 from "../../assets/img/banner/banner1.jpeg"
      9  import banner2 from "../../assets/img/banner/banner2.jpeg"
      10  import banner3 from "../../assets/img/banner/banner3.jpeg"
      11    export default {
      12        name: "SliderIndex",
      13        components:{
      14          slider:slider
      15        },
      16        data(){
      17          return{
      18            sliderArray:[banner1,banner2,banner3]
      19          }
      20        }
      21    }
      22</script>
      23
      24<style scoped>
      25
      26</style>

        Slide.vue

         1<template>
        2    <div class="banner-container">
        3      <ul class="images">
        4        <li v-for="(item,i) of sliderArray" :key="i">
        5          <a href="javascript:void(0)"><img :src=item alt=""></a>
        6        </li>
        7      </ul>
        8      <ul class="dots">
        9        <li v-for="(item,i) of sliderArray" :key='i'></li>
        10      </ul>
        11    </div>
        12</template>
        13
        14<script>
        15    export default {
        16        name: "Slider",
        17      props:{
        18          sliderArray:{
        19            require:true,
        20            type:Array,
        21          }
        22      }
        23    }
        24</script>
        25
        26<style scoped>
        27  /* 样式 */
        28  .banner-container {
        29    height: 350px;
        30    position: relative;
        31    overflow: hidden;
        32  }
        33  .banner-container li {
        34    display: block;
        35    width: 1080px;
        36    height: 100%;
        37    float: left;
        38  }
        39  .images {
        40    height: 100%;
        41    transition: 0.5s;
        42  }
        43  .banner-container img {
        44    width: 1080px;
        45    height: 100%;
        46  }
        47  .dots {
        48    position: absolute;
        49    bottom: 10px;
        50    right: 10px;
        51    display: flex;
        52  }
        53  .dots li {
        54    width: 10px;
        55    cursor: pointer;
        56    height: 10px;
        57    margin: 0 3px;
        58    border-radius: 50%;
        59    border: 1px solid;
        60    color: #fff;
        61  }
        62  .dots li.active {
        63    background: #fff;
        64  }
        65</style>

          到这一步的时候,有几个问题,第一个是默认我们图片显示第一张,小圆点默认第一个显示,容器的总宽度计算是总图片的长度*100%,Slide.vue定义内部数据index=0,当index和i相等时,添加active类

           1<template>
          2    <div class="banner-container">
          3      <ul class="images" :style="{
          4        width:sliderArray.length*100+'%',
          5        marginLeft:-index*100+'%'
          6      }">
          7        <li v-for="(item,i) of sliderArray" :key="i">
          8          <a href="javascript:void(0)"><img :src=item alt=""></a>
          9        </li>
          10      </ul>
          11      <ul class="dots">
          12        <li v-for="(item,i) of sliderArray" :class="{
          13          active:i===index
          14        }" :key="i"></li>
          15      </ul>
          16    </div>
          17</template>
          18
          19<script>
          20    export default {
          21        name: "Slider",
          22      props:{
          23          sliderArray:{
          24            require:true,
          25            type:Array,
          26          }
          27      },
          28      data(){
          29          return{
          30            index:0,
          31          }
          32      }
          33    }
          34</script>
          35
          36<style scoped>
          37  /* 样式 */
          38  .banner-container {
          39    height: 350px;
          40    position: relative;
          41    overflow: hidden;
          42  }
          43  .banner-container li {
          44    display: block;
          45    width: 1080px;
          46    height: 100%;
          47    float: left;
          48  }
          49  .images {
          50    height: 100%;
          51    transition: 0.5s;
          52  }
          53  .banner-container img {
          54    width: 1080px;
          55    height: 100%;
          56  }
          57  .dots {
          58    position: absolute;
          59    bottom: 10px;
          60    right: 10px;
          61    display: flex;
          62  }
          63  .dots li {
          64    width: 10px;
          65    cursor: pointer;
          66    height: 10px;
          67    margin: 0 3px;
          68    border-radius: 50%;
          69    border: 1px solid;
          70    color: #fff;
          71  }
          72  .dots li.active {
          73    background: #fff;
          74  }
          75</style>

            这时,可以实现基本的轮播效果,在这里我们无需关注视图,只需要关注数据即可,因为数据改变了,视图之然就变了,可以用控制台改变index的值。

            小圆点切换时,图片切换

            这个功能的实现特别简单,只需要在点击的时候将i的值赋值给index即可,即index改变,视图重新渲染。

            1      <ul class="dots">
            2        <li v-for="(item,i) of sliderArray" :class="{
            3          active:i===index
            4        }" :key="i" @click="index=i"></li>
            5      </ul>

              自动轮播和停止轮播

              实现自动轮播的关键是在组件挂载时调用方法,停止轮播的关键是组件销毁时,销毁定时器。

              鼠标悬停,轮播停止。鼠标离开,录播继续。

               1<template>
              2    <div class="banner-container">
              3      <ul class="images" :style="{
              4        width:sliderArray.length*100+'%',
              5        marginLeft:-index*100+'%'
              6      }">
              7        <li v-for="(item,i) of sliderArray" :key="i" @mouseleave="autoStart" @mouseenter="autoStop">
              8          <a href="javascript:void(0)"><img :src=item alt=""></a>
              9        </li>
              10      </ul>
              11      <ul class="dots">
              12        <li v-for="(item,i) of sliderArray" :class="{
              13          active:i===index
              14        }" :key="i" @click="index=i"></li>
              15      </ul>
              16    </div>
              17</template>
              18
              19<script>
              20    export default {
              21        name: "Slider",
              22      props:{
              23          sliderArray:{
              24            require:true,
              25            type:Array,
              26          }
              27      },
              28      data(){
              29          return{
              30            index:0,
              31            timer:null
              32          }
              33      },
              34      mounted(){
              35        this.autoStart()
              36      },
              37      destroyed(){
              38          this.autoStop()
              39      },
              40      methods:{
              41          autoStart(){
              42            if(this.timer){
              43              return
              44            }
              45            this.timer=setInterval(()=>{
              46              this.index=(this.index+1)%this.sliderArray.length;
              47            },2000)
              48          },
              49          autoStop(){
              50            clearInterval(this.timer);
              51            this.timer=null;
              52          }
              53      }
              54    }
              55</script>
              56
              57<style scoped>
              58  /* 样式 */
              59  .banner-container {
              60    height: 350px;
              61    position: relative;
              62    overflow: hidden;
              63  }
              64  .banner-container li {
              65    display: block;
              66    width: 1080px;
              67    height: 100%;
              68    float: left;
              69  }
              70  .images {
              71    height: 100%;
              72    transition: 0.5s;
              73  }
              74  .banner-container img {
              75    width: 1080px;
              76    height: 100%;
              77  }
              78  .dots {
              79    position: absolute;
              80    bottom: 10px;
              81    right: 10px;
              82    display: flex;
              83  }
              84  .dots li {
              85    width: 10px;
              86    cursor: pointer;
              87    height: 10px;
              88    margin: 0 3px;
              89    border-radius: 50%;
              90    border: 1px solid;
              91    color: #fff;
              92  }
              93  .dots li.active {
              94    background: #fff;
              95  }
              96</style>

                简单的轮播效果就已经实现了,整体难度不难,但是涉及的知识点比较多,从一个小的轮播效果就涉及那么多的知识点,所以说基础很重要,杨戬的基础也不是很好,但是杨戬是一个喜欢学习的暖男(我信你个鬼),好了,看到这里,本编博客的内容就要结束了,我们下篇文章见。

                结尾

                如果觉得本篇文章对您有用的话,可以麻烦您帮忙点亮那个点赞按钮吗?

                对于杨戬这个暖男来说:真的真的非常有用,您的支持将是我继续写文章前进的动力,我们下篇文章见。

                【原创】|二郎神杨戬

                二郎神杨戬,一个在互联网前端苟且偷生的划水程序员,专注于前端开发,善于技术分享。
                如需转载,请联系作者或者保留原文链接,微信公众号搜索二郎神杨戬或者扫描下方的二维码更加方便。

                一起来见证二郎神杨戬的成长吧!更多好文、技术分享尽在下方这个公众号。欢迎关注。

                声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小丑西瓜9/article/detail/251184
                推荐阅读
                相关标签
                  

                闽ICP备14008679号