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