Релиз Vue 2.6
04.02.2019 мы рады объявить о выпуске Vue 2.6 «Macross»!
В прошлом году мы потратили много времени на разработку нового CLI и создание прототипа для версии 3.0. В результате ветка Vue core 2.x давно не получала серьезных обновлений. Давно пора! Очередная новая версия объединяет ряд существенных улучшений, внутренних изменений и новых функций, которые мы описали в этом посте. Для получения более подробной информации обязательно ознакомьтесь с полным примечанием к выпуску на GitHub.
Slots: Новый синтаксис, улучшение производительности & совместимость в версией 3.0
Слоты являются важным механизмом, который позволяет гибкую композицию компонентов в Vue. Во время создания прототипа для версии 3.0 мы обнаружили несколько способов улучшить их. Некоторые из них могут быть внедрены без внесения значительных изменений, что позволяет нам включить их в версии 2.x. Для тех, которые требует более серьезных изменений, мы также попытаемся предоставить способы постепенного внедрения в 2.x, которые облегчили бы будущие миграции.
Новый синтаксис
Первым шагом является новый синтаксис слотов с ограниченной областью видимости (scoped slot). Мы предложили, обсудили и экспериментировали с рядом различных конструкций (1, 2, 3) и в конечном итоге определили новый синтаксис v-slot
, описанный в этом RFC. Краткий пример использования именованных слотов (named slot):
<my-component> <template v-slot:header> <p>Header</p> </template> <template v-slot:item="{ data }"> <h2>{{ data.title }}</h2> <p>{{ data.text }}</p> </template> <template v-slot:footer> <p>Footer</p> </template> </my-component>
Новый синтаксис объединяет использование обычных и слотов с ограниченной областью видимости в одной директиве и обеспечивает более явное и удобочитаемое использование именованных слотов. Он также полностью совместим с существующим синтаксисом, что позволяет нам выпустить его сегодня в версии 2.6.
Если вы уже знакомы с существующим синтаксисом слотов, мы рекомендуем вам прочитать RFC , чтобы лучше понять суть нового синтаксиса. Если вы еще не знакомы со слотами, рекомендуется вместо этого просмотреть обновленную документацию по слотам.
Улучшение производительности
Еще одно улучшение слотов, которое мы хотели бы видеть в 3.0, — это унификация слотов с обычной и ограниченной области видимости с точки зрения реализации из-за преимущества производительности слотов с ограниченным области видимости. Обычные слоты отображаются во время родительского цикла рендеринга. Когда изменяется зависимость слота, он вызывает повторный рендеринг как родительского, так и дочернего компонентов. Слоты с ограничениями, с другой стороны, компилируются в встроенные функции (inline functions) и вызываются во время цикла рендеринга дочернего компонента. Это означает, что любые зависимости данных, на которые опирается слот с ограниченной областью видимости, получает дочерний компонент, что приводит к более точным обновлениям. В версии 2.6 мы представили оптимизацию, которая дополнительно гарантирует, что мутации зависимостей родительской области влияют только на родительскую область и больше не будут заставлять дочерний компонент обновляться, если он использует только ограниченные слоты.
К тому же:
- Все слоты, использующие новый синтаксис
v-slot
, компилируются в слоты с ограниченными областями видимости. Это означает, что все слоты, использующие новый синтаксис, будут с улучшенной производительностью; - Все обычные слоты теперь также отображаются в
this.$scopedSlots
как функции. Это означает, что пользователи, использующие функции рендеринга вместо шаблонов, теперь могут всегда использоватьthis.$scopedSlots
, не беспокоясь о том, какие типы слотов передаются.
В версии 3.0 больше не будет различий между слотами с ограниченной областью действия и без нее — все слоты будут использовать один и тот же унифицированный синтаксис, скомпилированы в один и тот же формат и будут иметь одинаковую улучшенную производительность.
Асинхронная обработка ошибок
Встроенный в Vue механизм обработки ошибок (в компонентах errorCaptured
и глобальный хук errorHandler
) теперь также фиксирует ошибки внутри v-on обработчиков. Кроме того, если какой-либо из хуков жизненного цикла или обработчиков событий выполняет асинхронные операции, теперь вы можете вернуть Promise из функции, чтобы любые необработанные ошибки из этой цепочки Promise также отправлялись вашим обработчикам ошибок. Это становится еще проще, если вы используете async/await, поскольку асинхронные функции неявно возвращают Promises:
export default { async mounted() { // if an async error is thrown here, it now will get // caught by errorCaptured and Vue.config.errorHandler this.posts = await api.getPosts() } }
Динамические Директивные Аргументы
Директивные аргументы теперь могут принимать динамические выражения JavaScript:
<div v-bind:[attr]="value"></div> <div :[attr]="value"></div> <button v-on:[event]="handler"></button> <button @[event]="handler"></button> <my-component> <template v-slot:[slotName]> Dynamic slot name </template> </my-component>
Более подробную информацию можно найти в этом RFC. Теперь, если значение аргумента равно null, binding/listener (привязка/слушатель) будет удалена.
Примечание для авторов библиотек: для этой функции требуется среда исполнения Vue версии 2.6.0 или выше. Если вы воспользуетесь предварительно скомпилированными компонентами и захотите поддерживать совместимость с версиями до 2.6, то не используйте новый синтаксис в своем исходном коде.
Примеры кода в предупреждающих сообщениях компилятора
Благодаря звездному запросу GitHub пользователя @gzzhanghao, начиная с версии 2.6, большинство предупреждений о компиляции шаблонов теперь содержат информацию об исходном коде:
Явное создание автономных реактивных объектов
2.6 представляет новое глобальное API для явного создания автономных реактивных объектов:
const reactiveState = Vue.observable({ count: 0 })
Полученный объект может быть использован непосредственно в вычисляемых свойствах или функциях рендеринга, и будет вызывать соответствующие обновления при мутации.
Предварительная выборка данных во время рендеринга на стороне сервера
Новый хук serverPrefetch позволит любому компоненту (а не только компонентам уровня маршрута (route-level)) предварительно извлекать данные во время рендеринга на стороне сервера, обеспечивая более гибкое использование и уменьшая связь между извлечением данных и маршрутизатором. Такие проекты, как Nuxt и vue-apollo, уже планируют упростить свои реализации с помощью этой новой функции.
Сборка ES для прямого импорта в браузере
Ранее наша сборка модуля ES в первую очередь предназначалась для использования со сборщиками пакетов. Эти сборки содержат использование переменных среды, которые должны быть заменены во время компиляции. Vue 2.6 теперь также предоставляет сборку модуля ES, предназначенную для непосредственного использования в браузере:
<script type="module"> import Vue from 'https://unpkg.com/vue/dist/vue.esm.browser.js' new Vue({ // ... }) </script>
Важные внутренние изменения
Возврат nextTick в Microtask
В 2.5.0 мы внесли внутреннюю корректировку, которая заставила nextTick использовать Macrotaks вместо Microtasks, чтобы ставить обновления в очередь, если обновление было инициировано в обработчике событий v-on. Первоначально это было предназначено для исправления некоторых особенных ситуаций, что, в свою очередь, привело к ряду других проблем. В версии 2.6 мы нашли более простое исправление для первоначальной проблемы, которое позволяет нам вернуть nextTick для последовательного использования Microtasks во всех случаях.
Если вам интересно технические детали почитать об этом можно здесь.
Функции в this.$scopedSlots
теперь всегда возвращает массивы
(Это изменение влияет только на пользователей функции рендеринга.) В функциях рендеринга слоты с областью видимости представлены в this.$scopedSlots
как функции. До сих пор вызов функции слота с ограниченой областью видимости мог вернуть один VNode или массив VNodes в зависимости от того, что передает родительский компонент. Это был честный недосмотр, поскольку он делает тип возвращаемого значения неопределенным и может привести к непреднамеренным ситуациям. В версии 2.6 функции слотов с ограниченой областью видимости теперь гарантированно возвращают либо массив VNodes, либо undefined
. Это может повлиять на некоторый существующий код, если он неправильно проверяет возможные возвращаемые значения Array. Подробнее здесь.
Заключение
Спасибо авторам, которые делали пул запросы для этого релиза, и всем членам сообщества, которые участвовали в обсуждениях RFC.