99re热这里只有精品视频,7777色鬼xxxx欧美色妇,国产成人精品一区二三区在线观看,内射爽无广熟女亚洲,精品人妻av一区二区三区

Vue 3.0 進入過渡&離開過渡

2021-07-16 11:32 更新

在插入、更新或從 DOM 中移除項時,Vue 提供了多種應用轉換效果的方法。這包括以下工具:

  • 自動為 CSS 轉換和動畫應用 class;
  • 集成第三方 CSS 動畫庫,例如 animate.css
  • 在過渡鉤子期間使用 JavaScript 直接操作 DOM;
  • 集成第三方 JavaScript 動畫庫。

在這里,我們只會講到進入、離開和列表的過渡,你也可以看下一節(jié)的管理過渡狀態(tài) 。

#單元素/組件的過渡

Vue 提供了 transition 的封裝組件,在下列情形中,可以給任何元素和組件添加進入/離開過渡

  • 條件渲染 (使用 v-if)
  • 條件展示 (使用 v-show)
  • 動態(tài)組件
  • 組件根節(jié)點

這里是一個典型的例子:

<div id="demo">
  <button @click="show = !show">
    Toggle
  </button>


  <transition name="fade">
    <p v-if="show">hello</p>
  </transition>
</div>

const Demo = {
  data() {
    return {
      show: true
    }
  }
}


Vue.createApp(Demo).mount('#demo')

.fade-enter-active,
.fade-leave-active {
  transition: opacity 0.5s ease;
}


.fade-enter-from,
.fade-leave-to {
  opacity: 0;
}

點擊此處實現

當插入或刪除包含在 transition 組件中的元素時,Vue 將會做以下處理:

  1. 自動嗅探目標元素是否應用了 CSS 過渡或動畫,如果是,在恰當的時機添加/刪除 CSS 類名。
  2. 如果過渡組件提供了 JavaScript 鉤子函數 ,這些鉤子函數將在恰當的時機被調用。
  3. 如果沒有找到 JavaScript 鉤子并且也沒有檢測到 CSS 過渡/動畫,DOM 操作 (插入/刪除) 在下一幀中立即執(zhí)行。(注意:此指瀏覽器逐幀動畫機制,和 Vue 的 nextTick 概念不同)

#過渡class

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

  1. v-enter-from:定義進入過渡的開始狀態(tài)。在元素被插入之前生效,在元素被插入之后的下一幀移除。
  2. v-enter-active:定義進入過渡生效時的狀態(tài)。在整個進入過渡的階段中應用,在元素被插入之前生效,在過渡/動畫完成之后移除。這個類可以被用來定義進入過渡的過程時間,延遲和曲線函數。
  3. v-enter-to:定義進入過渡的結束狀態(tài)。在元素被插入之后下一幀生效 (與此同時 v-enter-from 被移除),在過渡/動畫完成之后移除。
  4. v-leave-from:定義離開過渡的開始狀態(tài)。在離開過渡被觸發(fā)時立刻生效,下一幀被移除。
  5. v-leave-active:定義離開過渡生效時的狀態(tài)。在整個離開過渡的階段中應用,在離開過渡被觸發(fā)時立刻生效,在過渡/動畫完成之后移除。這個類可以被用來定義離開過渡的過程時間,延遲和曲線函數。
  6. v-leave-to:離開過渡的結束狀態(tài)。在離開過渡被觸發(fā)之后下一幀生效 (與此同時 v-leave-from 被刪除),在過渡/動畫完成之后移除。

對于這些在過渡中切換的類名來說,如果你使用一個沒有名字的 <transition>,則 v- 是這些class名的默認前綴。如果你使用了 <transition name="my-transition">,那么 v-enter-from會替換為 my-transition-enter-from

v-enter-activev-leave-active 可以控制進入/離開過渡的不同的緩和曲線,在下面章節(jié)會有個示例說明。

#CSS 過渡

常用的過渡都是使用 CSS 過渡。

<div id="demo">
  <button @click="show = !show">
    Toggle render
  </button>


  <transition name="slide-fade">
    <p v-if="show">hello</p>
  </transition>
</div>

const Demo = {
  data() {
    return {
      show: true
    }
  }
}


Vue.createApp(Demo).mount('#demo')

/* 可以設置不同的進入和離開動畫   */
/* 設置持續(xù)時間和動畫函數        */
.slide-fade-enter-active {
  transition: all 0.3s ease-out;
}


.slide-fade-leave-active {
  transition: all 0.8s cubic-bezier(1, 0.5, 0.8, 1);
}


.slide-fade-enter-from,
.slide-fade-leave-to {
  transform: translateX(20px);
  opacity: 0;
}

點擊此處實現

#CSS 動畫

CSS 動畫用法同 CSS 過渡,區(qū)別是在動畫中 v-enter-from 類名在節(jié)點插入 DOM 后不會立即刪除,而是在 animationend 事件觸發(fā)時刪除。

下面是一個例子,為了簡潔起見,省略了帶前綴的 CSS 規(guī)則:

<div id="demo">
  <button @click="show = !show">Toggle show</button>
  <transition name="bounce">
    <p 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.
    </p>
  </transition>
</div>

const Demo = {
  data() {
    return {
      show: true
    }
  }
}


Vue.createApp(Demo).mount('#demo')

.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.25);
  }
  100% {
    transform: scale(1);
  }
}

點擊此處實現

#自定義過渡 class 類名

我們可以通過以下 attribute 來自定義過渡類名:

  • enter-from-class
  • enter-active-class
  • enter-to-class
  • leave-from-class
  • leave-active-class
  • leave-to-class

他們的優(yōu)先級高于普通的類名,這對于 Vue 的過渡系統(tǒng)和其他第三方 CSS 動畫庫,如 Animate.css. 結合使用十分有用。

示例:

<link
   rel="external nofollow" target="_blank" 
  rel="stylesheet"
  type="text/css"
/>


<div id="demo">
  <button @click="show = !show">
    Toggle render
  </button>


  <transition
    name="custom-classes-transition"
    enter-active-class="animate__animated animate__tada"
    leave-active-class="animate__animated animate__bounceOutRight"
  >
    <p v-if="show">hello</p>
  </transition>
</div>

const Demo = {
  data() {
    return {
      show: true
    }
  }
}


Vue.createApp(Demo).mount('#demo')

#同時使用過渡和動畫

Vue 為了知道過渡的完成,必須設置相應的事件監(jiān)聽器。它可以是 transitionendanimationend,這取決于給元素應用的 CSS 規(guī)則。如果你使用其中任何一種,Vue 能自動識別類型并設置監(jiān)聽。

但是,在一些場景中,你需要給同一個元素同時設置兩種過渡動效,比如 animation 很快的被觸發(fā)并完成了,而 transition 效果還沒結束。在這種情況中,你就需要使用 type attribute 并設置 animationtransition 來明確聲明你需要 Vue 監(jiān)聽的類型。

#顯性的過渡持續(xù)時間

在很多情況下,Vue 可以自動得出過渡效果的完成時機。默認情況下,Vue 會等待其在過渡效果的根元素的第一個 transitionendanimationend 事件。然而也可以不這樣設定——比如,我們可以擁有一個精心編排的一系列過渡效果,其中一些嵌套的內部元素相比于過渡效果的根元素有延遲的或更長的過渡效果。

在這種情況下你可以用 <transition> 組件上的 duration prop 定制一個顯性的過渡持續(xù)時間 (以毫秒計):

<transition :duration="1000">...</transition>

你也可以定制進入和移出的持續(xù)時間:

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

#JavaScript 鉤子

可以在 attribute 中聲明 JavaScript 鉤子

<transition
  @before-enter="beforeEnter"
  @enter="enter"
  @after-enter="afterEnter"
  @enter-cancelled="enterCancelled"
  @before-leave="beforeLeave"
  @leave="leave"
  @after-leave="afterLeave"
  @leave-cancelled="leaveCancelled"
  :css="false"
>
  <!-- ... -->
</transition>

// ...
methods: {
  // --------
  // ENTERING
  // --------


  beforeEnter(el) {
    // ...
  },
  // 當與 CSS 結合使用時
  // 回調函數 done 是可選的
  enter(el, done) {
    // ...
    done()
  },
  afterEnter(el) {
    // ...
  },
  enterCancelled(el) {
    // ...
  },


  // --------
  // 離開時
  // --------


  beforeLeave(el) {
    // ...
  },
  // 當與 CSS 結合使用時
  // 回調函數 done 是可選的
  leave(el, done) {
    // ...
    done()
  },
  afterLeave(el) {
    // ...
  },
  // leaveCancelled 只用于 v-show 中
  leaveCancelled(el) {
    // ...
  }
}

這些鉤子函數可以結合 CSS transitions/animations 使用,也可以單獨使用。

當只用 JavaScript 過渡的時候,在 enterleave 鉤中必須使用 done 進行回調。否則,它們將被同步調用,過渡會立即完成。添加 :css="false",也會讓 Vue 會跳過 CSS 的檢測,除了性能略高之外,這可以避免過渡過程中 CSS 規(guī)則的影響。

現在讓我們來看一個例子。下面是一個使用 GreenSock 的 JavaScript 過渡:

<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.3.4/gsap.min.js" rel="external nofollow" ></script>


<div id="demo">
  <button @click="show = !show">
    Toggle
  </button>


  <transition
    @before-enter="beforeEnter"
    @enter="enter"
    @leave="leave"
    :css="false"
  >
    <p v-if="show">
      Demo
    </p>
  </transition>
</div>

const Demo = {
  data() {
    return {
      show: false
    }
  },
  methods: {
    beforeEnter(el) {
      gsap.set(el, {
        scaleX: 0.8,
        scaleY: 1.2
      })
    },
    enter(el, done) {
      gsap.to(el, {
        duration: 1,
        scaleX: 1.5,
        scaleY: 0.7,
        opacity: 1,
        x: 150,
        ease: 'elastic.inOut(2.5, 1)',
        onComplete: done
      })
    },
    leave(el, done) {
      gsap.to(el, {
        duration: 0.7,
        scaleX: 1,
        scaleY: 1,
        x: 300,
        ease: 'elastic.inOut(2.5, 1)'
      })
      gsap.to(el, {
        duration: 0.2,
        delay: 0.5,
        opacity: 0,
        onComplete: done
      })
    }
  }
}


Vue.createApp(Demo).mount('#demo')

點擊此處實現

#初始渲染的過渡

可以通過 appear attribute 設置節(jié)點在初始渲染的過渡

<transition appear>
  <!-- ... -->
</transition>

#多個元素的過渡

我們之后討論多個組件的過渡,對于原生標簽可以使用 v-if/v-else。最常見的多標簽過渡是一個列表和描述這個列表為空消息的元素:

<transition>
  <table v-if="items.length > 0">
    <!-- ... -->
  </table>
  <p v-else>Sorry, no items found.</p>
</transition>

實際上,通過使用多個 v-if 或將單個元素綁定到一個動態(tài) property,可以在任意數量的元素之間進行過渡。例如:

<transition>
  <button v-if="docState === 'saved'" key="saved">
    Edit
  </button>
  <button v-if="docState === 'edited'" key="edited">
    Save
  </button>
  <button v-if="docState === 'editing'" key="editing">
    Cancel
  </button>
</transition>

也可以寫為:

<transition>
  <button :key="docState">
    {{ buttonMessage }}
  </button>
</transition>

// ...
computed: {
  buttonMessage() {
    switch (this.docState) {
      case 'saved': return 'Edit'
      case 'edited': return 'Save'
      case 'editing': return 'Cancel'
    }
  }
}

#過渡模式

這里還有一個問題,試著點擊下面的按鈕:

點擊此處實現

在“on”按鈕和“off”按鈕的過渡中,兩個按鈕都被重繪了,一個離開過渡的時候另一個開始進入過渡。這是 <transition> 的默認行為 —— 進入和離開同時發(fā)生。

有時這很有效,例如當過渡項絕對位于彼此的 top 時:

點擊此處實現

同時生效的進入和離開的過渡不能滿足所有要求,所以 Vue 提供了過渡模式

  • in-out: 新元素先進行過渡,完成之后當前元素過渡離開。
  • out-in: 當前元素先進行過渡,完成之后新元素過渡進入。

TIP

很快就會發(fā)現 out-in 是你大多數時候想要的狀態(tài) ????

現在讓我們用 out-in 更新 on/off 按鈕的轉換:

<transition name="fade" mode="out-in">
  <!-- ... the buttons ... -->
</transition>

點擊此處實現

通過添加一個 attribute,我們修復了原來的過渡,而不必添加任何特殊 style。

我們可以用它來協(xié)調更具表現力的動作,例如折疊卡片,如下所示。實際上是兩個元素在彼此之間轉換,但是由于開始狀態(tài)和結束狀態(tài)的比例是相同的:水平為0,它看起來就像一個流體運動。這種輕描淡寫對于真實的 UI 微交互非常有用:

點擊此處實現

#多個組件之間過渡

組件之間的過渡更簡單 —— 我們甚至不需要 key 屬性。相反,我們包裝了一個動態(tài)組件

<div id="demo">
  <input v-model="view" type="radio" value="v-a" id="a"><label for="a">A</label>
  <input v-model="view" type="radio" value="v-b" id="b"><label for="b">B</label>
  <transition name="component-fade" mode="out-in">
    <component :is="view"></component>
  </transition>
</div>

const Demo = {
  data() {
    return {
      view: 'v-a'
    }
  },
  components: {
    'v-a': {
      template: '<div>Component A</div>'
    },
    'v-b': {
      template: '<div>Component B</div>'
    }
  }
}


Vue.createApp(Demo).mount('#demo')

.component-fade-enter-active,
.component-fade-leave-active {
  transition: opacity 0.3s ease;
}


.component-fade-enter-from,
.component-fade-leave-to {
  opacity: 0;
}

點擊此處實現

以上內容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號