手寫vue輪播圖(一)

本著想學(xué)習(xí)寫自定義指令的初衷犀勒,當(dāng)遇到這個(gè)需求時(shí)摔笤,便想以此為契機(jī)寫一個(gè)v-carousel的指令副女,來實(shí)現(xiàn)輪播圖的效果蛤高。后來發(fā)現(xiàn),用vue自帶的“過渡&動(dòng)畫”就能夠基本實(shí)現(xiàn)碑幅。

過渡動(dòng)畫的實(shí)現(xiàn)依靠vue封裝的兩個(gè)組件

  1. 單元素/單組件/多元素/多組件過渡(單個(gè)節(jié)點(diǎn)或同一時(shí)間渲染多個(gè)節(jié)點(diǎn)中的一個(gè))戴陡,<transition></transtion>
  2. 列表過渡沟涨,<transition-group></transition-group>恤批。考慮到我們是實(shí)現(xiàn)多個(gè)圖片的輪播裹赴,可以跳過直接看 => 列表過渡

其實(shí)喜庞,用vue內(nèi)置組件實(shí)現(xiàn)輪播圖效果很簡(jiǎn)單,思路是根據(jù)圖片的索引(idx)用v-show來進(jìn)行控制顯示和隱藏棋返。相比于往常通過控制外層ul元素的translateX值來達(dá)到輪播效果赋荆,它只通過當(dāng)前顯示的即將顯示的兩個(gè)元素的translateX值來實(shí)現(xiàn)。

實(shí)現(xiàn)這個(gè)“輪播”效果的關(guān)鍵在于理解transition組件內(nèi)部css過渡類名的含義懊昨,并為其書寫相應(yīng)的css。

image.png

過渡的類名

在進(jìn)入/離開的過渡中春宣,會(huì)有 6 個(gè) class 切換酵颁。常用的是v-enter, v-enter-active, v-leave, v-leave-active這四個(gè)。其中"v"可以被自定義的name取代月帝。

v-enter:定義進(jìn)入過渡的開始狀態(tài)躏惋。在元素被插入之前生效,在元素被插入之后的下一幀移除嚷辅。

v-enter-active:定義進(jìn)入過渡生效時(shí)的狀態(tài)簿姨。在整個(gè)進(jìn)入過渡的階段中應(yīng)用,在元素被插入之前生效簸搞,在過渡/動(dòng)畫完成之后移除扁位。這個(gè)類可以被用來定義進(jìn)入過渡的過程時(shí)間,延遲和曲線函數(shù)趁俊。

v-enter-to: 2.1.8版及以上 定義進(jìn)入過渡的結(jié)束狀態(tài)域仇。在元素被插入之后下一幀生效 (與此同時(shí) v-enter 被移除),在過渡/動(dòng)畫完成之后移除寺擂。

v-leave: 定義離開過渡的開始狀態(tài)暇务。在離開過渡被觸發(fā)時(shí)立刻生效泼掠,下一幀被移除。

v-leave-active:定義離開過渡生效時(shí)的狀態(tài)垦细。在整個(gè)離開過渡的階段中應(yīng)用择镇,在離開過渡被觸發(fā)時(shí)立刻生效,在過渡/動(dòng)畫完成之后移除括改。這個(gè)類可以被用來定義離開過渡的過程時(shí)間腻豌,延遲和曲線函數(shù)。

v-leave-to: 2.1.8版及以上 定義離開過渡的結(jié)束狀態(tài)叹谁。在離開過渡被觸發(fā)之后下一幀生效 (與此同時(shí) v-leave 被刪除)饲梭,在過渡/動(dòng)畫完成之后移除。

在我們實(shí)現(xiàn)(自右向左)輪播的效果中焰檩,對(duì)應(yīng)css類名的css規(guī)則如下:

/* 注意順序不能錯(cuò)亂憔涉,-active的類名要配置在-enter類名之前 */
    .carousel-enter-active {
        transform: translateX(0);
        transition: all 1s ease-in-out;
    }
    .carousel-leave-active {
        transform: translateX(-100%);
        transition: all 1s ease-in-out;
    }
    .carousel-enter {
        transform: translateX(100%)   
    }
    .carousel-leave {
        transform: translateX(0)
    }
    //另外,li要添加position:absolute這個(gè)屬性析苫,它相對(duì)于carousel絕對(duì)定位兜叨。

對(duì)應(yīng)的html結(jié)構(gòu):

<transition-group tag="ul" name="carousel">
    <li v-for="(item, idx) in mybanner" :key="idx" v-show="idx===mark">
        <a href="" class="bannera">
            <img :src="item.banner" alt="">
        </a>
    </li>
</transition-group>
<div class="bullet">
    <span v-for='(item,idx) in mybanner.length' :class="{'active':idx===mark}" @click='change(index)'></span>
</div>

邏輯處理:

methods: {
   change(i) {
     this.mark = i
   },
   autoPlay() {
      this.mark++
      if (this.mark === this.len) { //len在data中定義了,為banner的個(gè)數(shù)
          this.mark = 0
          return
      }
    },
    play() {
       setInterval(this.autoPlay, 3000)
    }
}

至此衩侥,結(jié)合vue內(nèi)置組件<transition-group>實(shí)現(xiàn)圖片輪播的過渡效果基本完成国旷。用 transition系列 實(shí)現(xiàn)過渡效果,代碼量較少茫死,對(duì)于不復(fù)雜的需求可以輕松實(shí)現(xiàn)跪但。

然而,若需要實(shí)現(xiàn)手指滑動(dòng)-->圖片輪播這種效果峦萎,單靠這個(gè)組件沒有辦法實(shí)現(xiàn)屡久;另外,圖片總是從右向左出現(xiàn)爱榔,不論是自動(dòng)循環(huán)被环,還是點(diǎn)擊了某張圖,過渡效果是一樣的详幽,因?yàn)閑nter-active,leave-active樣式是固定的筛欢。這不符合當(dāng)我們點(diǎn)擊某一張之前的圖片,希望它從左往右出現(xiàn)的視覺邏輯唇聘。

于此版姑,我們可以嘗試手寫一個(gè)vue輪播圖指令。
第一版蹩腳的嘗試??迟郎,思路還是老舊的那種(不同于上面)漠酿,“輪播”主要是通過改變外層ul元素的translateX值來達(dá)到效果:

directives: {
   carousel: {
       bind: function (el, binding, vnode, oldVnode) {
           el.classList.add('flex', 'transition');
           el.style.transform = 'translateX(-750px)'; // 初始化
           let w = parseInt(el.style.width);
           let n = Number(w/750), m = 1;

          // 向左輪播
          const carousel = function () {
             if (m == n) {
                  el.style.transform = 'translateX(-750px)';
                  el.classList.remove('transition');
                  m = 1;
             } else if (m == 0) {
                   el.style.transform = 'translateX(' + -750 * (n-1) + 'px)';
                   el.classList.remove('transition');
                   m = n-1;
             } else {
                   el.classList.add('transition');
                   el.style.transform = 'translateX(' + -750 * (m) + 'px)';
                   m++;
             }
          }
          setInterval(()=>{
              carousel()
          }, 3000)
       }
   } 
}
.flex {
     display: flex;
}
.transition {
     transition: transform .5s linear;
} 
<ul :style="{width: ULwidth + 'px'}" v-carousel>
  <li v-for="(item, idx) in mybanner" v-if="idx === (mybanner.length - 1)">
    <a class="bannera" href="" :data-form="item.form" :data-actCode="item.actCode">
      <img :src="item.banner" alt="">
    </a>
  </li>
  <li v-for="(item, idx) in mybanner">
    <a class="bannera" href="" :data-form="item.form" :data-actCode="item.actCode">
      <img :src="item.banner" alt="">
    </a>
  </li>
  <li v-for="(item, idx) in mybanner" v-if="idx === 0">
    <a class="bannera" href="" :data-form="item.form" :data-actCode="item.actCode">
      <img :src="item.banner" alt="">
    </a>
  </li>
</ul>

至此,基本實(shí)現(xiàn)了自動(dòng)播放輪播效果谎亩,下一版本想著改變思路來做了炒嘲。代碼還是放在這記錄一下宇姚,算是思路的軌跡....
????????????

未完待續(xù)...

參考資料
Vue輪播圖的實(shí)現(xiàn)以及其與jQuery輪播圖的簡(jiǎn)單對(duì)比
JS bin代碼演示
mint-ui swiper

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市夫凸,隨后出現(xiàn)的幾起案子浑劳,更是在濱河造成了極大的恐慌,老刑警劉巖夭拌,帶你破解...
    沈念sama閱讀 211,817評(píng)論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件魔熏,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡鸽扁,警方通過查閱死者的電腦和手機(jī)蒜绽,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,329評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來桶现,“玉大人躲雅,你說我怎么就攤上這事÷夂停” “怎么了相赁?”我有些...
    開封第一講書人閱讀 157,354評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)慰于。 經(jīng)常有香客問我钮科,道長(zhǎng),這世上最難降的妖魔是什么婆赠? 我笑而不...
    開封第一講書人閱讀 56,498評(píng)論 1 284
  • 正文 為了忘掉前任绵脯,我火速辦了婚禮,結(jié)果婚禮上休里,老公的妹妹穿的比我還像新娘桨嫁。我一直安慰自己,他們只是感情好份帐,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,600評(píng)論 6 386
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著楣导,像睡著了一般废境。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上筒繁,一...
    開封第一講書人閱讀 49,829評(píng)論 1 290
  • 那天噩凹,我揣著相機(jī)與錄音,去河邊找鬼毡咏。 笑死驮宴,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的呕缭。 我是一名探鬼主播堵泽,決...
    沈念sama閱讀 38,979評(píng)論 3 408
  • 文/蒼蘭香墨 我猛地睜開眼修己,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了迎罗?” 一聲冷哼從身側(cè)響起睬愤,我...
    開封第一講書人閱讀 37,722評(píng)論 0 266
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎纹安,沒想到半個(gè)月后尤辱,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,189評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡厢岂,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,519評(píng)論 2 327
  • 正文 我和宋清朗相戀三年光督,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片塔粒。...
    茶點(diǎn)故事閱讀 38,654評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡结借,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出窗怒,到底是詐尸還是另有隱情映跟,我是刑警寧澤,帶...
    沈念sama閱讀 34,329評(píng)論 4 330
  • 正文 年R本政府宣布扬虚,位于F島的核電站努隙,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏辜昵。R本人自食惡果不足惜荸镊,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,940評(píng)論 3 313
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望堪置。 院中可真熱鬧躬存,春花似錦、人聲如沸舀锨。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,762評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽坎匿。三九已至盾剩,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間替蔬,已是汗流浹背告私。 一陣腳步聲響...
    開封第一講書人閱讀 31,993評(píng)論 1 266
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留承桥,地道東北人驻粟。 一個(gè)月前我還...
    沈念sama閱讀 46,382評(píng)論 2 360
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像凶异,于是被迫代替她去往敵國和親蜀撑。 傳聞我的和親對(duì)象是個(gè)殘疾皇子挤巡,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,543評(píng)論 2 349