[Официально] Выпущен Vue 2.6

внешний интерфейс Vue.js
[Официально] Выпущен Vue 2.6

Английский оригинал:medium.com/he и -v UE-POI…

Только вчера отпраздновали 5-ю годовщину выпуска Vue, и сегодня мы куем железо, пока горячо, чтобы выпустить Vue 2.6 «Macross» в канун Нового года. Поздравляем всех с китайским Новым годом!

За последний год мы потратили много сил на исследование дизайна/прототипирования нового интерфейса командной строки и версии 3.0, поэтому Vue 2.x не получал крупных обновлений в течение относительно долгого времени. Уже почти время! Этот 2.6 включает в себя несколько довольно значительных обновлений, и мы обсудим некоторые из основных моментов здесь - см. Полную информацию здесь.release note.

Слоты: новый синтаксис, оптимизация производительности, готовность к версии 3.0

Слоты являются важным механизмом для компонентов Vue, поскольку они обеспечивают гибкую композицию между полностью несвязанными компонентами. В процессе создания прототипа версии 3.0 мы обнаружили несколько способов дальнейшего улучшения существующего механизма слотов. Для некоторых из них могут потребоваться незначительные критические изменения, но другие могут быть введены в 2.x с полной обратной совместимостью. Для тех улучшений, которые требуют критических изменений, мы также пытаемся постепенно привести их в соответствие с API 3.0, внося полностью совместимые изменения в 2.x.

новый синтаксис

Во-первых, мы ввели новый синтаксис шаблонов для слотов. Изменения синтаксиса — это то, что мы редко делаем (и единственное, запланированное для версии 3.0), поэтому мы попробовали несколько разных дизайнов и много обсуждали. Наконец, мы остановились на синтаксисе, основанном на новой директиве v-slot (см. конкретные детали дизайнаRFC).这里是两个简略的例子:

Scoped Scoped Scoped

<my-component v-slot="{ msg }">
  {{ msg }}
</my-component>

именованные слоты

<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чтобы лучше понять, почему новый синтаксис разработан таким образом. Если вы не знакомы со слотом, рекомендуется прочитать его напрямую.обновленная документация(Или подождите, пока Pythagorean обновит китайский перевод).

оптимизация производительности

Еще одно улучшение слотов, которое мы надеемся достичь в версии 3.0, — это унификация внутренней реализации слотов и слотов с ограниченной областью действия для лучшей оптимизации производительности. Обычные слоты генерируются в функции рендеринга родительского компонента, поэтому, когда данные, от которых зависит обычный слот, изменяются, сначала запускается обновление родительского компонента, а затем новое содержимое слота передается дочернему компоненту, вызывая подкомпонент. Обновить. Напротив, слот с областью действия генерирует функцию во время компиляции, и после того, как эта функция будет передана дочернему компоненту, она будет вызываться в функции рендеринга дочернего компонента. Это означает, что зависимости слота с областью действия будут собираться подкомпонентом, поэтому при изменении зависимости непосредственно будет обновляться только подкомпонент. В версии 2.6 мы ввели еще одну оптимизацию: если дочерний компонент использует только слот с ограниченной областью действия, то сам родительский компонент не будет принудительно обновляться при изменении его собственных зависимостей. Эта оптимизация делает зависимости между родительскими и дочерними компонентами полностью развязанными даже при наличии слотов, что обеспечивает оптимальную общую эффективность обновления. (Напротив, когда React использует свойства рендеринга, в большинстве случаев родительский и дочерний компоненты будут обновляться вместе).

Помимо:

  • Все слоты, использующие новый синтаксис v-slot, компилируются как слоты с ограниченной областью действия. Это означает, что весь код слота, использующий новый синтаксис, получит указанные выше оптимизации производительности;
  • Все слоты без области действия теперь также отображаются как функции в this.$scopedSlots . Если вы являетесь пользователем функции рендеринга напрямую, теперь вы можете полностью отказаться от this.$slots и использовать this.$scopedSlots для всех слотов. (в 3.0 this.$slots будет напрямую предоставлять функцию, заменяя this.$scopedSlots)

В версии 3.0 не будет различий между обычными слотами и слотами с ограниченной областью действия — все слоты используют унифицированный синтаксис, используют унифицированную внутреннюю реализацию и получают одинаковые оптимизации производительности.

Асинхронная обработка ошибок

Встроенные механизмы обработки ошибок Vue (обработчик errorCaptured в компонентах и ​​глобальная конфигурация errorHandler) теперь также обрабатывают ошибки, возникающие в функциях прослушивателя v-on. Кроме того, если обработчики жизненного цикла вашего компонента или практические прослушиватели имеют асинхронные операции, вы можете позволить Vue обрабатывать возможные асинхронные ошибки, возвращая Promise. Если вы используете async/await, это еще проще, потому что асинхронные функции по умолчанию возвращают Promise:

export default {
  async mounted() {
    // 这里抛出的异步错误会被 errorCaptured 或是
    // 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.

Авторам библиотек компонентов следует обратить внимание: этот синтаксис требует взаимодействия со средой выполнения версии 2.6 или выше. Если вы отправляете предварительно скомпилированный компонент и хотите сохранить совместимость с версиями до 2.6, не используйте эту функцию.

Информация о расположении предупреждений о компиляции

Начиная с версии 2.6, все предупреждения компилятора содержат информацию о расположении источника. Это позволяет нам генерировать более полезные предупреждения:

Явно создавать реактивные объекты

В версии 2.6 представлен новый глобальный API, который можно использовать для явного создания реактивных объектов:

const reactiveState = Vue.observable({
  count: 0
})

Результирующий объект можно использовать непосредственно в вычисляемых свойствах и функциях рендеринга, и при изменении он будет запускать соответствующие обновления.

Предварительная выборка данных SSR

новыйхук serverPrefetchПозволяет любому компоненту запрашивать асинхронные данные во время серверного рендеринга (больше не ограничивается компонентами маршрутизации). Это делает общую схему предварительной выборки данных более гибкой и не связанной с маршрутизацией. Такие проекты, как Nuxt и vue-apollo, уже планируют использовать эту функцию для упрощения своих внутренних реализаций и предоставления новых возможностей.

Модули ES создают файлы, которые можно импортировать прямо в браузер.

Файл сборки ES Modules предыдущей версии Vue предназначен для инструментов упаковки, поэтому он содержит некоторые переменные среды, которые необходимо заменить во время сборки, что делает невозможным его использование непосредственно в браузере. 2.6 включает версию, которую можно импортировать прямо в браузере:

<script type="module">
import Vue from 'https://unpkg.com/vue/dist/vue.esm.browser.js'
  
new Vue({
  // ...
})
</script>

Важные внутренние изменения

nextTick перенастроен для использования всех микрозадач

В версии 2.5 мы представили изменение, позволяющее использовать макрозадачу вместо микрозадачи для асинхронной буферизации, когда прослушиватель событий v-on DOM запускает обновление. Первоначально это было введено для исправления ошибок, вызванных особыми пограничными случаями в классе браузеров, но само изменение вызвало гораздо больше проблем. В версии 2.6 мы нашли более простое исправление для исходного маргинального случая, поэтому в этом изменении макрозадачи нет необходимости. Теперь nextTick будет использовать Microtask единообразно. Если вас интересуют конкретные детали, см.здесь.

Функция This.$scopedSlots равномерно возвращает массив

(Это изменение касается только пользователей, использующих функцию рендеринга.) В функции рендеринга переданный слот с заданной областью действия отображается как функция в this.$scopedSlots . В предыдущих версиях эти функции возвращали один виртуальный узел или массив виртуальных узлов в зависимости от того, что было передано из родительского компонента. Это было упущением в исходной реализации, из-за которого возвращаемый тип функции слота с областью действия был неопределенным. В версии 2.6 все функции слота с областью действия будут возвращать только массив VNodes или undefined. Если ваш существующий код использует this.$scopedSlots и не обрабатывает случай, когда может быть возвращен массив, вам может потребоваться исправить его соответствующим образом. подробнеепосмотреть здесь.

Спасибо

Спасибо всем участникам, предоставившим PR для этого релиза, и членам сообщества, участвовавшим в обсуждениях RFC.