В документации Vue появился глоссарий.
Может помочь как в изучении фреймворка при работе с незнакомыми терминами, так и разработчикам говорить на одном языке при упоминании термина.
https://vuejs.org/glossary/
Спасибо @mattersj за ссылочку.
Может помочь как в изучении фреймворка при работе с незнакомыми терминами, так и разработчикам говорить на одном языке при упоминании термина.
https://vuejs.org/glossary/
Спасибо @mattersj за ссылочку.
vuejs.org
Vue.js
Vue.js - The Progressive JavaScript Framework
🔥8❤3😱2👍1🤔1
🚀 Релиз Vue 3.4.0 Slam Dunk
Относительно
Добавления и значимые улучшения
🏎 Ускорение реактивности PR#5912, включающее в себя множество оптимизаций. Например, ранее
🌼 Долгожданный
🫱 Добавлена сокращённая запись директивы
🕰 Добавлен
Подобно
Это позволяет, например, избежать лишнего вычисления нового значения при иммутабельных изменениях
-
∫ Появилась поддержка MathML тегов для шаблона
🛡 В валидатор пропсов теперь приходят значения других пропсов
А также улучшения для TS
Добавился тип
Удалены `deprecated`:
🧹 Reactivity Transform (
🧹 Директива
🧹
🧹 Старые события жизненного цикла компонента
Прочее:
- Улучшение вывода ошибок компиляции шаблона в проде
- Улучшение типизации, включая JSX
- Множество багфиксов в SSR и гидратации
- Багфиксы
Подробности в блоге: https://blog.vuejs.org/posts/vue-3-4
Changelog: https://github.com/vuejs/core/blob/main/CHANGELOG.md#340-slam-dunk-2023-12-29
Относительно
beta
и rc
релизов ничего нового, так что вспомним обо всех значимых изменениях в них.Добавления и значимые улучшения
🏎 Ускорение реактивности PR#5912, включающее в себя множество оптимизаций. Например, ранее
computed
не был зависимостью как самостоятельное значение, использующий его эффект зависел от его вычисления. Теперь перевычисление computed
с тем же результатом не будет триггерить использующие его эффекты.🌼 Долгожданный
once
в watch
. Теперь можно однократно среагировать на изменение значения без ручного вызова stop
!// before
const foo = ref(...)
const stop = watch(foo, () => {
// react
stop()
})
// After v3.4
watch(foo, () => {
// react
}, { once: true })
🫱 Добавлена сокращённая запись директивы
v-bind
, когда аргумент директивы совпадает со значением (аналогично { shorthand }
в JS объектах ):<input :disabled="disabled" />
<UiInput :model-value="modelValue" />
Теперь можно записывать как
<input :disabled />
<UiInput :model-value />
🕰 Добавлен
oldValue
для computed
. Подобно
watch
теперь можно получить старое значение вычисляемого свойства при перевычислении.Это позволяет, например, избежать лишнего вычисления нового значения при иммутабельных изменениях
const dataObject = computed((oldValue) => {
const newValue = computeSomeObject()
// Если объект получился с тем же значением - возвращаем старый,
// чтобы не создавать новый объект по новой ссылке
// и не триггерить реактивность лишний раз
return isEqual(newValue, oldValue) ? oldValue : newValue
})
-
defineModel
макрос больше не экспериментальный, а его производительность улучшенаconst modelValue = defineModel()
// Заменяет (но эффективнее)
const props = defineProps(['modelValue'])
const emit = defineEmits(['update:modelValue'])
const modelValue = computed({
get: () => props.modelValue,
set: (value) => emit('update:modelValue', value),
})
∫ Появилась поддержка MathML тегов для шаблона
🛡 В валидатор пропсов теперь приходят значения других пропсов
color: {
type: String,
validator: (value, props) =>
props.format === 'hex'
? HEX_RE.test(value)
: RGB_RE.test(value)
},
А также улучшения для TS
Добавился тип
ComponentInstance
, позволяющий из типа описания компонента получить тип экземпляра компонентаdefineSlots
теперь поддерживает keyof
от generic компонентов. Это позволяет описывать тип слотов в зависимости от типа пропсов, например, для типизации универсальной таблицы<script lang="ts" setup generic="TRow extends Record<string, unknown>">
const props = defineProps<{
rows: TRow[] // тип объекта для каждой строки - из дженерика
cols: { name: keyof TRow; label: string }[]
}>()
const slots = defineSlots<{
// Тип слота для заголовкой каждой ячейки
[K in keyof TRow as `header:${K & string}`]: (props: {
col: { name: keyof TRow; label: string }
}) => any[]
}>()
</script>
Удалены `deprecated`:
🧹 Reactivity Transform (
$ref
сахар), который был deprecated
в Vue 3.3. Много горячих обсуждений было о разных вариантах его внедрения.🧹 Директива
v-is
, вместо которой используется специальный атрибут is🧹
app.config.unwrapInjectedRef
, который включен по умолчанию с 3.3🧹 Старые события жизненного цикла компонента
@vnodeXXX
, вместо которых есть @vue:xxx
Прочее:
- Улучшение вывода ошибок компиляции шаблона в проде
- Улучшение типизации, включая JSX
- Множество багфиксов в SSR и гидратации
- Багфиксы
Suspense
Подробности в блоге: https://blog.vuejs.org/posts/vue-3-4
Changelog: https://github.com/vuejs/core/blob/main/CHANGELOG.md#340-slam-dunk-2023-12-29
blog.vuejs.org
Announcing Vue 3.4 | The Vue Point
The official blog for the Vue.js project
🔥10❤5🎉4😱3👍2
🤕 Vue 3.4.0 вышел в релиз только 2 недели назад, но за ним уже последовало 9 патчей, а на этой неделе патчи буквально каждый день. Иногда в них откатывают изменения. Пофикшено много багов с
Если используете Vue 3 в проде, где критичны ошибки, или не хотите разбираться, вылезхает ли у вас ошибка из-за бага в Vue или вашего бага - возможно, стоит не обновляться на 3.4 пока он не стабилизируется, и хотя бы несколько недель не будет новых патчей и активного появления новых issue.
FULL CHANGELOG
SSR
, suspense
, compiler-sfc
, а также несколько багов нового defineModel
, новой реализации реактивности, включая производительность, и другие.Если используете Vue 3 в проде, где критичны ошибки, или не хотите разбираться, вылезхает ли у вас ошибка из-за бага в Vue или вашего бага - возможно, стоит не обновляться на 3.4 пока он не стабилизируется, и хотя бы несколько недель не будет новых патчей и активного появления новых issue.
FULL CHANGELOG
😢5👍2😱2❤1🤔1🤯1🤬1🥴1
Ещё одна интересная статья об опыте миграции на Vitest.
❤1🔥1🤔1
Forwarded from Валя читает ишью
Vitest: 9 месяцев спустя
Напомню, мы в Авиасейлс переехали с Jest на Vitest и были (ну, я уж точно) не очень довольны результатом. Прошло 9 месяцев, вышла Vitest 1.0 (а актуальная версия уже и 1.2.1) и мы научились с ним как-то жить.
Во-первых, я оказался прав на счёт шардирования. В синтетических тестах (только vitest в пайплайне, это существенно ускоряет тесты) используя 12 тредов, тесты проходили за ~3 минуты. 4 шарда по 3 треда в каждом (с меньшим количеством тредов тесты начинали зависать) мы укладываемся в ~2 минуты. Сайд-эффект шардов — теперь у нас 4 разных отчёта, а не один единый. Неудобно. Команда Vitest открыта к blob репортерам, как в playwright. Их можно склеить после и получить единый отчёт. Осталось написать ишью и реализовать, хех.
Касательно перформанса тредов вот моё ишью — The performance of threads doesn't scale much after 8 threads.
Во-вторых, нам удалось стабилизировать тесты и избавиться от залипаний и случайных падений. С тех пор мы обновились до node v18.19.0 и vitest v1.1.3, удалили любые исключения из poolMatchGlobs и используем threads пул (стандартный и не самый быстрый).
В-третьих, нестабильность витеста породила особенный подход обновлению его самого и ноды. Мы запускаем 100+ пайплайнов по крону, смотрим fail rate и принимаем решение об обновлении или включении каких-то опций. Как я сказал выше, на v1.1.3 нам удалось добиться 100% стабильности, но вот уже с v1.2.1 (latest) один из тестов начинает отваливаться в трети случаев.
В-четвёртых, я был не особо прав, когда сравнивал типы пулов. С тех пор в витесте появился пул vmThreads, который полностью копирует подход из джеста. Он действительно быстрее (в нашем случае срезает ~30 секунд), но менее стабильный и течёт по памяти (как и джест).
В общем, кажется мы научились его готовить, но иногда процесс готовки становится, прямо скажем, неприятным.
Напомню, мы в Авиасейлс переехали с Jest на Vitest и были (ну, я уж точно) не очень довольны результатом. Прошло 9 месяцев, вышла Vitest 1.0 (а актуальная версия уже и 1.2.1) и мы научились с ним как-то жить.
Во-первых, я оказался прав на счёт шардирования. В синтетических тестах (только vitest в пайплайне, это существенно ускоряет тесты) используя 12 тредов, тесты проходили за ~3 минуты. 4 шарда по 3 треда в каждом (с меньшим количеством тредов тесты начинали зависать) мы укладываемся в ~2 минуты. Сайд-эффект шардов — теперь у нас 4 разных отчёта, а не один единый. Неудобно. Команда Vitest открыта к blob репортерам, как в playwright. Их можно склеить после и получить единый отчёт. Осталось написать ишью и реализовать, хех.
Касательно перформанса тредов вот моё ишью — The performance of threads doesn't scale much after 8 threads.
Во-вторых, нам удалось стабилизировать тесты и избавиться от залипаний и случайных падений. С тех пор мы обновились до node v18.19.0 и vitest v1.1.3, удалили любые исключения из poolMatchGlobs и используем threads пул (стандартный и не самый быстрый).
В-третьих, нестабильность витеста породила особенный подход обновлению его самого и ноды. Мы запускаем 100+ пайплайнов по крону, смотрим fail rate и принимаем решение об обновлении или включении каких-то опций. Как я сказал выше, на v1.1.3 нам удалось добиться 100% стабильности, но вот уже с v1.2.1 (latest) один из тестов начинает отваливаться в трети случаев.
В-четвёртых, я был не особо прав, когда сравнивал типы пулов. С тех пор в витесте появился пул vmThreads, который полностью копирует подход из джеста. Он действительно быстрее (в нашем случае срезает ~30 секунд), но менее стабильный и течёт по памяти (как и джест).
В общем, кажется мы научились его готовить, но иногда процесс готовки становится, прямо скажем, неприятным.
👍1😱1
Forwarded from Vue-FAQ
Vue.js Nation конференция началась с часовой рекламы курсов и сертификаций (скоро появится по Nuxt и JS)
Затем Evan You отвечал на вопросы ведущей:
- Поддержка TypeScript во Vue 3 нормальная
- В феврале будет Vuenniversary - 10 лет Vue
- В 3.5 и 3.6 изменения будут небольшие, типа сomponent types и uuid для SSR
- Во второй половине года объявит о чем-то интересном (exciting)
- Если Signals будут стандартизованы, то Vue может использовать это
- Elk (клиент Mastodon) - пример крутого нетривиального приложения на Vue (Nuxt)
- Vueукрал был вдохновлен разными моментами в Angular 1, React, Knockout, Svelte
- Options API убирать не собираются
- Evan сомневается, что React идет куда-то туда с RSC
- Объяснил, почему не рекомендуется мутировать пропс-объект (не так явно видно, кто и как его меняет)
- VitePress 1.0.0 готов, но в конце декабря они погрязли в другой работе и не релизнулись. Скоро выпустят с фанфарами.
- AI сильно фронтенд не изменит в ближайшем времени. Пока это просто помощник
#evanyou #vuejsnation
Затем Evan You отвечал на вопросы ведущей:
- Поддержка TypeScript во Vue 3 нормальная
- В феврале будет Vuenniversary - 10 лет Vue
- В 3.5 и 3.6 изменения будут небольшие, типа сomponent types и uuid для SSR
- Во второй половине года объявит о чем-то интересном (exciting)
- Если Signals будут стандартизованы, то Vue может использовать это
- Elk (клиент Mastodon) - пример крутого нетривиального приложения на Vue (Nuxt)
- Vue
- Options API убирать не собираются
- Evan сомневается, что React идет куда-то туда с RSC
- Объяснил, почему не рекомендуется мутировать пропс-объект (не так явно видно, кто и как его меняет)
- VitePress 1.0.0 готов, но в конце декабря они погрязли в другой работе и не релизнулись. Скоро выпустят с фанфарами.
- AI сильно фронтенд не изменит в ближайшем времени. Пока это просто помощник
#evanyou #vuejsnation
👍7😁2🤔1
Forwarded from artalog (artalar)
Зачем реатом во vue?
У нас там апдейты подъехали, стоит рассказать о мотивации.
Во вью из коробки идут простые и достаточно мощные примитивы для обработки состояния, рефы можно создавать вне компонента и большая часть задач этим решается. Но есть ряд вопросов, которые реатом покрывает лучше.
- Реатом лучше позволяет описывать логику полностью отделенную от компонента, которую потом еще и легче дебажить. Проявляется это в наличии лайфсайкл хуков у каждого атома (можно инициировать ресурс на первую подписку - использование в компоненте, и уничтожить ресурс при последней отписке) и выделенной сущности “экшен”, для удобного разделения кода на логические блоки. Т.к. все эти сущности именованны (автоматически еслинтом), в последствии можно наблюдать полезные логи того что поменялось и по какой причине (уникальная фича реатома).
- За счет первого пункта реатом можно использовать как ядро микрофронтовой системы, у нас уже есть адаптеры для vue, react, solid, svelte, и в разработке адаптеры для lit и angular.
- У реатома есть очень мощные примитивы для описания асинхронной логики, собравшие все самое лучшее с rxjs, redux-saga и TanStack Query. Тут впринципе альтернатив, вроде, нет.
- У реатома одна из самых больших экосистем среди всех стейт менеджеров и, посмею сказать, самая сбалансированная. При этом, каждый пакет разрабатывается с маниакальным фокусом на бандлсайзе и перфе.
Если стало интересно, вот видосики по реатому: https://www.youtube.com/playlist?list=PLXObawgXpIfxERCN8Lqd89wdsXeUHm9XU
У нас там апдейты подъехали, стоит рассказать о мотивации.
Во вью из коробки идут простые и достаточно мощные примитивы для обработки состояния, рефы можно создавать вне компонента и большая часть задач этим решается. Но есть ряд вопросов, которые реатом покрывает лучше.
- Реатом лучше позволяет описывать логику полностью отделенную от компонента, которую потом еще и легче дебажить. Проявляется это в наличии лайфсайкл хуков у каждого атома (можно инициировать ресурс на первую подписку - использование в компоненте, и уничтожить ресурс при последней отписке) и выделенной сущности “экшен”, для удобного разделения кода на логические блоки. Т.к. все эти сущности именованны (автоматически еслинтом), в последствии можно наблюдать полезные логи того что поменялось и по какой причине (уникальная фича реатома).
- За счет первого пункта реатом можно использовать как ядро микрофронтовой системы, у нас уже есть адаптеры для vue, react, solid, svelte, и в разработке адаптеры для lit и angular.
- У реатома есть очень мощные примитивы для описания асинхронной логики, собравшие все самое лучшее с rxjs, redux-saga и TanStack Query. Тут впринципе альтернатив, вроде, нет.
- У реатома одна из самых больших экосистем среди всех стейт менеджеров и, посмею сказать, самая сбалансированная. При этом, каждый пакет разрабатывается с маниакальным фокусом на бандлсайзе и перфе.
Если стало интересно, вот видосики по реатому: https://www.youtube.com/playlist?list=PLXObawgXpIfxERCN8Lqd89wdsXeUHm9XU
Telegram
Reatom новости
🔥Huge drop🔥
@reatom/persist-web-storage - @osovv добавил withBroadcastChannel для синхронизации табов без лишнего оверхеда на хранение стейта и withIndexedDb для персиста большого объема данных (рекомендуется для reatom/async.withCache)
@reatom/npm-vue …
@reatom/persist-web-storage - @osovv добавил withBroadcastChannel для синхронизации табов без лишнего оверхеда на хранение стейта и withIndexedDb для персиста большого объема данных (рекомендуется для reatom/async.withCache)
@reatom/npm-vue …
👍5🤔1
Forwarded from Denis Chernov
vue-vapor обзавелся своим плейграундом.
Для тех кто не знает что это:
На данный момент Vue используем механизм VDOM (виртуальный DOM), но у него есть свои недостатки: избыточность по памяти, непрямое изменение и тд
Так вот Vapor это вдохновленный Solid-ом подход к механизму рендеринга без использования VDOM. Все происходит чисто на работе реактивности и счедуллингу эффектов. Более подробно можно ознакомиться тут
Мы можем вполне оценить то что уже сделано в плейграунде:
https://vapor-repl.netlify.app
выглядит действительно многообещающе
Для того, чтобы увидеть результат работы заходим во вкладку: JS / SSR
там можно обратить внимание как меняется результат билда между vapor режимом и обыкновенным (кликаем VAPOR ON/OFF в правой части шапки плейграунда)
На что я обратил внимание:
1) более агрессивно берется все из контекста рендеринга (например, Array сейчас будет браться из _ctx.Array). В исходники не заглядывал, но возможно исправят
2) Часть функционала ожидаемо нереализована (ее можно посмотреть на чеклисте репозитория )
3) Багов хватает :D Любая попытка потестить перф выходила каким-то багом
В целом решение пока сыроватое и прям сильно его не оценить. Но первые шаги уже видны явно, а не на словах
Для тех кто не знает что это:
На данный момент Vue используем механизм VDOM (виртуальный DOM), но у него есть свои недостатки: избыточность по памяти, непрямое изменение и тд
Так вот Vapor это вдохновленный Solid-ом подход к механизму рендеринга без использования VDOM. Все происходит чисто на работе реактивности и счедуллингу эффектов. Более подробно можно ознакомиться тут
Мы можем вполне оценить то что уже сделано в плейграунде:
https://vapor-repl.netlify.app
выглядит действительно многообещающе
Для того, чтобы увидеть результат работы заходим во вкладку: JS / SSR
там можно обратить внимание как меняется результат билда между vapor режимом и обыкновенным (кликаем VAPOR ON/OFF в правой части шапки плейграунда)
На что я обратил внимание:
1) более агрессивно берется все из контекста рендеринга (например, Array сейчас будет браться из _ctx.Array). В исходники не заглядывал, но возможно исправят
2) Часть функционала ожидаемо нереализована (ее можно посмотреть на чеклисте репозитория )
3) Багов хватает :D Любая попытка потестить перф выходила каким-то багом
В целом решение пока сыроватое и прям сильно его не оценить. Но первые шаги уже видны явно, а не на словах
GitHub
GitHub - vuejs/core-vapor: Vue Vapor is a variant of Vue that offers rendering without the Virtual DOM.
Vue Vapor is a variant of Vue that offers rendering without the Virtual DOM. - vuejs/core-vapor
🤔6🔥3👍2❤1
Forwarded from Denis Chernov
Ого какая новость пролетела мимо:
Vue опять нехило импрувнули перф реактивности (в этот раз поменяли структуры данных используемые внутри системы реактивности на манер сигналов Preact)
Это дало перф:
- на ~56% уменьшено потребление памяти системой реактивности 🤯
- случай когда 1 реф вызыввает несколько эффектов (+118%-185% прирост производительности)
- чтение множества invalidated computed-ов (+176%+244% прирост производительности)
Дополнительно:
- Обнова обещает никак не афектить поведение и вся реализация прячется лишь в @vue/reactivity
- Закрывает некоторые специфичные баги/корнер-кейсы для системы реактивности
- Компьютеды стали гораздо дешевле и теперь еще более ленивые
- теперь если компьютед не имеет подписчиков на него то он сбрасывает все свои зависимости
- компьютед теперь в целом не может иметь зависимостей если от него никто не зависит
- Противный варнинг из 3.4.19 о грязных компьютедах удален!
- Обещают что сборка мусора в режиме SSR будет работать лучше (как это будет аффектить в реальности пока неизвестно)
Для любителей копаться в тонкостях:
- Больше никакого ручного счедуллинга:
- pauseScheduling, pauseTracking, resetScheduling больше недоступны (впрочем они и не были задокументированной возможностью)
- теперь зависимости в deps это не Map/Set а самостоятельная структура Dep с версионированием и на базе двусвязанного списка
- код стал читаться как-то проще :D
- еще не копался на в Dev режиме включили какой-то трекинг по типу действия сигнала и как его трекают
Обновление попало в минорную ветку, так что пока неизвестно когда оно попадет в наши приложения. Однако остается только порадоваться, как много сил было вложено в последнее время в повышение перфа во Vue за последние месяцы
Vue опять нехило импрувнули перф реактивности (в этот раз поменяли структуры данных используемые внутри системы реактивности на манер сигналов Preact)
Это дало перф:
- на ~56% уменьшено потребление памяти системой реактивности 🤯
- случай когда 1 реф вызыввает несколько эффектов (+118%-185% прирост производительности)
- чтение множества invalidated computed-ов (+176%+244% прирост производительности)
Дополнительно:
- Обнова обещает никак не афектить поведение и вся реализация прячется лишь в @vue/reactivity
- Закрывает некоторые специфичные баги/корнер-кейсы для системы реактивности
- Компьютеды стали гораздо дешевле и теперь еще более ленивые
- теперь если компьютед не имеет подписчиков на него то он сбрасывает все свои зависимости
- компьютед теперь в целом не может иметь зависимостей если от него никто не зависит
- Противный варнинг из 3.4.19 о грязных компьютедах удален!
- Обещают что сборка мусора в режиме SSR будет работать лучше (как это будет аффектить в реальности пока неизвестно)
Для любителей копаться в тонкостях:
- Больше никакого ручного счедуллинга:
- pauseScheduling, pauseTracking, resetScheduling больше недоступны (впрочем они и не были задокументированной возможностью)
- теперь зависимости в deps это не Map/Set а самостоятельная структура Dep с версионированием и на базе двусвязанного списка
- код стал читаться как-то проще :D
- еще не копался на в Dev режиме включили какой-то трекинг по типу действия сигнала и как его трекают
Обновление попало в минорную ветку, так что пока неизвестно когда оно попадет в наши приложения. Однако остается только порадоваться, как много сил было вложено в последнее время в повышение перфа во Vue за последние месяцы
GitHub
Refactor reactivity system to use version counting and doubly-linked list tracking by yyx990803 · Pull Request #10397 · vuejs/core
This PR refactors the core reactivity system to use version counting and a doubly-linked list data structure inspired by Preact signals.
It brings some improvements and solves some issues around co...
It brings some improvements and solves some issues around co...
👍4❤3🔥1
Forwarded from Denis Chernov
Такс ребятушки. Новый исторический момент в мире Vue.js: Vue language tools v2
- Что это такое и как оно нас касается?
не так давно вы могли слышать о обнове Volar.js. Если нет, то не страшно. Команда Vue очень заточена под улучшения экосистемы целиком, а не только Vue-разработчиков. Поэтому Джонсон (которого вы можете знать по тем самым обновлениям с перфом реактивности во Vue3) закорешился с мейнтенейром Astro и мейнтейнером MDX. Что этих крутышей связывает? Им нужно встраивать несколько языков в рамках одного файла и поддерживать при этом высокий DX. На самом деле это задача не из простых. И во Vue это проявлялось в VSC тем, что был злополучный Takeover Mode. Это особый режим который перекрывает плагин TS и вынуждал нас включать 2 плагина и отключать родной от TS.
Конечно все это пугало новичков. Но полтора месяца назад было объявляено, что эту проблему смогли побороть в рамках Volar 2. Теперь плагин использует возможности самого lsp от TS и не требует перекрытия плагином. С этого момента я оч ждал обновы language-tools.
https://github.com/vuejs/language-tools/releases/tag/v2.0.0
И вот час назад этот релиз вышел:
БОЛЬШЕ НИКАКОГО TAKEOVER MODE
+ к этому
- мы получаем родные для TS преобразования от TS плагина
- правит множество багов связанных с интеграцией и кастомным языком для VSC
- Больше нет плагина Volar - так как это более глобальный проект о фреймворке для поддержания авторов фреймворков. Теперь плагин это "Vue - Official"
- можете смело удалять расширение "TypeScript Vue Plugin"
Как это отразится на пользователях JetBrains? Пока сказать сложно, но буквально недавно была конференция у брейнсов, где скорее всего эту тему поднимали. Очень хочется верить, что это отразится на DX в IDE у JetBrains, так как они уже почти год переехали на Vue language server
PS. Вышло всего час назад, так что вполне возможны баги :D
PPS. Багов выше крыши. Советую переждать недельку!
- Что это такое и как оно нас касается?
не так давно вы могли слышать о обнове Volar.js. Если нет, то не страшно. Команда Vue очень заточена под улучшения экосистемы целиком, а не только Vue-разработчиков. Поэтому Джонсон (которого вы можете знать по тем самым обновлениям с перфом реактивности во Vue3) закорешился с мейнтенейром Astro и мейнтейнером MDX. Что этих крутышей связывает? Им нужно встраивать несколько языков в рамках одного файла и поддерживать при этом высокий DX. На самом деле это задача не из простых. И во Vue это проявлялось в VSC тем, что был злополучный Takeover Mode. Это особый режим который перекрывает плагин TS и вынуждал нас включать 2 плагина и отключать родной от TS.
Конечно все это пугало новичков. Но полтора месяца назад было объявляено, что эту проблему смогли побороть в рамках Volar 2. Теперь плагин использует возможности самого lsp от TS и не требует перекрытия плагином. С этого момента я оч ждал обновы language-tools.
https://github.com/vuejs/language-tools/releases/tag/v2.0.0
И вот час назад этот релиз вышел:
БОЛЬШЕ НИКАКОГО TAKEOVER MODE
+ к этому
- мы получаем родные для TS преобразования от TS плагина
- правит множество багов связанных с интеграцией и кастомным языком для VSC
- Больше нет плагина Volar - так как это более глобальный проект о фреймворке для поддержания авторов фреймворков. Теперь плагин это "Vue - Official"
- можете смело удалять расширение "TypeScript Vue Plugin"
Как это отразится на пользователях JetBrains? Пока сказать сложно, но буквально недавно была конференция у брейнсов, где скорее всего эту тему поднимали. Очень хочется верить, что это отразится на DX в IDE у JetBrains, так как они уже почти год переехали на Vue language server
PS. Вышло всего час назад, так что вполне возможны баги :D
PPS. Багов выше крыши. Советую переждать недельку!
GitHub
Release v2.0.0 · vuejs/language-tools
New Features
Hybrid Mode
Takeover Mode has been deprecated. The extension now has the same performance as Takeover Mode by default.
TypeScript language support has been moved from Vue language se...
Hybrid Mode
Takeover Mode has been deprecated. The extension now has the same performance as Takeover Mode by default.
TypeScript language support has been moved from Vue language se...
❤6👍4
Документация Vue наконец получила долгожданный обновленный перевод на русский язык, который теперь доступен по ссылке ниже, а также в шапке основной англоязычной версии в блоке переводов:
https://ru.vuejs.org/
До этого на русском языке была доступна только устаревшая документация, написанная практически сразу после первоначального релиза Vue 3, но с тех пор многое изменилось, поэтому теперь рекомендуется читать именно обновленную документацию.
Переведены все основные разделы, но в документации все еще есть ошибки и неточности, например, на странице “Component v-model” описана работа функции
Если вы встретили ошибку/опечатку/неточность, о которой еще не написано в issues - можно создать его, либо исправить самому, прислав Pull Request.
Спасибо всем, кто помогал и принимал участие в переводе!
https://ru.vuejs.org/
До этого на русском языке была доступна только устаревшая документация, написанная практически сразу после первоначального релиза Vue 3, но с тех пор многое изменилось, поэтому теперь рекомендуется читать именно обновленную документацию.
Переведены все основные разделы, но в документации все еще есть ошибки и неточности, например, на странице “Component v-model” описана работа функции
toValue
.Если вы встретили ошибку/опечатку/неточность, о которой еще не написано в issues - можно создать его, либо исправить самому, прислав Pull Request.
Спасибо всем, кто помогал и принимал участие в переводе!
ru.vuejs.org
Vue.js
Vue.js - The Progressive JavaScript Framework
🔥32❤6👍4🎉3🙏1
Через пол часа начинается митап от MSK Vue.js
Смотреть онлайн трансляцию можно по ссылке: https://youtube.com/live/7SWzCjDPtoQ
Смотреть онлайн трансляцию можно по ссылке: https://youtube.com/live/7SWzCjDPtoQ
YouTube
Meetup #12
🔥6❤4🌚1
Vue 3.5 alpha.1 - Reactive Props Destructure
#vue_3_5 #changelog
Начали выходить alpha и beta версии нового Vue 🎉
Первое обновление - Reactive Props Destructure теперь доступен без экспериментального флага. Позволяет более красиво описывать значения по умолчанию в SFC Setup + TS.
RFC был спорный и долго горячо обсуждался. При компиляции обращение к переменой превращается в обращение к полю объекта.
Обсуждался ещё с 3.2 и был ранее добавлен под экспериментальным флагом в 3.3.
- RFC: https://github.com/vuejs/rfcs/discussions/502
#vue_3_5 #changelog
Начали выходить alpha и beta версии нового Vue 🎉
Первое обновление - Reactive Props Destructure теперь доступен без экспериментального флага. Позволяет более красиво описывать значения по умолчанию в SFC Setup + TS.
RFC был спорный и долго горячо обсуждался. При компиляции обращение к переменой превращается в обращение к полю объекта.
Обсуждался ещё с 3.2 и был ранее добавлен под экспериментальным флагом в 3.3.
<script setup lang="ts">
// Before
const props = withDefaults(defineProps<
foo?: string
>(), {
foo: 'foo'
})
// After
const { foo = 'foo' } = defineProps<
foo?: string
>()
// foo <==> props.foo
</script>
- RFC: https://github.com/vuejs/rfcs/discussions/502
👍6👎2🔥2😢1
Vue 3.5.0-alpha.3 - Появился новый компосабл
#vue_3_5 #changelog
Типичный use-case - id элементов, например, форм и атрибуты для доступности.
Результат получается невоспроизводимым, что усложняет тестирование и не работает на SSR
Такое решение может приводить к дублированию ID. Например, и в вашем приложении, и в UI фреймворке могли сделать
Чтобы облегчить жизнь разработчиков, добавили долгожданный
- PR: https://github.com/vuejs/core/pull/11404/
useId()
для генерации ID в компонентах.#vue_3_5 #changelog
const inputId = useId()
Зачем генерировать ID?
Типичный use-case - id элементов, например, форм и атрибуты для доступности.
Почему не просто `Math.random()` или `nanoid()`?
Результат получается невоспроизводимым, что усложняет тестирование и не работает на SSR
Почему не просто `id++`?
Такое решение может приводить к дублированию ID. Например, и в вашем приложении, и в UI фреймворке могли сделать
input-label-${id++}
.Чтобы облегчить жизнь разработчиков, добавили долгожданный
useId
, возвращающий уникальный ID, префикс которого можно настроить в конфиге Vue приложения.const app = createApp(App)
app.config.idPrefix = 'my-app'
// useId() === "my-app:0"
- PR: https://github.com/vuejs/core/pull/11404/
GitHub
feat(runtime-core): useId() by yyx990803 · Pull Request #11404 · vuejs/core
Similar to React's useId, this composable returns a unique ID that can be used for form elements and accessibility attributes.
The generated IDs look like v:1-2-3 and are unique across each...
The generated IDs look like v:1-2-3 and are unique across each...
👍9🔥5❤3🤔1🎉1🕊1🌚1
Vue 3.5.0-alpha.3: появился
#vue_3_5 #changelog
Позволяет описывать свойства для
- Семантически понятнее - явно определяется как переменная для template ref
-
- Значение атрибута
- Возможно, будет особая поддержка в IDE ?
- Commit: https://github.com/vuejs/core/commit/3ba70e49b5856c53611c314d4855d679a546a7df
useTemplateRef(key)
для Template Ref
#vue_3_5 #changelog
Позволяет описывать свойства для
Template Ref
аналогично ref()
. Отличия:- Семантически понятнее - явно определяется как переменная для template ref
-
readonly
- нельзя случайно изменить вручную- Значение атрибута
ref
- определяемый отдельно ключ, а не имя переменной (свойства компонента)- Возможно, будет особая поддержка в IDE ?
<script setup lang="ts">
// Vue 3.5+
const inputElement = useTemplateRef<HTMLInputElement>('inputElement')
// Или с отдельным ключом
const fileInputKey = 'FILE_INPUT'
const fileInputElement = useTemplateRef<HTMLInputElement>(fileInputKey)
// Аналог в прошлых версиях
const inputElement = ref<HTMLInputElement|null>()
</script>
<template>
<input ref="inputElement" />
<input :ref="fileInputKey" type="file" />
</template>
- Commit: https://github.com/vuejs/core/commit/3ba70e49b5856c53611c314d4855d679a546a7df
GitHub
feat: useTemplateRef() · vuejs/core@3ba70e4
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web. - feat: useTemplateRef() · vuejs/core@3ba70e4
👍8🤔8🔥5
Vue 3.5: появился отдельный API для работы с cleanup-функциями в watch/watchEffect -
- позволяет зарегистрировать функцию “очищения”, которая будет вызываться прямо перед повторным запуском watch/watchEffect (например, если изменилась зависимость и он вот-вот сработает);
- подходит для того, чтобы, например, отменять асинхронные запросы (избегая гонки состояний) или очищать старые таймеры перед запуском новых;
- сильно облегчает работу в паре с
- имеет те же ограничения, что и остальные функции, привязанные к контексту выполнения - должен выполняться синхронно и вызываться внутри watch/watchEffect;
- дополнительно имеет второй аргумент
либо можно воспользоваться еще одной новой функцией
тогда cleanup-функция будет зарегистрирована только в том случае, если мы находимся внутри watch/watchEffect.
Использование:
Новый подраздел в документации: https://vuejs.org/guide/essentials/watchers.html#side-effect-cleanup
PR: https://github.com/vuejs/core/pull/9927
#vue_3_5 #changelog
onWatcherCleanup
:- позволяет зарегистрировать функцию “очищения”, которая будет вызываться прямо перед повторным запуском watch/watchEffect (например, если изменилась зависимость и он вот-вот сработает);
- подходит для того, чтобы, например, отменять асинхронные запросы (избегая гонки состояний) или очищать старые таймеры перед запуском новых;
- сильно облегчает работу в паре с
watch
: сейчас функция onCleanup
передается в него третьим аргументом (после value и oldValue), что довольно неудобно, особенно, если первые 2 аргумента не нужны, поэтому раньше приходилось писать (_, __, onCleanup)
;- имеет те же ограничения, что и остальные функции, привязанные к контексту выполнения - должен выполняться синхронно и вызываться внутри watch/watchEffect;
- дополнительно имеет второй аргумент
failSilently
, куда можно передать true
, чтобы не получать предупреждение в консоли, если функция вызвана за пределами watch/watchEffect, что открывает окно для следующих паттернов:
export function request() {
const controller = new AbortController();
// регистрируем cleanup-функцию и передаем failSilently: true
onWatcherCleanup(() => controller.abort(), true);
return fetch(…, { signal: controller.signal });
}
либо можно воспользоваться еще одной новой функцией
getCurrentWatcher
и переписать код выше иначе:
export function request() {
const controller = new AbortController();
// если мы внутри вотчера
if (getCurrentWatcher()) {
// то регистрирурем cleanup-функцию
onWatcherCleanup(() => controller.abort());
}
return fetch(…, { signal: controller.signal });
}
тогда cleanup-функция будет зарегистрирована только в том случае, если мы находимся внутри watch/watchEffect.
Использование:
watchEffect(async () => {
const response = await request(…);
});
Новый подраздел в документации: https://vuejs.org/guide/essentials/watchers.html#side-effect-cleanup
PR: https://github.com/vuejs/core/pull/9927
#vue_3_5 #changelog
vuejs.org
Vue.js
Vue.js - The Progressive JavaScript Framework
🔥15🤔2👍1
Работа с картинками в шаблоне
1. Почему такой код не работает? Картинка точно есть по этому, и без переменной работает!
Собранное приложение в проде имеет другие файлы по другим путям. Путь относительно исходников - некорректный. Чтобы это работало, нужно работать с картинками и другими ресурсами, как с модулями, прогоняя их через сборщик. Сборщик переместит файл, поменяет имя, и вернёт новое имя, а может даже вставит inline-ссылкой (data url).
2. Но у меня раньше работало без импорта! Например, так:
Сборщик с
Только чистый
3. Что же тогда делать, если надо хранить путь в данных?
Можно использовать:
- Явные импорты, если заранее известен набор файлов
-
-
-
4. Но как работают все эти функции, если тут путь тоже вычисляется только в рантайме, а нужен ещё на этапе сборки?
Сборщик забирает шаблонную строку или конкатенацию строк. Затем считает, что вы можете импортировать в рантайме ЛЮБОЙ файл, подходящий под шаблон. В примерах выше сборщик найдёт все файлы
Более сложные JS выражения не будут работать.
Подробности:
- https://vitejs.dev/guide/assets.html
- https://vitejs.dev/guide/features.html#glob-import
- https://webpack.js.org/guides/asset-management/#loading-images
- https://github.com/vitejs/vite/issues/10597
!src
#help1. Почему такой код не работает? Картинка точно есть по этому, и без переменной работает!
<img :src="`../assets/images/${image}`" />
Собранное приложение в проде имеет другие файлы по другим путям. Путь относительно исходников - некорректный. Чтобы это работало, нужно работать с картинками и другими ресурсами, как с модулями, прогоняя их через сборщик. Сборщик переместит файл, поменяет имя, и вернёт новое имя, а может даже вставит inline-ссылкой (data url).
import Cat from '../images/Cat.png'
console.log(Cat) // выведет /img/Cat.45df63.png
<img :src="Cat" />
2. Но у меня раньше работало без импорта! Например, так:
<img src="@/assets/images/cat.png" />
Сборщик с
@vue/sfc-compiler
знает, что в src
в HTML и url()
в CSS указывается путь. Если он относительный (не с /), то он автоматически работает с ним, как с модулем, сам делая импорт. Но это должен быть статический путь именно в таком атрибуте. :src
с привязкой у JS вычислению или даже data-src
— работать не будут.<img :src="`@/assets/images/cat.png`" data-src="@/assets/images/cat.png" />
<img src="@/assets/images/dog.png" data-src="@/assets/images/dog.png" />
Превращается в
<img src="@/assets/cat.653gtd.png" data-src="@/assets/images/cat.png" />
<img src="/assets/dog.45df63.png" data-src="@/assets/images/dog.png" />
Только чистый
src
обработался, как путь до модуля.3. Что же тогда делать, если надо хранить путь в данных?
Можно использовать:
- Явные импорты, если заранее известен набор файлов
-
require
в Webpack-
new URL
в Vite (без поддержки алиасов и SSR)-
import.glob
в Vite, если нужен список всех файлов// Нам нужна картинка питомца из переменной
const myPet = 'dog'
// Webpack + Vite - прямой импорт
import cat from '@/assets/pets/cat.png'
import dog from '@/assets/pets/dog.png'
const pets = { cat, dog }
const myPetImage = pets[myPet]
// Webpack - require
const myPetImage = require(`../assets/pets/${myPet}.png`)
// Vite - new URL
const myPetImage = new URL(`../assets/pets/${myPet}.png`, import.iss.oneta.url).href
// Vite - import.glob
const petImages = import.iss.oneta.glob('../assets/pets/*.png', { eager: true })
const myPetImage = petImages[`../assets/pets/${myPet}.png`]
4. Но как работают все эти функции, если тут путь тоже вычисляется только в рантайме, а нужен ещё на этапе сборки?
Сборщик забирает шаблонную строку или конкатенацию строк. Затем считает, что вы можете импортировать в рантайме ЛЮБОЙ файл, подходящий под шаблон. В примерах выше сборщик найдёт все файлы
.png
в директории /assets/pets/
.Более сложные JS выражения не будут работать.
new URL(getPetImageByName(myPet)) // ❌ Не сработает
Подробности:
- https://vitejs.dev/guide/assets.html
- https://vitejs.dev/guide/features.html#glob-import
- https://webpack.js.org/guides/asset-management/#loading-images
- https://github.com/vitejs/vite/issues/10597
👍8❤4🔥2👏1🤔1
Отличия ref и reactive
!ref #help
Ref:
- позволяет удобно и просто перезаписать переменную целиком:
- может быть использован с примитивами (string, number, boolean и т.д.);
- представляет из себя геттер и сеттер в случае с примитивами (без Proxy);
- в случае с объектами просто вызывает
- обязательно имеет контейнер, в котором хранит значение (.value), о котором нельзя забывать.
Reactive:
- работает только с непримитивными значениями (объекты и массивы);
- использует Proxy и глубокую реактивность по умолчанию;
- не может быть просто перезаписан целиком по аналогии с
- удобен для группировки связанных значений в общий объект (чтобы не создавать отдельные независимые переменные для связанного состояния);
- поддерживает ref unwrapping (https://vuejs.org/guide/essentials/reactivity-fundamentals.html#additional-ref-unwrapping-details), а значит в него можно положить другие ref’ы, и они раскроются (не нужно будет писать лишний .value) внутри объекта;
- иногда может быть удобнее в типизации - для него не нужно использовать отдельный тип
В общем случае можно просто использовать
Полезные ссылки:
1. https://vuejs.org/guide/essentials/reactivity-fundamentals.html
2. https://vuejs.org/guide/extras/reactivity-in-depth.html#how-reactivity-works-in-vue
3. https://stackoverflow.com/questions/61452458/ref-vs-reactive-in-vue-3/65262638#65262638
!ref #help
ref
и reactive
позволяют создать реактивную переменную, но имеют некоторые отличия:Ref:
- позволяет удобно и просто перезаписать переменную целиком:
example.value = 123
, при этом сохранив реактивность;- может быть использован с примитивами (string, number, boolean и т.д.);
- представляет из себя геттер и сеттер в случае с примитивами (без Proxy);
- в случае с объектами просто вызывает
reactive
и передает обработку ему;- обязательно имеет контейнер, в котором хранит значение (.value), о котором нельзя забывать.
Reactive:
- работает только с непримитивными значениями (объекты и массивы);
- использует Proxy и глубокую реактивность по умолчанию;
- не может быть просто перезаписан целиком по аналогии с
ref
, потому что потеряется реактивность;- удобен для группировки связанных значений в общий объект (чтобы не создавать отдельные независимые переменные для связанного состояния);
- поддерживает ref unwrapping (https://vuejs.org/guide/essentials/reactivity-fundamentals.html#additional-ref-unwrapping-details), а значит в него можно положить другие ref’ы, и они раскроются (не нужно будет писать лишний .value) внутри объекта;
- иногда может быть удобнее в типизации - для него не нужно использовать отдельный тип
MaybeRef<T>
, как в случае с обычным ref
(например, если хочется иметь объект, который может быть как реактивным, так и нет, то типизация и работа с reactive
будет в целом выглядеть удобнее).В общем случае можно просто использовать
ref
, если это кажется проще, но про reactive
тоже полезно помнить, потому что его особенности могут рано или поздно пригодиться.Полезные ссылки:
1. https://vuejs.org/guide/essentials/reactivity-fundamentals.html
2. https://vuejs.org/guide/extras/reactivity-in-depth.html#how-reactivity-works-in-vue
3. https://stackoverflow.com/questions/61452458/ref-vs-reactive-in-vue-3/65262638#65262638
🔥9👍7👏3❤2🤔1
Зачем Pinia, если можно написать свой стор?
!store #help
Во-первых, это прежде всего велосипед - мы пишем свое собственное решение, которое делает то же самое, что и Pinia.
Во-вторых, у этого велосипеда будет масса недостатков по сравнению с готовым решением:
1. Свой простенький стор не будет унифицирован - у него нет единого API, которое диктует формат определения новых сторов, описания их полей и методов. Можно описывать каждое свойство в виде
2. Если идти по пути комплексного решения, продумывать унифицированный интерфейс (аналог
3. В Pinia сторы инициализируются лениво: если в приложении описано 20 сторов, но на странице используется только один, то инициализирован будет тоже только один. В своем решении из коробки не будет “ленивости”, это отдельный функционал, который требует времени на реализацию.
4. В своем простеньком сторе не будет поддержки SSR: код, описанный в ES-модуле, выполняется на сервере только один раз (при старте сервера), а затем переиспользуется каждым клиентом. Это значит, что стор будет один общий на всех клиентов, вместо изолированных инстансов под каждого клиента. В своем сторе не будет поддержки сериализации для передачи данных с сервера на клиент.
5. Переменные, описанные в скоупе ES-модуля, являются глобальными, поэтому, если эти переменные будут использованы в любом другом коде и на них останутся ссылки, то сборщик мусора будет игнорировать такой код и никогда не освободит память, которую этот код занимает. В Pinia такой проблемы нет, потому что сторы создаются не в скоупе модуля.
6. В Pinia все сторы объединены в общий
7. В Pinia все сторы сгруппированы и хранятся в одной общей Map-структуре, в которой всегда можно найти любой стор. В своей реализации сторы будут раскиданы по модулям и ничем не объединены.
8. В Pinia есть поддержка HMR: стейт точечно обновляется при изменении кода, а не сбрасывается целиком, как было бы в своей собственной реализации.
9. В Pinia есть система плагинов: удобно подвязываться на жизненный цикл стора и, например, писать интеграции с внешними хранилищами. И для этого есть унифицированный, задокументированный и оттестированный API.
10. Pinia интегрирована во Vue DevTools: можно смотреть на таймлайны, отслеживать вызовы функций и дебажить сторы.
При этом у своего решения, как правило, практически нет никаких весомых плюсов, кроме потенциально меньшего размера. Но, как понятно из пунктов выше, за эту экономию придется платить функционалом и удобством.
!store #help
Во-первых, это прежде всего велосипед - мы пишем свое собственное решение, которое делает то же самое, что и Pinia.
Во-вторых, у этого велосипеда будет масса недостатков по сравнению с готовым решением:
1. Свой простенький стор не будет унифицирован - у него нет единого API, которое диктует формат определения новых сторов, описания их полей и методов. Можно описывать каждое свойство в виде
export const count = ref(0);
, а можно оборачивать все в useCount
. Этот формат будет негласным и его нужно проговаривать с командой, документировать и делать то, что уже сделано в Pinia.2. Если идти по пути комплексного решения, продумывать унифицированный интерфейс (аналог
defineStore
), то это будет путь к своей копии Pinia, только это решение не покрыто тестами, не прошло проверку в проде, не тестировалось на утечки памяти, не знакомо другим разработчикам, его нельзя добавить в новый проект одной командой и еще много других “не”.3. В Pinia сторы инициализируются лениво: если в приложении описано 20 сторов, но на странице используется только один, то инициализирован будет тоже только один. В своем решении из коробки не будет “ленивости”, это отдельный функционал, который требует времени на реализацию.
4. В своем простеньком сторе не будет поддержки SSR: код, описанный в ES-модуле, выполняется на сервере только один раз (при старте сервера), а затем переиспользуется каждым клиентом. Это значит, что стор будет один общий на всех клиентов, вместо изолированных инстансов под каждого клиента. В своем сторе не будет поддержки сериализации для передачи данных с сервера на клиент.
5. Переменные, описанные в скоупе ES-модуля, являются глобальными, поэтому, если эти переменные будут использованы в любом другом коде и на них останутся ссылки, то сборщик мусора будет игнорировать такой код и никогда не освободит память, которую этот код занимает. В Pinia такой проблемы нет, потому что сторы создаются не в скоупе модуля.
6. В Pinia все сторы объединены в общий
effectScope
, а значит любой стор можно одной строкой “удалить”, очистив все его ref/computed/watch/watchEffect/etc., и освободив память. В своей простой реализации так сделать будет нельзя.7. В Pinia все сторы сгруппированы и хранятся в одной общей Map-структуре, в которой всегда можно найти любой стор. В своей реализации сторы будут раскиданы по модулям и ничем не объединены.
8. В Pinia есть поддержка HMR: стейт точечно обновляется при изменении кода, а не сбрасывается целиком, как было бы в своей собственной реализации.
9. В Pinia есть система плагинов: удобно подвязываться на жизненный цикл стора и, например, писать интеграции с внешними хранилищами. И для этого есть унифицированный, задокументированный и оттестированный API.
10. Pinia интегрирована во Vue DevTools: можно смотреть на таймлайны, отслеживать вызовы функций и дебажить сторы.
При этом у своего решения, как правило, практически нет никаких весомых плюсов, кроме потенциально меньшего размера. Но, как понятно из пунктов выше, за эту экономию придется платить функционалом и удобством.
👍13🔥3❤2