Vueist – Telegram
Vueist
1.04K subscribers
25 photos
46 links
Vue шитпостинг, желтуха, советы и мысли

Дополнительный канал к @zede_code от @zede1697
Download Telegram
Что вы используете у себя (можете отмечать как для петов, так и для коммерческой разработки). Nuxt UI считайте взрослым поколением, ибо он ближе к ним по духу (установка готовой либы)
Anonymous Poll
17%
Поколение старичков, а ля Vuetify
28%
Взрослое поколение (PrimeVue...) + Nuxt UI
11%
Молодое headless поколение (Reka UI...)
19%
Молодое shadcn поколение (Shadcn...)
33%
Своя UI библиотека
5%
нет UI библиотеки / AI генерация компонентов
18%
посмотреть ответы
👩‍💻 Вчера я потратил 3 часа на…

…отладку неожиданного бага в Transition из Vue? Я пока что не понял, баг это или нет, но поведение точно абсолютно некорректное.

Сейчас я преимущественно занимаюсь красивостями в рабочем проекте, и вот реализовал нативные переходы между представлениями (страницами). Конечно, не без трудностей.

Всё шло гладко, пока я не встретился с какой-то странной проблемой — Transition напрочь отказывался анимировать именно одно из представлений, и на протяжении трех часов я не мог понять в чем дело. В консоли пусто, leave-обработчики не вызываются, а элемент просто мгновенной исчезает без переходов.

Догадаетесь в чем проблема?

// SomeViewLayout.vue
<template>
<span>
Some view layout goes here
</span>
</template>


// CurrentView.vue
<noscript lang="ts" setup>
import SomeViewLayout from './SomeViewLayout.vue';
</noscript>

<template>
<!-- comment -->
<SomeViewLayout/>
</template>


// App.vue
<noscript lang="ts" setup>
import { onMounted, ref } from 'vue';
import CurrentView from './CurrentView.vue';

const onEnter = (el: Element, done: VoidFunction) => {
el.animate({ opacity: [0, 1] }, { duration: 200 }).finished.then(() => done());
};
const onLeave = (el: Element, done: VoidFunction) => {
el.animate({ opacity: [1, 0] }, { duration: 200 }).finished.then(() => done());
};
const key = ref(1);
onMounted(() => {
setTimeout(() => key.value = 2, 1000);
});
</noscript>

<template>
<Transition @enter="onEnter" @leave="onLeave">
<CurrentView :key="key"/>
</Transition>
</template>


По какой-то неведомой мне причине, если Transition отрисовывает компонент, в котором сначала идёт комментарий, а затем другой компонент, он просто в silent-режиме удаляет компонент (точнее дерево элементов) из DOM без каких-либо предупреждений и вызовов хуков для переходов (leave, например), а ты потом сиди гадай, что идет не так. То есть если убрать комментарий, либо же заменить компонент, идущий после него, на какой-нибудь элемент, то всё работает отлично.

И всё бы ничего, но ведь Transition имеет встроенные предупреждения о том, что он не может анимировать какой-либо элемент, либо что в него нельзя передавать множество элементов. Несмотря на это, словил просто глухой баг, на который потратил кучу времени.

Понятно, что проблема специфичная, потому что, как понимаю, мало кто пользуется HTML-комментариями (а у меня они были просто потому, что я временно закомментировал код), но было бы здорово другим разработчикам с этим не столкнуться.
Please open Telegram to view this post
VIEW IN TELEGRAM
👍31😱62
По поводу бага выше:
Да Vue генерирует в Dev среде комментарии из template. Это поведение можно отключить вот таким образом. Тогда баг с Transition и тп пропадет
🔥28👍5
По поводу очередных споров в чате предлагаю узнать: что вы предпочитаете для изоляции стилей конкретно на Vue проектах. Вы можно выбрать несколько уместных для вас вариантов. позже мы попробуем разобрать каждый из подходов с его неочевиднвми нюансами.
Anonymous Poll
37%
BEM-like
63%
SFC Scopes
24%
SFC Modules
11%
Atomics
2%
CSS-inJS 👀
2%
Другое (в комментарии)
10%
Посмотреть ответы
BEM-like

Будем разбирать каждый тип по очереди и начнем с BEM-like решений. Сразу оговорюсь, что тут речь не о чистом BEM, а именно о тех вариациях которые можно встретить зачастую в проектах и конкретно ДЛЯ ИЗОЛЯЦИИ (БЭМ решает и другие проблемы, но это отдельной статьи бы потребовало)

Ключевые признаки:
1) Пишем стили в <style> выбор между css/sass/postcss не важен
2) изоляция достигается оберткой стиля в BEM-like нотацию: имя компонента становится классом, далее поверх накидываются уже элементы/модификаторы и тд

Основные плюсы:
1) Нативность: для работы BEM-like почти никакого сопровождения со стороны фреймворка не требуется, работает везде
2) Простота (относительная): пишем почти как обычный CSS, но с парой правил сверху, справится любой. в блоке скриптов тоже представляется в виде обычных строк
3) Семантичность: зайдя в девтулзы найти компонент по классу легко, легко понять что именно за классы навешены на div, да и при чтении кода компонента +- понятно за что отвечает каждый тег
4) При грамотных действиях дает неплохую стандартизацию по именам классов на проекте/
5) Очень хорошо подходит для обучения новичков с точки зрения развития инженерных навыков (новички учатся быстро понимать, что классы могут иметь четкие роли, внешняя геометрия вне компонента и тд), но в реальности большинство ограничивается только базой нейминга без самой сути

Минусы:
1) Большие имена классов: то за что ругают чаще всего, что имена становятся длинными и громоздкими, есть техники уменьшающие длину классов, но они уже компромисны
2) С точки зрения изоляции, то изоляция держится на условном контракте, те если кто-то нарушит и переиспользует имя, то будет коллизия, на больших проектах имена классов раздуваются еще сильнее и перед именем блока появляется еще и "неймспейс", данная изоляция особенно течет на микрофронтендах, если не предпринять особых мер
3) Я не просто так пишу BEM-like. ибо BEM как таковой люди понимают очень по разному и каждый проект уникален в своем "БЭМ"-е. Также селекторы могут включать в себя любой хаос и не подчиняться строгой BEM-нотации
4) Относительный минус: порой людям кажется сложным поиск элемента сразу
5) Никакой защиты на уровне типизации (очепятка в имени класса обнаруживается только в рантайме)
6) Истекает из семантичности: на каждую маломальскую потребность в использовании стиля нуно придумывать отдельное имя, иногда это людям дается сложно и некоторые ощущают в этом потерю времени за зря

Нюансы:
1) Скорее всего в 99% случаев у вас будет 1 блок = 1 компонент, так как семантика понятия блока и компонента крайне близка. Действительно желание сделать блок это повод задуматься: а почему бы не вынести это в компонент (мне нравится, когда сам подход дает такие эвристики для мышления!)
2) Если вы разрабатываете библиотеку, то сохранность имен классов дает возможность расширения стилей (что в 90% зло), но иногда действительно спасает
3) Пользователи адблоков, кастомных тем/плагинов на сайтах скажут спасибо, ибо когда есть четкие классы, то их очень легко и удобно расширять и подвязываться на них

Вариации:
1) Может сочетаться со скоупами или модулями, но это во многом избыточно. Для модулей этого точно лучше избегать, так как БЭМ+модули даст крайне громоздкий и избыточный код, предпочтите подходы специфичные для модулей
2) БЭМ+atomics подход озвучивался даже в комментариях выше. Если вам нужно повесить только внешнюю геометрию или 1-2 класса, а нейминг придумать к этому нереально, то atomics прекрасно закрывает данную потребность. Тут советую больше присмотреться к unocss нежели tw из-за простоты настройки только точечных классов, а не всего подряд
👍234🤔2
Итоги:
1) В целом данный подход все еще работает, но на проектах которые предполагают большой размер, независимую разработку команд есть более современные и простые методы изоляции
2) У него есть сторонники (в том числе и я), но есть и жесткие хейтеры.
3) Подход постепенно теряет актуальность, но я все еще вижу хороший потенциал именно в обучении людей
4) Если выбираете BEM-like для своих проектов, то пожалуйста, не поленитесь и копните глубже в философию БЭМ-а (раскрыть мне все в 1 посте тут просто нереально) и подумайте еще раз надо ли оно вам
👍16
Анатомия композаблов

DISCLAIMER: сравнение натянутое и заведомо раздутое, но в нем есть и зерно истины


возможно это прозвучит дико, но композаблы не шибко отличаются от обычного ООП, только описание у них императивное вместо декларативного. И многих это действительно удивляет. Так что я решил показать это более наглядно


function useA () { // имя класса
const b = ref() // поле класса
const c = ref() // поле класса 2
const sum = computed(() => b.value + c.value) // getter (и возможно setter)
function swap() {} // метод класса

// тут может быть ваша логика конструктора

// и даже деструктор доступен
onScopeDispose(() => { ... })

return {
b, // теперь b публичное поле класса (а вот С приватное)
sum // публичный метод
}
}


Вы можете возразить: а как же 3 столпа ООП наследование/инкапсуляция/полиморфизм.
С инкапсуляцией разобраться просто: композаблы и нужны, чтобы инкапсулировать логику в 1 месте (как сокрытие работает мы уже тоже рассмотрели)

Что насчет полиморфизма: с ним все замечательно, просто мы применяем его редко:

interface A {
(): { // описываем параметра конструктора
b: Ref<number>
swap(): void // описали публичный интерфейс
}
}
const useA1: A = () => { ... }
const useA2: A = () => { ... }

A1 и A2 реализуют один интерфейс и мы можем подменять их в зависимости от ситуации, 90% нам это не понадобится, но если сильно хочется то возможно

А где наследование то?
Ну с наследованием ситуация веселе. Сейчас такая тенденция, что наследования стараются избегать всячески предлагая вместо него использовать композицю, но многим лень, так как наследование написать на классах проще и удобнее чем композицю (особенно если хочется сохранить прежний интерфейс). С композаблами ровно обратная ситуация: мы легко можем использовать композицию, но наследование становится болезненным (чему я очень рад!)


function useA() {} // base
function useB() { // композиция ❤️
const a = useA() // изи
const { b, swap } = useA() // внедрение тоже легкое
...
}
const useB = ({...}: {...} & Parameters<typeof useA>) => { // наследование 🙈
const a = useA() // взяли и
const c = ref()
return {...a, с} // вернули
...
}


Если кому интересно проверить теорию на прочность, то велком в комментарии. Но основная суть поста показать, что мы отчасти остались в тех же рамках только с переходом от декларативности к императивности, чтобы иметь большую гибкость в действиях
👍16🔥97🗿2
Обновление language-tools 3.2

Вы могли этого не знать, но весь последний месяц команда работающая над vuejs/language-tools работала непокладая рук. Было за месяц закрыто около 100 issues-ов суммарно и огромное количество фией также было выкачено. Тут можно ознакомиться подробно с огромным обновлением

Были исправлены как старые мучавшие баги годами, так специфичные моменты внутри движка. + Джонсон впервые с его слов опробовал пакет @vuejs/components-meta и был им недаволен, теперь намеревается его переписать

О интересных новых фичах:
1) Подробный вывод информации о компонентах: пропсы слоты/дефолтное значение
2) Поддержка md разметки в JSDoc
3) Новый магический комментарий <!-- @strictTemplates -->. И данная директива включает строгую проверку шаблонов (по факту аналог strict в TS, но включается строгая проверка существования компонентов с их пропсами ивентами и тд)

По результатам проделанной работы количество открытых issues снизилось с 80+ до 10 😱
Я считаю, что это отличный подарок всему сообщству Vue перед новым годом!
🔥426🐳3❤‍🔥1👏1🤝1