1. 程式人生 > 實用技巧 >用Vue實現一個簡單的圖片輪播

用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/
2v2.0|20110126
3License:none(publicdomain)
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{
87margin:0;
88padding:0;
89border:0;
90font-size:100%;
91font:inherit;
92vertical-align:baseline;
93}
94/*HTML5display-roleresetforolderbrowsers*/
95article,
96aside,
97details,
98figcaption,
99figure,
100footer,
101header,
102hgroup,
103menu,
104nav,
105section{
106display:block;
107}
108body{
109line-height:1;
110}
111ol,
112ul{
113list-style:none;
114}
115blockquote,
116q{
117quotes:none;
118}
119blockquote:before,
120blockquote:after,
121q:before,
122q:after{
123content:"";
124content:none;
125}
126table{
127border-collapse:collapse;
128border-spacing:0;
129}

global.css

 [email protected]"//at.alicdn.com/t/font_1811699_2hvkwp7upcz.css";
2
3a{
4color:#409eff;
5text-decoration:none;
6}
7a:hover{
8color:#66b1ff;
9}
10*{
11box-sizing:border-box;
12}
13
14.container{
15width:1080px;
16margin:0auto;
17}
18
19input{
20background-color:#fff;
21background-image:none;
22border-radius:4px;
23border:1pxsolid#dcdfe6;
24color:#606266;
25display:inline-block;
26font-size:inherit;
27height:40px;
28line-height:40px;
29outline:none;
30padding:015px;
31transition:border-color0.2scubic-bezier(0.645,0.045,0.355,1);
32}
33input:focus{
34outline:none;
35border-color:#409eff;
36}
37
38body{
39min-width:1100px;
40line-height:1.5;
41color:#333;
42}
43
44button{
45outline:none;
46border:none;
47width:170px;
48font-size:inherit;
49color:#fff;
50background-color:#409eff;
51border-color:#409eff;
52line-height:1;
53white-space:nowrap;
54cursor:pointer;
55transition:0.1s;
56font-weight:500;
57font-size:14px;
58border-radius:4px;
59padding:12px;
60}
61button:hover{
62background:#66b1ff;
63border-color:#66b1ff;
64}

全域性匯入

main.js

 1//TheVuebuildversiontoloadwiththe`import`command
2//(runtime-onlyorstandalone)hasbeensetinwebpack.base.confwithanalias.
3importVuefrom'vue'
4import"./assets/css/reset.css"
5import"./assets/css/global.css"
6importrouterfrom'./router'
7importstorefrom"./store/index"
8importVuexfrom"vuex"
9Vue.use(Vuex)
10Vue.config.productionTip=false
11
12/*eslint-disableno-new*/
13newVue({
14el:'#app',
15router,
16store,
17components:{},
18template:''
19})

2、在components/slider資料夾下新建Slider.vue和sliderIndex.vue這兩個元件

Slider.vue

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

SliderIndex.vue

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

這樣,整體的佈局效果就已經出來了。這裡就不進行截圖了。

元件通訊和靜態資源匯入

在Slider.vue這個元件中,我們是將圖片直接寫死的,上面分析也提到過,哪些資料是可控的,哪些資料是不可控的,圖片的話,我們動態引入。

資源匯入

資源匯入有兩種方式,一種是import,另一種是require匯入。

  • import 匯入
1importbanner1from"../../assets/img/banner/banner1.jpeg"
2importbanner2from"../../assets/img/banner/banner2.jpeg"
3importbanner3from"../../assets/img/banner/banner3.jpeg"
  • require匯入
1require("./../../assets/img/banner/banner1.jpeg")
2require("./../../assets/img/banner/banner2.jpeg")
3require("./../../assets/img/banner/banner3.jpeg")

這兩種方式都可以,

SliderIndex.vue

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

Slide.vue

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

到這一步的時候,有幾個問題,第一個是預設我們圖片顯示第一張,小圓點預設第一個顯示,容器的總寬度計算是總圖片的長度*100%,Slide.vue定義內部資料index=0,當index和i相等時,新增active類

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

這時,可以實現基本的輪播效果,在這裡我們無需關注檢視,只需要關注資料即可,因為資料改變了,檢視之然就變了,可以用控制檯改變index的值。

小圓點切換時,圖片切換

這個功能的實現特別簡單,只需要在點選的時候將i的值賦值給index即可,即index改變,檢視重新渲染。

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

自動輪播和停止輪播

實現自動輪播的關鍵是在元件掛載時呼叫方法,停止輪播的關鍵是元件銷燬時,銷燬定時器。

滑鼠懸停,輪播停止。滑鼠離開,錄播繼續。

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

簡單的輪播效果就已經實現了,整體難度不難,但是涉及的知識點比較多,從一個小的輪播效果就涉及那麼多的知識點,所以說基礎很重要,楊戩的基礎也不是很好,但是楊戩是一個喜歡學習的暖男(我信你個鬼),好了,看到這裡,本編部落格的內容就要結束了,我們下篇文章見。

結尾

如果覺得本篇文章對您有用的話,可以麻煩您幫忙點亮那個點贊按鈕嗎?

對於楊戩這個暖男來說:真的真的非常有用,您的支援將是我繼續寫文章前進的動力,我們下篇文章見。

【原創】|二郎神楊戩

二郎神楊戩,一個在網際網路前端苟且偷生的划水程式設計師,專注於前端開發,善於技術分享。
如需轉載,請聯絡作者或者保留原文連結,微信公眾號搜尋二郎神楊戩或者掃描下方的二維碼更加方便。

一起來見證二郎神楊戩的成長吧!更多好文、技術分享盡在下方這個公眾號。歡迎關注。