Как стать автором
Обновить

Комментарии 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 элементов, или прототипов, которые все равно придется переделывать нормально.

По анимации, могу посоветовать вот эту часть (5) еще есть остальные 4 части

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


Я использую 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.
Спасибо, теперь понятно, в чем отличие.
НЛО прилетело и опубликовало эту надпись здесь
Это рекомендация из официальной документации для распространения. Ранее (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, получается прикольно и вполне плавно.
Зарегистрируйтесь на Хабре , чтобы оставить комментарий

Публикации

Истории