在 vue 中用 transition 實現輪播效果


概述

今天我接到一個需求:輪播效果。本來我是打算使用 Swiper 實現的,但是想起來貌似 transition 也能實現。於是就試了下,真的可以,還挺簡單的,於是就記錄下來,供以后開發時參考,相信對其他人也有用。

參考資料:進入/離開 & 列表過渡

transition

我從官網扒了一個示例的源碼,如下所示:

<div id="no-mode-translate-demo" class="demo">
  <div class="no-mode-translate-demo-wrapper">
    <transition name="no-mode-translate-fade">
      <button v-if="on" key="on" @click="on = false">
        on
      </button>
      <button v-else="" key="off" @click="on = true">
        off
      </button>
    </transition>
  </div>
</div>
<script>
new Vue({
  el: '#no-mode-translate-demo',
  data: {
    on: false
  }
})
</script>
<style>
.no-mode-translate-demo-wrapper {
  position: relative;
  height: 18px;
}
.no-mode-translate-demo-wrapper button {
  position: absolute;
}
.no-mode-translate-fade-enter-active, .no-mode-translate-fade-leave-active {
  transition: all 1s;
}
.no-mode-translate-fade-enter, .no-mode-translate-fade-leave-active {
  opacity: 0;
}
.no-mode-translate-fade-enter {
  transform: translateX(31px);
}
.no-mode-translate-fade-leave-active {
  transform: translateX(-31px);
}
</style>

這個示例是,如果點擊按鈕,按鈕就會從左邊漸隱消失,然后另一個按鈕會從右邊漸隱出現。這不就是輪播效果嗎?所以我仿照這個例子做了如下改寫:

<template>
  <div>
    <div class="chart-wrapper">
      <transition name="slide">
        <div v-if="id === 0" class="chart" key="0">
          <e-charts
            :options="chartOption"
          />
        </div>

        <div v-else-if="id === 1" class="chart" key="1">
          <e-charts
            :options="chartOption"
          />
        </div>
        <div v-else-if="id === 2" class="chart" key="2">
          3333
        </div>
        <div v-else-if="id === 3" class="chart" key="3">
          444
        </div>
      </transition>
    </div>

    <ul style="display: flex;">
      <li @click="id = 0">第一個</li>
      <li @click="id = 1">第二個</li>
      <li @click="id = 2">第三個</li>
      <li @click="id = 3">第四個</li>
    </ul>
  </div>
</template>

<script>
export default {
  data() {
    return {
      id: 0,
    };
  },
  computed: {
    chartOption() {
      return {
        xAxis: {
            type: 'category',
            data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']
        },
        yAxis: {
            type: 'value'
        },
        series: [{
            data: [820, 932, 901, 934, 1290, 1330, 1320],
            type: 'line'
        }],
      };
    },
  },
};
</script>

<style lang="scss">
.chart-wrapper {
  position: relative;
  margin-left: 200px;
  width: 800px;
  height: 400px;
}
.chart-wrapper .chart {
  display: flex;
  position: absolute;
  width: 100%;
  height: 400px;
}
.slide-enter-active, .slide-leave-active {
  transition: all 1s;
}
.slide-enter {
  opacity: 0;
  transform: translateX(100%);
}

.slide-leave-active {
  opacity: 0;
  transform: translateX(-100%);
}
</style>

上面我們希望通過輪播,來切換 echarts 的圖標,但是,實際用起來我們發現,當切換第三頁和第四頁的時候,切換效果是正常的,說明已經成功了。但是在切換第一頁和第二頁的時候,echarts 圖表總是會無緣無故消失

冷靜分析,我們在切換的時候,是通過利用 v-if 來實現的,也就是說,v-if 先起作用,然后帶動 scss 的動畫起作用。那么因為第三頁和第四頁中的內容是靜態的,所以 v-if 對它沒什么影響;但是第一頁和第二頁中的 echarts 圖表組件,在 v-if 起作用的瞬間,就已經調用 destroy 方法銷毀掉了,然后 scss 才開始起作用,最后出現輪播的動畫效果,所以就出現了 echarts 圖表先消失,然后才發生輪播動畫的情況。

所以這里如果要實現 echarts 圖表組件的漸隱,就不能用 v-if 方法,只能用 v-show 方法

transition-group

如果用 v-show 方法,那么 transition 組件里面就有不止一個元素了,所以必須將 transition 改成 transition-group。改后的代碼如下:

<template>
  <div>
    <div class="chart-wrapper">
      <transition-group name="slide">
        <div v-show="id === 0" class="chart" key="0">
          <e-charts
            :options="chartOption"
          />
        </div>

        <div v-show="id === 1" class="chart" key="1">
          <e-charts
            :options="chartOption"
          />
        </div>
        <div v-if="id === 2" class="chart" key="2">
          3333
        </div>
        <div v-else-if="id === 3" class="chart" key="3">
          444
        </div>
      </transition-group>
    </div>

    <ul style="display: flex;">
      <li @click="id = 0">第一個</li>
      <li @click="id = 1">第二個</li>
      <li @click="id = 2">第三個</li>
      <li @click="id = 3">第四個</li>
    </ul>
  </div>
</template>

<script>
export default {
  data() {
    return {
      id: 0,
    };
  },
  computed: {
    chartOption() {
      return {
        xAxis: {
            type: 'category',
            data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']
        },
        yAxis: {
            type: 'value'
        },
        series: [{
            data: [820, 932, 901, 934, 1290, 1330, 1320],
            type: 'line'
        }],
      };
    },
  },
};
</script>

<style lang="scss">
.chart-wrapper {
  position: relative;
  margin-left: 200px;
  width: 800px;
  height: 400px;
}
.chart-wrapper .chart {
  display: flex;
  position: absolute;
  width: 100%;
  height: 400px;
}
.slide-enter-active, .slide-leave-active {
  transition: all 1s;
}
.slide-enter {
  opacity: 0;
  transform: translateX(100%);
}

.slide-leave-active {
  opacity: 0;
  transform: translateX(-100%);
}
</style>

由於 transition-group 和 transition 的原理基本上是一樣的。所以只需要把 transition 改成 transition-group,然后把 v-if 改成 v-show 就行了,其它地方根本不需要動。

運行起來后,發現 echarts 圖表的輪播效果正常了!


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM