Vue - запуск анимации при изменении вычисленного отфильтрованного списка

Со списком элементов, которые фильтруются с использованием вычисляемого свойства, как вы можете запустить анимацию в разметке результатов {{ filteredRows.length }} каждый раз, когда список фильтруется / обновляется.

.container#app

  transition name="fade"
    .filter.input-group.mb-3 Results:  
      strong {{ filteredRows.length }}

  .filter.input-group.mb-3  
    input.form-control(type="text" placeholder="Name Filter" v-model="filter_name")

  table.table
    thead
      tr
        th #
        th name
        th age
        th gender
    transition-group.list name="list" tag="tbody"
      tr(v-for="(r, index) in filteredRows.slice(pageStart, pageStart + countOfPage)")
        th {{ (currPage-1) * countOfPage + index + 1 }}
        td {{ r.name }}
        td {{ r.age }}
        td {{ r.gender }}

Javascript

var data = [
  {
    "index": 0, 
    "age": 56, 
    "_id": "574c06e5793fa069d8a9bb7d", 
    "name": "Flowers Harmon", 
    "gender": "male"
  }, 
  {
    "index": 1, 
    "age": 60, 
    "_id": "574c06e543a97c141d304414", 
    "name": "Angie Matthews", 
    "gender": "female"
  }, 
  ...
]
var app = new Vue({
  el: '#app',
  data: {
    rows: data,
    countOfPage: 5,
    currPage: 1,
    filter_name: ''
  },
  computed: {
    filteredRows: function(){
      var filter_name = this.filter_name.toLowerCase();
      return ( this.filter_name.trim() !== '' ) ? 
        this.rows.filter(function(d){ return d.name.toLowerCase().indexOf(filter_name) > -1; }) : 
      this.rows;
    },
    pageStart: function(){
        return (this.currPage - 1) * this.countOfPage;
      },
    totalPage: function(){
      return Math.ceil(this.filteredRows.length / this.countOfPage);
    }
  },
  methods: {
    setPage: function(idx){
      if( idx <= 0 || idx > this.totalPage ){
        return;
      }
      this.currPage = idx;
    },
  },
  // created: function(){
  // }
});

Вот рабочий пример https://codepen.io/ben_jammin/pen/JqQYaM?editors=1010

1 ответ

Решение

Переместить transition компонент, чтобы обернуть strong элемент вместо

strong элемент не будет заменяться каждый раз filteredRows.length изменения и анимация не будет работать, потому что:

При переключении между элементами с одинаковыми именами тегов вы должны указать Vue, что они являются отдельными элементами, предоставив им уникальные ключевые атрибуты. В противном случае компилятор Vue заменит содержимое элемента только для эффективности.

Так что вам нужно добавить key приписать strong элемент и использовать режим перехода:

  .filter.input-group.mb-3 Results:  
    transition(name="fade" mode="out-in")
      strong(:key="filteredRows.length") {{ filteredRows.length }}

Наконец, добавьте классы перехода для вашего имени перехода.

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

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

Пересмотренный CodePen

Другие вопросы по тегам