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

Vue 3.0 列表過渡

2021-07-16 11:35 更新

目前為止,關于過渡我們已經(jīng)講到:

  • 單個節(jié)點
  • 同一時間渲染多個節(jié)點中的一個

那么怎么同時渲染整個列表,比如使用 v-for?在這種場景中,使用 <transition-group> 組件。在我們深入例子之前,先了解關于這個組件的幾個特點:

  • 不同于 <transition>,它會以一個真實元素渲染:默認為一個 <span>。你也可以通過 tag attribute 更換為其他元素。
  • 過渡模式不可用,因為我們不再相互切換特有的元素。
  • 內(nèi)部元素總是需要提供唯一的 key attribute 值。
  • CSS 過渡的類將會應用在內(nèi)部的元素中,而不是這個組/容器本身。

#列表的進入/離開過渡

現(xiàn)在讓我們由一個簡單的例子深入,進入和離開的過渡使用之前一樣的 CSS class 名。

<div id="list-demo">
  <button @click="add">Add</button>
  <button @click="remove">Remove</button>
  <transition-group name="list" tag="p">
    <span v-for="item in items" :key="item" class="list-item">
      {{ item }}
    </span>
  </transition-group>
</div>

const Demo = {
  data() {
    return {
      items: [1, 2, 3, 4, 5, 6, 7, 8, 9],
      nextNum: 10
    }
  },
  methods: {
    randomIndex() {
      return Math.floor(Math.random() * this.items.length)
    },
    add() {
      this.items.splice(this.randomIndex(), 0, this.nextNum++)
    },
    remove() {
      this.items.splice(this.randomIndex(), 1)
    }
  }
}


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

.list-item {
  display: inline-block;
  margin-right: 10px;
}
.list-enter-active,
.list-leave-active {
  transition: all 1s ease;
}
.list-enter-from,
.list-leave-to {
  opacity: 0;
  transform: translateY(30px);
}

點擊此處實現(xiàn)

這個例子有個問題,當添加和移除元素的時候,周圍的元素會瞬間移動到他們的新布局的位置,而不是平滑的過渡,我們下面會解決這個問題。

#列表的排序過渡

<transition-group> 組件還有一個特殊之處。不僅可以進入和離開動畫,還可以改變定位。要使用這個新功能只需了解新增的 v-move class,它會在元素的改變定位的過程中應用。像之前的類名一樣,可以通過 name attribute 來自定義前綴,也可以通過 move-class attribute 手動設置。

該 class 主要用于指定過渡 timing 和 easing 曲線,如下所示:

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


<div id="flip-list-demo">
  <button @click="shuffle">Shuffle</button>
  <transition-group name="flip-list" tag="ul">
    <li v-for="item in items" :key="item">
      {{ item }}
    </li>
  </transition-group>
</div>

const Demo = {
  data() {
    return {
      items: [1, 2, 3, 4, 5, 6, 7, 8, 9]
    }
  },
  methods: {
    shuffle() {
      this.items = _.shuffle(this.items)
    }
  }
}


Vue.createApp(Demo).mount('#flip-list-demo')

.flip-list-move {
  transition: transform 0.8s ease;
}

點擊此處實現(xiàn)

這個看起來很神奇,內(nèi)部的實現(xiàn),Vue 使用了一個叫 FLIP 簡單的動畫隊列使用 transforms 將元素從之前的位置平滑過渡新的位置。

我們將之前實現(xiàn)的例子和這個技術結(jié)合,使我們列表的一切變動都會有動畫過渡。

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


<div id="list-complete-demo" class="demo">
  <button @click="shuffle">Shuffle</button>
  <button @click="add">Add</button>
  <button @click="remove">Remove</button>
  <transition-group name="list-complete" tag="p">
    <span v-for="item in items" :key="item" class="list-complete-item">
      {{ item }}
    </span>
  </transition-group>
</div>

const Demo = {
  data() {
    return {
      items: [1, 2, 3, 4, 5, 6, 7, 8, 9],
      nextNum: 10
    }
  },
  methods: {
    randomIndex() {
      return Math.floor(Math.random() * this.items.length)
    },
    add() {
      this.items.splice(this.randomIndex(), 0, this.nextNum++)
    },
    remove() {
      this.items.splice(this.randomIndex(), 1)
    },
    shuffle() {
      this.items = _.shuffle(this.items)
    }
  }
}


Vue.createApp(Demo).mount('#list-complete-demo')

.list-complete-item {
  transition: all 0.8s ease;
  display: inline-block;
  margin-right: 10px;
}


.list-complete-enter-from,
.list-complete-leave-to {
  opacity: 0;
  transform: translateY(30px);
}


.list-complete-leave-active {
  position: absolute;
}

點擊此處實現(xiàn)

TIP

需要注意的是使用 FLIP 過渡的元素不能設置為 display: inline。作為替代方案,可以設置為 display: inline-block 或者放置于 flex 中

FLIP 動畫不僅可以實現(xiàn)單列過渡,多維網(wǎng)格也同樣可以過渡

TODO:示例

#列表的交錯過渡

通過 data attribute 與 JavaScript 通信,就可以實現(xiàn)列表的交錯過渡:

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


<div id="demo">
  <input v-model="query" />
  <transition-group
    name="staggered-fade"
    tag="ul"
    :css="false"
    @before-enter="beforeEnter"
    @enter="enter"
    @leave="leave"
  >
    <li
      v-for="(item, index) in computedList"
      :key="item.msg"
      :data-index="index"
    >
      {{ item.msg }}
    </li>
  </transition-group>
</div>

const Demo = {
  data() {
    return {
      query: '',
      list: [
        { msg: 'Bruce Lee' },
        { msg: 'Jackie Chan' },
        { msg: 'Chuck Norris' },
        { msg: 'Jet Li' },
        { msg: 'Kung Fury' }
      ]
    }
  },
  computed: {
    computedList() {
      var vm = this
      return this.list.filter(item => {
        return item.msg.toLowerCase().indexOf(vm.query.toLowerCase()) !== -1
      })
    }
  },
  methods: {
    beforeEnter(el) {
      el.style.opacity = 0
      el.style.height = 0
    },
    enter(el, done) {
      gsap.to(el, {
        opacity: 1,
        height: '1.6em',
        delay: el.dataset.index * 0.15,
        onComplete: done
      })
    },
    leave(el, done) {
      gsap.to(el, {
        opacity: 0,
        height: 0,
        delay: el.dataset.index * 0.15,
        onComplete: done
      })
    }
  }
}


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

點擊此處實現(xiàn)

#可復用的過渡

過渡可以通過 Vue 的組件系統(tǒng)實現(xiàn)復用。要創(chuàng)建一個可復用過渡組件,你需要做的就是將 <transition> 或者 <transition-group> 作為根組件,然后將任何子組件放置在其中就可以了。

TODO:使用 Vue3 重構(gòu)

使用 template 的簡單例子:

Vue.component('my-special-transition', {
  template: '\
    <transition\
      name="very-special-transition"\
      mode="out-in"\
      @before-enter="beforeEnter"\
      @after-enter="afterEnter"\
    >\
      <slot></slot>\
    </transition>\
  ',
  methods: {
    beforeEnter(el) {
      // ...
    },
    afterEnter(el) {
      // ...
    }
  }
})

函數(shù)式組件更適合完成這個任務:

Vue.component('my-special-transition', {
  functional: true,
  render: function(createElement, context) {
    var data = {
      props: {
        name: 'very-special-transition',
        mode: 'out-in'
      },
      on: {
        beforeEnter(el) {
          // ...
        },
        afterEnter(el) {
          // ...
        }
      }
    }
    return createElement('transition', data, context.children)
  }
})

#動態(tài)過渡

在 Vue 中即使是過渡也是數(shù)據(jù)驅(qū)動的!動態(tài)過渡最基本的例子是通過 name attribute 來綁定動態(tài)值。

<transition :name="transitionName">
  <!-- ... -->
</transition>

當你想用 Vue 的過渡系統(tǒng)來定義的 CSS 過渡/動畫在不同過渡間切換會非常有用。

所有過渡 attribute 都可以動態(tài)綁定,但我們不僅僅只有 attribute 可以利用,還可以通過事件鉤子獲取上下文中的所有數(shù)據(jù),因為事件鉤子都是方法。這意味著,根據(jù)組件的狀態(tài)不同,你的 JavaScript 過渡會有不同的表現(xiàn)

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


<div id="dynamic-fade-demo" class="demo">
  Fade In:
  <input type="range" v-model="fadeInDuration" min="0" :max="maxFadeDuration" />
  Fade Out:
  <input
    type="range"
    v-model="fadeOutDuration"
    min="0"
    :max="maxFadeDuration"
  />
  <transition
    :css="false"
    @before-enter="beforeEnter"
    @enter="enter"
    @leave="leave"
  >
    <p v-if="show">hello</p>
  </transition>
  <button v-if="stop" @click="stop = false; show = false">
    Start animating
  </button>
  <button v-else @click="stop = true">Stop it!</button>
</div>

const app = Vue.createApp({
  data() {
    return {
      show: true,
      fadeInDuration: 1000,
      fadeOutDuration: 1000,
      maxFadeDuration: 1500,
      stop: true
    }
  },
  mounted() {
    this.show = false
  },
  methods: {
    beforeEnter(el) {
      el.style.opacity = 0
    },
    enter(el, done) {
      var vm = this
      Velocity(
        el,
        { opacity: 1 },
        {
          duration: this.fadeInDuration,
          complete: function() {
            done()
            if (!vm.stop) vm.show = false
          }
        }
      )
    },
    leave(el, done) {
      var vm = this
      Velocity(
        el,
        { opacity: 0 },
        {
          duration: this.fadeOutDuration,
          complete: function() {
            done()
            vm.show = true
          }
        }
      )
    }
  }
})


app.mount('#dynamic-fade-demo')

TODO:示例

最后,創(chuàng)建動態(tài)過渡的最終方案是組件通過接受 props 來動態(tài)修改之前的過渡。一句老話,唯一的限制是你的想象力。

以上內(nèi)容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號