Почему Vue.nextTick() срабатывает ещё до рендеринга изменений?

Делаю прототип шаговой карусели / бесконечного горизонтального скролла для колонок широкой таблицы. Рендерятся только видимые колонки.

По событию клика вправо/влево добавляется новая колонка за кадром и колонкам изменяется их свойство left, а заранее назначенный transition делает плавную прокрутку на 1 шаг.

Компоненты колонок рендерятся через v-for из массива. По клику добавляю в начале/в хвосте 1 новый элемент в массив через обёрнутые методы push() или unshift(). После этого Vue.nextTick() и в нём, когда, по идее, новый элемент уже отрендерен с позицией «до», всем элементам обновляю позицию на «после», что меняет их свойство left и начинается transition.

Вот почему-то новые элементы появляются сразу в конечной позиции и анимация к ним не применяется.

Как позволить отрендериться компонентам после добавления в массив, и вызвать функцию после их отрисовки?

Upd. прототип довёл до желаемого поведения. При повторных нажатиях достраиваются элементы слева/справа и «едут» все в общем контейнере с transform: translate() Но теперь новая проблема, если зверски прыгать по стрелкам влево-вправо, и не давая анимации завершиться, запускать ее в противоположную сторону, "перевернув" её хотя бы 2 раза, по завершении в консоли вылетает ошибка самого Vue: TypeError: "e is undefined"
  • Вопрос задан
  • 1033 просмотра
Решения вопроса 1
potapchino
@potapchino
проблема не во Vue. проблема (а это на самом деле не проблема) в особенностях рендеринга браузера. за ничтожно малый промежуток времени к элементу применяется два одинаковых патча стилей, поэтому он их в целях оптимизации не рендерит два раза, а рендерит сразу второе положение. изменить это поведение можно если насильно спровоцировать reflow/repaint между двумя патчами, сделать это можно, например, запросив для чтения какое-нибудь св-во, например ширины элемента. т.е. как-то так:

<Box v-for="(item, index) in subset"
  ...
  :ref="`ref${index}`">


Vue.nextTick( () => {
  this.$refs.ref2[0].$el.clientWidth;
  ...
});


https://jsfiddle.net/f4qao1xt/
https://jsfiddle.net/dyuct4x9/
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы