VueJS переходы не работают без setTimeout - PullRequest
0 голосов
/ 24 октября 2018

У меня есть код, чтобы выдвинуть меню, которое работает:

      Vue.set(this.filterStyles, filterIndex, {
        display: "block",
        height: "auto",
      });

      let filterValuesElHeight;
      Vue.nextTick().then(() => {
        let filterValuesEl = document.getElementById('parent-filter-values-' + filterIndex);
        filterValuesElHeight = filterValuesEl.clientHeight;

        Vue.set(this.filterStyles, filterIndex, {
          height: 0,
          display: "block"
        });

        return Vue.nextTick();
      }).then(() => {
        setTimeout(() => {
          Vue.set(this.filterStyles, filterIndex, {
            height: filterValuesElHeight + "px",
            display: "block"
          });
        }, 10);
      });

Первоначально меню настроено по следующим правилам:

display: none;
height: 0;
transition: all 500ms;

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

На следующем тике высота возвращается обратно к 0, а затем на последнем тике устанавливается ее естественная высота.

Тем не менее, кажется, что Vue.nextTick () недостаточно, хотя я заметил, что добавление очень маленького таймаута, кажется, делает эту работу.Это работает, но чувствует себя довольно грязно.Я надеялся, что у кого-то может быть лучшее решение?

1 Ответ

0 голосов
/ 24 октября 2018

Я предполагаю, что вы используете filterStyles в шаблоне, что-то вроде: :style="filterStyles".Если это так, то

Vue.set(this.filterStyles, filterIndex, {
    display: "block",
    height: "auto",
});

не установит высоту на auto сразу.Скорее, он обновляет данные компонента, и это обновление будет отражено в DOM после nextTick().Таким образом, по сути, ваш код отключен на один тик.

Однако стек из серии nextTick вызовов один за другим, вероятно, является плохой практикой.Например, если компонент удален во время серии, у вас останется свисающая ссылка.

Вы можете избежать всех этих тиков, просто установив стиль непосредственно, чтобы измерить его естественную высоту.Например, если элемент имеет атрибут ref="filter", то что-то вроде:

this.$refs.filter.style.height = "auto";
filterValuesElHeight = this.$refs.filter.clientHeight;
this.$refs.filter.style.height = "0";

Возможно, вам придется решить конфликты между шаблоном и встроенным JavaScript (я не могу сказать, потому что вы этого не делаетепокажи свой шаблон.), но с этого следует начать.

...