從零開始學 Web 之 Vue.js(五)Vue的動畫

你們好,這裏是「 從零開始學 Web 系列教程 」,並在下列地址同步更新......css

  • github:https://github.com/Daotin/Web
  • 微信公衆號:Web前端之巔
  • 博客園:http://www.cnblogs.com/lvonve/

在這裏我會從 Web 前端零基礎開始,一步步學習 Web 相關的知識點,期間也會分享一些好玩的項目。如今就讓咱們一塊兒進入 Web 前端學習的冒險之旅吧!html

1、Vue的動畫

爲何要有動畫:動畫可以提升用戶的體驗,幫助用戶更好的理解頁面中的功能;前端

Vue 中也有動畫,不過遠沒有 css3 中的那麼炫酷。只能有一些簡單的變換,可是卻能夠配合第三方css動畫庫完成炫酷的變換。vue

一、過渡的類名

在進入/離開的過渡中,會有 6 個 class 切換。css3

  • v-enter:定義進入過渡的開始狀態。在元素被插入以前生效,在元素被插入以後的下一幀移除。
  • v-enter-active:定義進入過渡生效時的狀態。在整個進入過渡的階段中應用,在元素被插入以前生效,在過渡/動畫完成以後移除。這個類能夠被用來定義進入過渡的過程時間,延遲和曲線函數。
  • v-enter-to: 定義進入過渡的結束狀態。在元素被插入以後下一幀生效 (與此同時 v-enter 被移除),在過渡/動畫完成以後移除。
  • v-leave: 定義離開過渡的開始狀態。在離開過渡被觸發時馬上生效,下一幀被移除。
  • v-leave-active:定義離開過渡生效時的狀態。在整個離開過渡的階段中應用,在離開過渡被觸發時馬上生效,在過渡/動畫完成以後移除。這個類能夠被用來定義離開過渡的過程時間,延遲和曲線函數。
  • v-leave-to: 定義離開過渡的結束狀態。在離開過渡被觸發以後下一幀生效 (與此同時 v-leave 被刪除),在過渡/動畫完成以後移除。

要實現元素過渡,須要在添加過渡元素外邊包裹上 <transition> </transition> 閉合標籤。git

而後將 v-enterv-leave-to 分爲一組,v-enter-tov-leave分爲一組,v-enter-activev-leave-active 分爲一組。github

v-enterv-leave-to 設置動畫的起始狀態;微信

v-enter-tov-leave 設置動畫的結束狀態;app

v-enter-activev-leave-active 設置動畫的過渡時間和過渡效果。函數

示例:點擊按鈕實現標籤的淡入淡出:

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Document</title>
  <script src="./lib/vue-2.4.0.js"></script>
  <style>
    .v-enter,
    .v-leave-to {
      opacity: 0;
    }

    .v-enter-active,
    .v-leave-active {
      transition: opacity 1s ease;
    }
  </style>
</head>

<body>
  <div id="box">
    <input type="button" value="顯示/隱藏" @click="flag=!flag">
    <transition>
      <h3 v-show="flag">這是一個H3標籤</h3>
    </transition>
  </div>

  <script>
    var vm = new Vue({
      el: "#box",
      data: {
        flag: false
      },
      methods: {}
    });
  </script>
</body>

</html>

注意事項:

一、發生動畫的元素必須被 transition 標籤包裹。

二、動畫的進入離開爲css屬性,寫在style標籤中。

三、對於這些在過渡中切換的類名來講,若是你使用一個沒有名字的 <transition>,則 v-是這些類名的默認前綴。若是你使用了 <transition name="my-transition">,那麼 v-enter 會替換爲my-transition-enter

二、使用插件實現動畫

這裏咱們使用:Animate.css 第三方css插件。

官方網站:https://daneden.github.io/animate.css/

使用方式:

一、引入 animate.css 庫文件

二、在 tramsition 標籤中使用特定動畫的類樣式。

<transition enter-active-class="animated zoomIn" leave-active-class="animated zoomOut" :duration="{ enter: 200, leave: 400 }">
  <h3 v-show="flag">這是一個H3標籤</h3>
</transition>

注意:

一、類樣式必定要加基礎類樣式 animated

二、enter-active-class :表示進入動畫樣式

leave-active-class:表示離開動畫樣式

:duration="{ enter: 200, leave: 400 }": 表示進入和離開的動畫時間,單位ms。

若是隻寫 :duration="200"則表示進入和離開的事件都爲200ms。

三、半程動畫

有的時候咱們只想實現動畫的進入,不想實現動畫的退出。好比將物品加入購物車的動畫,會有一個商品掉入購物車的動畫效果,可是咱們卻不須要商品再從購物車出來的動畫效果,那麼如何實現動畫的半程效果呢?

使用 JavaScript 鉤子函數:(寫在 transition 標籤中)

<transition
  v-on:before-enter="beforeEnter"
  v-on:enter="enter"
  v-on:after-enter="afterEnter"
  v-on:enter-cancelled="enterCancelled"

  v-on:before-leave="beforeLeave"
  v-on:leave="leave"
  v-on:after-leave="afterLeave"
  v-on:leave-cancelled="leaveCancelled"
>
  <!-- ... -->
</transition>

其中上面四個事件是進如動畫的幾個階段:

  • before-enter :動畫進入以前的狀態
  • enter:動畫進入結束時的狀態
  • after-enter:動畫進入完成後的操做。
  • enter-cancelled:動畫進入中斷的操做(通常不使用)

既然是事件綁定函數,那麼就有須要在 methods 中填寫對應的事件處理函數:

methods: {
  // --------
  // 進入中
  // --------

  beforeEnter: function (el) {
    // ...
  },
  enter: function (el, done) {
    // ...
    done()
  },
  afterEnter: function (el) {
    // ...
  }

其中:

一、參數 el 表示的是須要動畫操做的 原生DOM對象。

二、當只用 JavaScript 過渡的時候,在 enter 和 leave 中必須使用 done 進行回調。enter中的done參數就至關於進入動畫中的 afterEnter 函數,能夠避免動畫完成後的延遲。

三、這些鉤子函數能夠結合 CSS transitions/animations 使用,也能夠單獨使用。

模擬商品掉入購物車過程

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <title>Document</title>
  <script src="./lib/vue-2.4.0.js"></script>
  <style>
    .ball {
      width: 20px;
      height: 20px;
      border-radius: 50%;
      background-color: blue;
      margin-top: 10px;
    }
  </style>
</head>

<body>
  <div id="box">
    <input type="button" value="快到碗裏來" @click="flag = !flag">
    <transition @before-enter="beforeEnter" @enter="enter" @after-enter="afterEnter">
      <div class="ball" v-show="flag"></div>
    </transition>

  </div>

  <script>
    var vm = new Vue({
      el: "#box",
      data: {
        flag: false
      },
      methods: {
        beforeEnter(el) {
          el.style.transform = "translate(0, 0)";
        },
        enter(el, done) {
          // 這句話,沒有實際的做用,可是,若是不寫,出不來動畫效果;
          el.offsetWidth;
          el.style.transform = "translate(100px, 400px)";
          el.style.transition = 'transform 1s';
          // 不使用的話,小圓點會停留一段時間才消失,不能當即調用 afterEnter 函數
          done();
        },
        afterEnter(el) {
          this.flag = !this.flag;
        }
      }
    });
  </script>
</body>

</html>

一、enter 中的 el.offsetWidth; 無實際做用,能夠認爲 el.offset系列語句會強制動畫刷新。

二、done(); 必須使用,至關於當即調用 afterEnter 函數。

三、既然是半程動畫,那麼意味着點擊按鈕的時候,每次小球都是從起始位置出發,而不會從終點位置回到其實位置的過程。

四、列表動畫

列表增長,刪除項的時候,顯示動畫效果。

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Document</title>
  <script src="./lib/vue-2.4.0.js"></script>
  <style>
    li {
      width: 100%;
      border: 1px dashed #aaa;
      margin: 10px 0;
      font: 700 12px/36px 'Microsoft YaHei';
      padding-left: 10px;
    }

    li:hover {
      border: 1px solid rgb(226, 22, 124);
      transition: border .5s;
    }

    /* 只對transition-group包裹的起做用*/

    .v-enter,
    .v-leave-to {
      opacity: 0;
      transform: translateY(-10px);
    }

    .v-enter-active,
    .v-leave-active {
      transition: transform 0.5s ease-out;
    }

    /*列表的過渡更加平緩柔和*/
    .v-move {
      transition: all 0.5s;
    }
    /*列表的過渡更加平緩柔和*/
    .v-leave-active {
      position: absolute;
    }
  </style>
</head>

<body>
  <div id="box">
    <div>
      <label for="">
        ID:
        <input type="text" v-model="id">
      </label>
      <label for="">
        name:
        <input type="text" v-model="name">
      </label>
      <input type="button" value="添加" @click="add">
    </div>

    <div>
      <ul>
        <!-- 一、使用transition-group包裹v-for渲染的li列表 -->
        <transition-group appear>
          <li v-for="(item, index) in list" :key="item.id" @click="del(index)">
            {{item.id}} --- {{item.name}}
          </li>
        </transition-group>
      </ul>
    </div>

  </div>

  <script>
    var vm = new Vue({
      el: "#box",
      data: {
        id: '',
        name: '',
        list: [{
            id: 1,
            name: '漩渦鳴人'
          },
          {
            id: 2,
            name: '宇智波佐助'
          },
          {
            id: 3,
            name: '旗木卡卡西'
          },
          {
            id: 4,
            name: '自來也'
          },
        ]
      },
      methods: {
        add() {
          this.list.push({
            id: this.id,
            name: this.name
          });
        },
        del(id) {
          this.list.splice(id, 1);
        }
      }
    });
  </script>
</body>

</html>

注意:

一、在實現列表過渡的時候,若是須要過渡的元素,是經過 v-for 循環渲染出來的,不能使用 transition 包裹,須要使用 transition-group.

二、若是要爲 v-for 循環建立的元素設置動畫,必須爲每個 元素 設置 :key 屬性

三、過渡的類名:v-enter 等,這些類只對 transition 或者 transition-group 包裹起來的元素起做用。

四、<transition-group> 組件還有一個特殊之處。不只能夠進入和離開動畫,還能夠改變定位。要使用這個新功能只需瞭解新增的 v-move 特性,它會在元素的改變定位的過程當中應用。實現刪除動畫的時候,後一個元素補到刪除元素的位置也能動畫,v-movev-leave-active 結合使用,可以讓列表的過渡更加平緩柔和:

.v-move {
  transition: all 0.5s;
}

.v-leave-active {
  position: absolute;
}

五、給 transition 或者 transition-group 添加屬性:appear 能夠實現頁面開始加載的時候,實現動畫效果。

咱們發現一個問題就是,transition-group 會被默認當作 span 標籤,這不是咱們想要的樣子鴨。

經過 爲 transition-group 元素,設置 tag 屬性,指定 transition-group 渲染爲指定的元素,若是不指定 tag 屬性,默認渲染爲 span 標籤,這就不符合語義了。因此咱們能夠把外層的 ul 去掉,而後加上tag="ul"來把 transition-group 標籤做爲 ul 標籤。

相關文章
相關標籤/搜索