Pull to refresh

Comments 20

Часто хочется анимировать появление какого-то блока неизвестных размеров, т.е. изменить его высоту с height: 0 до height: auto.

Анимируй не height, а max-height. Главное чтоб значение max-height было больше, чем элемент должен достигать. Тем самым установив элементу height: auto; max-height: 0; анимируешь уже только max-height.
<div id="menu">
    <a>hover me</a>
    <ul id="list">
        <!-- Create a bunch, or not a bunch, of li's to see the timing. -->
        <li>item</li>
        <li>item</li>
        <li>item</li>
        <li>item</li>
        <li>item</li>
    </ul>
</div>

#menu #list {
    max-height: 0;
    transition: max-height 0.15s ease-out;
    overflow: hidden;
    background: #d5d5d5;
}

#menu:hover #list {
    max-height: 500px;
    transition: max-height 0.25s ease-in;
}



Живой пример: jsfiddle
Вредный совет, высота неизвестна, а вы на глаз предлагаете подбирать.
Во первых не на глаз, а выставить максимально возможную для элемента, которую он не должен достигать. Во вторых это единственное решение, которое есть. В третьих, результат работы полностью удовлетворительный.
1. У вас 1000 компонентов плавно изменяющих высоту, в разных местах приложения. Откуда вы узнаете максимально возможную высоту?
2. Блок с высотой 500px будет анимироваться 200мс, а с высотой 100px уже 40мс.
Единственно правильное решение — это мерить элемент javascript'ом.
Речь шла исключительно о решении на CSS. Оно есть, оно не идеальное, есть подводные камни, но тем не менее, факт его существования и возможность его применения отрицать нельзя. И не надо приплетать хитровымудренные примеры, когда оно не может быть применено, для каждого решения есть своя область применения.
По хорошему, если вдруг очень нужно анимировать что-то кроме transform или opacity, например высоту как в данном случае, что влечёт перерасчёт макета страницы, то лучше использовать методику First Last Invert Play с помощью js. Немного мудрённо, но для для перформанса хорошо.

Это решение нечестное. Нужно заранее в CSS выставить max-height. Это получится только для фиксированных выпадающих меню, а у автора в проекте это используется для динамического списка точек. Придется ставить заведомо большее значение, что-то вроде 10000px.


А если вы выставите такое значение в своем демо, то заметите, что анимация выпадения сильно ускорилась. Это происходит потому, что браузер рассчитывает кадры, исходя из высоты от 0 до 10000, хотя реальная высота блока будет намного меньше.


В общем, чтобы получить нормальную анимацию, когда она всегда отрабатывает за фиксированные N секунд, нужно добавить немного Javascript.


А метод с max-height сгодится лишь для фиксированных блоков из 5 элементов, или прототипов, которые все равно придется переделывать нормально.

Спасибо, познавательно. Особенно в части мутаций.


Я использую webpack-svgstore-plugin.
Также можно подключить директиву


<svg width="12" height="12" fill="#ccc9c6" v-svg="'mono-info'" />,
# где `v-svg` — путь к `id` в спрайте
Есть ли разница, где отписываться: в beforeDestroy или destroyed?
У меня тоже были проблемы с памятью, но после добавления отписок в destroyed от части утечек памяти избавился.
Имхо, если у тебя листенер через addEventListener привязан к ДОМу — отписывайся в beforeDestroy.
В destroyed ДОМ не доступен:

Вызывается после уничтожения экземпляра Vue. К моменту вызова этого хука, все директивы экземпляра Vue уже отвязаны, все подписчики событий удалены, а все дочерние экземпляры Vue уничтожены.


Если не привязан — хоть там, хоть там.
Нет, у меня там общая шина, не привязанная к DOM.
Спасибо, теперь понятно, в чем отличие.
Можно глупый вопрос? Почему event bus создается как пустой объект Vue. Во-первых, вроде как в приложении уже есть инстанс Vue. Почему нельзя использовать его? Во-вторых, с точки зрения дизайна это вообще ни разу не очевидно и выглядит как какой-то левый хак. И в целом, насколько легковесна такая операция? Потому что вот пример плагина, который берет и создает собственный even bus, хотя мог бы использовать тот, который уже есть в приложении.
Это рекомендация из официальной документации для распространения. Ранее (v1) был кроме emit() был еще dispatch(), который бросал эвент вверх по дереву компонентов.

Первый совет напомнил повсеместное использование rootScope в angular 1 приложении, что как по мне антипаттерн, от которого в последствии избавились.

На мой взгляд, между глобальными переменными и глобальной шиной событий есть большая разница. По сути, все redux-mobx-vuex это попытки более безопасного использования глобальных переменных. Как только приложение разбивается на локальные компоненты, над ними всегда висит что-то глобальное, что их связывает. EventEmitter — еще один способ связи, довольно безопасный.
Все события на странице так или иначе приводят к изменению данных. Зачем городить глобальный Event Bus и следить за утечками, если есть vuex и actions, а компоненты уже реактивно отреагируют на изменившиеся данные?
Наверное, в vuex возможно хранить вообще все переменные приложения, но, на мой взгляд, это — неоптимальный вариант. У меня в vuex хранится только критический минимум важных данных, а компоненты имеют свои собственные локальные данные и события. Они более независимы, лучше живут сами по себе.
Можно же вообще все в одном компоненте написать.
Простой пример — вызов модального окошка с настройками, которое вызывается из компонента каждого элемента списка и еще откуда-нибудь.
Не надо в vuex хранить всё. Но если компонентам нужна связь длиннее, чем родитель-потомок, то есть смысл задуматься о вынесении общего состояния в vuex (не обязательно всё в одном хранилище держать, там система модулей есть).
А модальное окошко я бы через плагин сделал, добавляющий всем компонентам метод для показа окошка (можно возвращать промис с результатами работы окошка).
Часто хочется анимировать появление какого-то блока неизвестных размеров, т.е. изменить его высоту с height: 0 до height: auto.

Вопрос не имеет отношение в Vue, это независимая css проблема.
Анимировать max-height невкусно, ибо (1) изчезает плавность, если взять с большим запасом, или (2) можно «подрезать» текст, если высота окажется больше значения max-height. Лично мне нравится в подобных случаях анимировать line-height+opacity, получается прикольно и вполне плавно.
Only those users with full accounts are able to leave comments. Log in, please.