過(guò)渡&&動(dòng)畫(huà)總結(jié)

一. vue的過(guò)渡與動(dòng)畫(huà)

Vue 在插入攻冷、更新或者移除 DOM 時(shí)具帮,提供多種不同方式的應(yīng)用過(guò)渡效果。過(guò)渡效果的應(yīng)用可以通過(guò)不同方式實(shí)現(xiàn):

  1. 在CSS過(guò)渡和動(dòng)畫(huà)中自動(dòng)應(yīng)用class
  2. 在過(guò)渡鉤子函數(shù)中使用JavaScript直接操作dom
  3. 配合第三方css動(dòng)畫(huà)庫(kù):Animate.css 或者第三方j(luò)avascript動(dòng)畫(huà)庫(kù):Velocity

上面三種方式其實(shí)主要就是兩種:一個(gè)是利用CSS過(guò)渡或者動(dòng)畫(huà)券时,另一個(gè)是利用JavaScript鉤子函數(shù)懦尝。

二. 如何應(yīng)用過(guò)渡與動(dòng)畫(huà)

下面從進(jìn)入離開(kāi)過(guò)渡以及列表過(guò)渡兩大方向,概述vue如何為元素添加過(guò)渡效果浩考。

2-1. 單元素/組件進(jìn)入離開(kāi)過(guò)渡

1. css過(guò)渡

vue提供了transition封裝組件夹孔,在以下情況下為任何單元素以及組件添加進(jìn)入/離開(kāi)過(guò)渡。

  • 條件渲染v-if / 條件展示v-show
  • 動(dòng)態(tài)組件
  • 組件根節(jié)點(diǎn)

例子如下:

<div>
    <button @click="show = !show">切換</button>
    <transition name="fade">
        <p v-if="show">看我顯示隱藏!!!</p>
    </transition>
</div>
.fade-enter-active {
  transition: all 0.5s ease;
}

.fade-leave-active {
  transition: all 0.9s cubic-bezier(1, 0.5, 0.8, 1);
}
.fade-enter,
.fade-leave-to {
  opacity: 0;
  transform: translateX(20px);
}

2. css動(dòng)畫(huà)

CSS 動(dòng)畫(huà)用法同 CSS 過(guò)渡析孽,區(qū)別是在動(dòng)畫(huà)中 v-enter 類名在節(jié)點(diǎn)插入 DOM 后不會(huì)立即刪除搭伤,而是在 animationend 事件觸發(fā)時(shí)刪除。

<transition name="bounce">
    <div style="width:300px;height:400px;" v-if="show">
        Lorem ipsum dolor sit amet, consectetur adipiscing elit. Mauris facilisis enim libero, at lacinia diam fermentum id.
        Pellentesque habitant morbi tristique senectus et netus.
    </div>
</transition>

3. javascript鉤子函數(shù)

可以在<transition>組件上聲明JavaScript鉤子函數(shù)袜瞬。

<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>
methods: {
  // ----  進(jìn)入中 ------
  beforeEnter: function (el) {
  },
  // 當(dāng)與 CSS 結(jié)合使用時(shí)
  // 回調(diào)函數(shù) done 是可選的
  enter: function (el, done) {
    // ...
    done()
  },
  afterEnter: function (el) {
    // ...
  },
  enterCancelled: function (el) {
    // ...
  }
}

4. 過(guò)渡的類名

進(jìn)入/離開(kāi)過(guò)渡的類名

  1. v-enter:定義過(guò)渡的開(kāi)始狀態(tài)怜俐。在元素插入之前生效,在元素被插入的下一幀移除
  2. v-enter-active:定義過(guò)渡生效時(shí)候的狀態(tài)邓尤。在整個(gè)進(jìn)入過(guò)渡的階段中應(yīng)用拍鲤。這個(gè)類可以被用來(lái)定義進(jìn)入過(guò)渡的過(guò)程時(shí)間贴谎,延遲和曲線函數(shù)
  3. v-enter-to:定義過(guò)渡的結(jié)束狀態(tài)。在元素被插入之后下一幀生效季稳,在過(guò)渡/動(dòng)畫(huà)完成之后移除擅这。
  4. v-leave:定義離開(kāi)過(guò)渡的開(kāi)始狀態(tài)。在離開(kāi)過(guò)渡被觸發(fā)時(shí)立刻生效景鼠,下一幀被移除仲翎。
  5. v-leave-active:定義離開(kāi)過(guò)渡生效時(shí)的狀態(tài)。在整個(gè)離開(kāi)過(guò)渡的階段中應(yīng)用铛漓。
  6. v-leave-to:定義離開(kāi)過(guò)渡的結(jié)束狀態(tài)溯香。
  • <transition name="fade"> 組件中,通過(guò)name屬性浓恶,定義過(guò)渡的類名逐哈;如果沒(méi)有命名,則使用默認(rèn)的v-為類名的前綴问顷,例如:v-enter...
  • 我們還可以自定義過(guò)渡的類名:enter-class,enter-active-class,enter-to-class,leave-class,leave-active-class,leave-to-class。它們的優(yōu)先級(jí)高于普通的類名禀梳。

代碼如下:

<button @click="show = !show">切換</button>
<transition 
            name="custom-classes-transition" 
            enter-active-class="animated tada"
            leave-active-class="animated bounceOutRight"
            >
    <p v-if="show">看我杜窄!</p>
</transition>
.bounce-enter-active {
  animation: bounce-in 0.5s;
}

.bounce-leave-active {
  animation: bounce-in 0.5s reverse;
}

@keyframes bounce-in {
  0% {
    transform: scale(0);
  }
  50% {
    transform: scale(1.5);
  }
  0% {
    transform: scale(1);
  }
}

5. 同時(shí)使用css過(guò)渡/動(dòng)畫(huà)

使用 type 特性并設(shè)置 animationtransition 來(lái)明確聲明你需要 Vue 監(jiān)聽(tīng)的類型。

6. 過(guò)渡持續(xù)事件

<transition> 組件上的 duration 屬性定制一個(gè)顯性的過(guò)渡持續(xù)時(shí)間 (以毫秒計(jì)):

<transition :duration="1000">...</transition>
<transition :duration="{ enter: 500, leave: 800 }">...</transition>

7. 初始渲染的過(guò)渡

使用apear特性設(shè)置節(jié)點(diǎn)在初始渲染的過(guò)渡算途。與進(jìn)入和離開(kāi)一樣塞耕,可以自定義css類名以及javascript鉤子函數(shù)。

<transition
  appear
  appear-class="custom-appear-class"
  appear-to-class="custom-appear-to-class"
  appear-active-class="custom-appear-active-class"
>
  <!-- ... -->
</transition>
<transition
  appear
  v-on:before-appear="customBeforeAppearHook"
  v-on:appear="customAppearHook"
  v-on:after-appear="customAfterAppearHook"
  v-on:appear-cancelled="customAppearCancelledHook"
>
  <!-- ... -->
</transition>

8. 多個(gè)元素/組件 過(guò)渡

  • <transition>內(nèi)如果是原生標(biāo)簽嘴瓤,可以使用v-if/ v-else扫外。

注意事項(xiàng):當(dāng)有相同標(biāo)簽名的元素切換時(shí),需要給在 <transition> 組件中的多個(gè)元素設(shè)置 key 是一個(gè)更好的實(shí)踐廓脆。

  • 多組件過(guò)渡筛谚,不需要提供key,只需要使用動(dòng)態(tài)組件停忿。
<transition>
    <button v-if="isEditing" key="save"> Save </button>
    <button v-else key="edit"> Edit </button>
</transition>

9. vue 提供的過(guò)渡模式

  • in-out:新元素先進(jìn)行過(guò)渡驾讲,完成之后當(dāng)前元素過(guò)渡離開(kāi)。
  • out-in:當(dāng)前元素先進(jìn)行過(guò)渡席赂,完成之后新元素過(guò)渡進(jìn)入吮铭。

2-2 列表過(guò)渡

在使用v-for同時(shí)渲染整個(gè)列表的時(shí)候,可以使用<transition-group>組件颅停。其與<transition>組件的區(qū)別:

  • 以真實(shí)元素呈現(xiàn)谓晌,默認(rèn)是<span>,可以通過(guò)tag屬性更換其他元素。
  • 過(guò)渡模式不可用
  • 內(nèi)部元素總是需要提供key屬性值

列表的三種過(guò)渡模式:

  1. 列表的進(jìn)入/離開(kāi)過(guò)渡
  2. 列表的排序過(guò)渡
  3. 列表的交錯(cuò)過(guò)渡

代碼匯總?cè)缦拢?/p>

<!-- 1. 列表交錯(cuò)過(guò)渡 -->
<div id="staggered-list-demo">
    <input v-model="query">
    <transition-group
          name="staggered-fade"
          tag="ul"
          v-bind:css="false"
          v-on:before-enter="beforeEnter"
          v-on:enter="enter"
          v-on:leave="leave"
          >
        <li
            v-for="(item, index) in computedList"
            v-bind:key="item.msg"
            v-bind:data-index="index"
            >{{ item.msg }}</li>
    </transition-group>
</div>

 <!-- 2. 列表進(jìn)入-離開(kāi)過(guò)渡 -->
<button @click="add">add</button>
<button @click="remove">remove</button>
<transition-group tag="p" name="list">
    <span v-for="item in items" :key="item" class="list-item">{{item}}</span>
</transition-group>

<!-- 3. 列表排序過(guò)渡 -->
<button @click="Shuffle">Shuffle</button>
<transition-group tag="ul" name="flip-list">
    <li v-for="item in items" :key="item" class="list-item">{{item}}</li>
</transition-group>
export default {
  name: "listTransition",
  data() {
    return {
      list: [
        { msg: "Bruce Lee" },
        { msg: "Jackie Chan" },
        { msg: "Chuck Norris" },
        { msg: "Jet Li" },
        { msg: "Kung Fury" }
      ],
      items: [1, 2, 3, 4, 5, 6, 7, 8, 9],
      nextNum: 10
    };
  },
  computed: {
    computedList: function() {
      var vm = this;
      return this.list.filter(function(item) {
        return item.msg.toLowerCase().indexOf(vm.query.toLowerCase()) !== -1;
      });
    }
  },
  methods: {
    // 1. 當(dāng)只用 JavaScript 過(guò)渡的時(shí)候癞揉,在 enter 和 leave 中必須使用 done 進(jìn)行回調(diào)纸肉。否則溺欧,它們將被同步調(diào)用,過(guò)渡會(huì)立即完成毁靶。
    // 2. 推薦對(duì)于僅使用 JavaScript 過(guò)渡的元素添加 v-bind:css="false"胧奔,Vue 會(huì)跳過(guò) CSS 的檢測(cè)。這也可以避免過(guò)渡過(guò)程中 CSS 的影響预吆。
    // appear 特性設(shè)置節(jié)點(diǎn)在初始渲染的過(guò)渡
    // <transition-group>組件 用于列表進(jìn)入離開(kāi)過(guò)渡  / 排序過(guò)渡(v-move)
    //  自定義類名前綴:(1)name屬性 (2)move-class/enter-class...屬性手動(dòng)設(shè)置
    beforeEnter: function(el) {
      el.style.opacity = 0;
      el.style.height = 0;
    },
    enter: function(el, done) {
      var delay = el.dataset.index * 150;
      setTimeout(function() {
        Velocity(el, { opacity: 1, height: "1.6em" }, { complete: done });
      }, delay);
    },
    leave: function(el, done) {
      var delay = el.dataset.index * 150;
      setTimeout(function() {
        Velocity(el, { opacity: 0, height: 0 }, { complete: done });
      }, delay);
    },

    // 2. 列表進(jìn)入-離開(kāi)過(guò)渡
    randomIndex: function() {
      return Math.floor(Math.random() * this.items.length);
    },
    add() {
      this.items.splice(this.randomIndex(), 0, this.nextNum++);
    },
    remove() {
      this.items.splice(this.randomIndex(), 1);
    },

    // 3. 列表-排序過(guò)渡
    Shuffle() {
      this.items = _.shuffle(this.items);
    }
  }
};
/* 2. 進(jìn)入離開(kāi)過(guò)渡-列表 */
.list-item {
  margin-right: 20px;
  display: inline-block;
}

.list-enter-active,
.list-leave-active {
  transition: all 1s;
}
.list-enter,
.list-leave-to {
  opacity: 0;
  transform: translateY(30px);
}

/*  排序 */
.flip-list-move{
  transition: transform 1s;
}
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末龙填,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子拐叉,更是在濱河造成了極大的恐慌岩遗,老刑警劉巖,帶你破解...
    沈念sama閱讀 212,294評(píng)論 6 493
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件凤瘦,死亡現(xiàn)場(chǎng)離奇詭異宿礁,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)蔬芥,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,493評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門(mén)梆靖,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人笔诵,你說(shuō)我怎么就攤上這事返吻。” “怎么了乎婿?”我有些...
    開(kāi)封第一講書(shū)人閱讀 157,790評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵测僵,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我谢翎,道長(zhǎng)捍靠,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 56,595評(píng)論 1 284
  • 正文 為了忘掉前任森逮,我火速辦了婚禮榨婆,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘褒侧。我一直安慰自己纲辽,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,718評(píng)論 6 386
  • 文/花漫 我一把揭開(kāi)白布璃搜。 她就那樣靜靜地躺著拖吼,像睡著了一般。 火紅的嫁衣襯著肌膚如雪这吻。 梳的紋絲不亂的頭發(fā)上吊档,一...
    開(kāi)封第一講書(shū)人閱讀 49,906評(píng)論 1 290
  • 那天,我揣著相機(jī)與錄音唾糯,去河邊找鬼怠硼。 笑死鬼贱,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的香璃。 我是一名探鬼主播这难,決...
    沈念sama閱讀 39,053評(píng)論 3 410
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼葡秒!你這毒婦竟也來(lái)了姻乓?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 37,797評(píng)論 0 268
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤眯牧,失蹤者是張志新(化名)和其女友劉穎蹋岩,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體学少,經(jīng)...
    沈念sama閱讀 44,250評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡剪个,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,570評(píng)論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了版确。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片扣囊。...
    茶點(diǎn)故事閱讀 38,711評(píng)論 1 341
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖绒疗,靈堂內(nèi)的尸體忽然破棺而出侵歇,到底是詐尸還是另有隱情,我是刑警寧澤忌堂,帶...
    沈念sama閱讀 34,388評(píng)論 4 332
  • 正文 年R本政府宣布,位于F島的核電站酗洒,受9級(jí)特大地震影響士修,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜樱衷,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 40,018評(píng)論 3 316
  • 文/蒙蒙 一棋嘲、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧矩桂,春花似錦沸移、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,796評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至癞蚕,卻和暖如春蕊爵,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背桦山。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,023評(píng)論 1 266
  • 我被黑心中介騙來(lái)泰國(guó)打工攒射, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留醋旦,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 46,461評(píng)論 2 360
  • 正文 我出身青樓会放,卻偏偏與公主長(zhǎng)得像饲齐,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子咧最,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,595評(píng)論 2 350

推薦閱讀更多精彩內(nèi)容

  • 這篇筆記主要包含 Vue 2 不同于 Vue 1 或者特有的內(nèi)容捂人,還有我對(duì)于 Vue 1.0 印象不深的內(nèi)容。關(guān)于...
    云之外閱讀 5,046評(píng)論 0 29
  • Vue 實(shí)例 屬性和方法 每個(gè) Vue 實(shí)例都會(huì)代理其 data 對(duì)象里所有的屬性:var data = { a:...
    云之外閱讀 2,204評(píng)論 0 6
  • 混合 組件系統(tǒng)是Vue的核心窗市,如何合理的規(guī)劃組件先慷,是我們?cè)陂_(kāi)發(fā)中需要深入思考的問(wèn)題,我個(gè)人習(xí)慣把一些組件使用邏輯和...
    li4065閱讀 842評(píng)論 0 1
  • 混合 組件系統(tǒng)是Vue的核心,如何合理的規(guī)劃組件摄狱,是我們?cè)陂_(kāi)發(fā)中需要深入思考的問(wèn)題脓诡,我個(gè)人習(xí)慣把一些組件使用邏輯和...
    去年的牛肉閱讀 630評(píng)論 0 1
  • 概述 Vue 在插入、更新或者移除 DOM 時(shí)媒役,提供多種不同方式的應(yīng)用過(guò)渡效果祝谚。包括以下工具: 在 CSS 過(guò)渡和...
    寒梁沐月閱讀 1,324評(píng)論 0 3