Skip to content

Міграційна збірка

Огляд

@vue/compat (така ж «міграційна збірка») — це збірка Vue 3, яка забезпечує настроювану поведінку, сумісну з Vue 2.

Міграційна збірка виконується в режимі Vue 2 за замовчуванням - більшість загальнодоступних API поводяться так само, як Vue 2, лише за кількома винятками. Використання функцій, які були змінені або застарілі у Vue 3, видасть попередження під час виконання. Сумісність функції також можна ввімкнути/вимкнути для кожного компонента.

Випадки використання за призначенням

  • Оновлення програми Vue 2 до Vue 3 (з обмеженнями)
  • Перенесення бібліотеки на Vue 3
  • Досвідчені розробники Vue 2, які ще не пробували Vue 3, можуть використовувати збірку міграції замість Vue 3, щоб допомогти дізнатися різницю між версіями.

Відомі обмеження

Попри те, що ми докладаємо всіх зусиль, щоб збірка для міграції якомога більше імітувала поведінку Vue 2, є деякі обмеження, через які ваш додаток не можна оновити:

  • Залежності, які покладаються на внутрішні API Vue 2 або недокументовану поведінку. Найпоширенішим випадком є використання приватних властивостей у VNodes. Якщо ваш проєкт покладається на такі бібліотеки компонентів, як Vuetify, Quasar або ElementUI, найкраще дочекатися їхніх версій, сумісних з Vue 3.

  • Підтримка Internet Explorer 11: Vue 3 офіційно відмовився від плану підтримки IE11. Якщо вам все ще потрібна підтримка IE11 або нижче, вам доведеться залишитися на Vue 2.

  • Візуалізація на стороні сервера: збірку міграції можна використовувати для SSR, але міграція користувацьких налаштувань SSR набагато складніша. Загальна ідея полягає в тому, щоб замінити vue-server-renderer на @vue/server-renderer. Vue 3 більше не надає пакетний рендерер, тому рекомендується використовувати Vue 3 SSR із Vite. Якщо ви використовуєте Nuxt.js, можливо, краще дочекатися Nuxt 3.

Очікування

Зауважте, що збірка міграції має на меті охопити лише публічно задокументовані API та поведінку Vue 2. Якщо ваша програма не запускається в збірці міграції через незадокументовану поведінку, малоймовірно, що ми налаштуємо збірку міграції відповідно до вашого конкретного випадку. Натомість подумайте про рефакторинг, щоб усунути залежність від розглянутої поведінки.

Застереження: якщо ваша програма є великою та складною, міграція, ймовірно, буде проблемою навіть зі збіркою міграції. Якщо ваш додаток, на жаль, не підходить для оновлення, зверніть увагу, що ми плануємо резервно перенести композиційний API та деякі інші функції Vue 3 у випуск 2.7 (приблизно наприкінці третього кварталу 2021 року).

Якщо ви запустите свою програму на збірці для міграції, ви можете відправити її в робочу версію до завершення міграції. Хоча є невеликі накладні витрати на продуктивність/розмір, це не повинно помітно вплинути на робочий UX. Можливо, вам доведеться це зробити, якщо у вас є залежності, які залежать від поведінки Vue 2 і не можуть бути оновлені/замінені.

Міграційна збірка надаватиметься, починаючи з версії 3.1, і продовжуватиме публікуватися разом із версією версії 3.2. Зрештою ми плануємо припинити публікацію збірки для міграції в майбутній проміжній версії (не раніше кінця 2021 року), тому ви все одно повинні прагнути перейти на стандартну збірку до цього.

Процес оновлення

У наведеному нижче робочому процесі описано етапи міграції фактичної програми Vue 2 (Vue HackerNews 2.0) до Vue 3. Повні коміти можна знайти тут. Зауважте, що фактичні кроки, необхідні для вашого проєкту, можуть відрізнятися, і ці кроки слід розглядати як загальне керівництво, а не суворі інструкції.

Приготування

Встановлення

  1. Оновіть інструменти, якщо це можливо.

    • Якщо використовується спеціальне налаштування webpack: оновіть vue-loader до ^16.0.0.
    • Якщо використовується vue-cli: оновіть до останньої версії @vue/cli-service за допомогою vue upgrade
    • (Альтернатива) перейдіть на Vite + vite-plugin-vue2. [Приклад коміту]
  2. В package.json, оновіть vue до 3.1, встановіть @vue/compat тієї ж версії та замініть vue-template-compiler (якщо є) на @vue/compiler-sfc:

    diff
    "dependencies": {
    -  "vue": "^2.6.12",
    +  "vue": "^3.1.0",
    +  "@vue/compat": "^3.1.0"
       ...
    },
    "devDependencies": {
    -  "vue-template-compiler": "^2.6.12"
    +  "@vue/compiler-sfc": "^3.1.0"
    }
    

    Приклад змін

  3. У налаштуваннях збірки додайте псевдонім vue до @vue/compat і ввімкніть режим сумісності за допомогою параметрів компілятора Vue.

    Приклади конфігурацій

    vue-cli
    js
    // vue.config.js
    module.exports = {
      chainWebpack: (config) => {
        config.resolve.alias.set('vue', '@vue/compat')
    
        config.module
          .rule('vue')
          .use('vue-loader')
          .tap((options) => {
            return {
              ...options,
              compilerOptions: {
                compatConfig: {
                  MODE: 2
                }
              }
            }
          })
      }
    }
    
    "Чистий" webpack
    js
    // webpack.config.js
    module.exports = {
      resolve: {
        alias: {
          vue: '@vue/compat'
        }
      },
      module: {
        rules: [
          {
            test: /\.vue$/,
            loader: 'vue-loader',
            options: {
              compilerOptions: {
                compatConfig: {
                  MODE: 2
                }
              }
            }
          }
        ]
      }
    }
    
    Vite
    js
    // vite.config.js
    export default {
      resolve: {
        alias: {
          vue: '@vue/compat'
        }
      },
      plugins: [
        vue({
          template: {
            compilerOptions: {
              compatConfig: {
                MODE: 2
              }
            }
          }
        })
      ]
    }
    
  4. Якщо ви використовуєте TypeScript, вам також потрібно змінити набір тексту vue, щоб відобразити експорт за замовчуванням (якого більше немає у Vue 3), додавши файл *.d.ts із таким:

    ts
    declare module 'vue' {
      import { CompatVue } from '@vue/runtime-dom'
      const Vue: CompatVue
      export default Vue
      export * from '@vue/runtime-dom'
      const { configureCompat } = Vue
      export { configureCompat }
    }
    
  5. На цьому етапі ваша програма може зіткнутися з деякими помилками/попередженнями під час компіляції (наприклад, використання фільтрів). Спочатку виправте їх. Якщо всі попередження компілятора зникли, ви також можете встановити компілятор у режим Vue 3.

    Приклад змін

  6. Після виправлення помилок програма має працювати, якщо на неї не поширюються обмеження, згадані вище.

    Ймовірно, ви побачите БАГАТО попереджень як з командного рядка, так і з консолі браузера. Ось кілька загальних порад:

    • Ви можете фільтрувати певні попередження в консолі браузера. Бажано використовувати фільтр і зосереджуватися на виправленні одного елемента за раз. Ви також можете використовувати негативні фільтри, такі як -GLOBAL_MOUNT.

    • Ви можете скасувати певні застарілі параметри за допомогою налаштувань сумісності.

    • Деякі попередження можуть бути викликані залежністю, яку ви використовуєте (наприклад, vue-router). Ви можете перевірити це в трасуванні компонента попередження або трасуванні стека (розгортається після клацання). Спершу зосередьтеся на виправленні попереджень, які походять із вашого власного вихідного коду.

    • Якщо ви використовуєте vue-router, зауважте, <transition> і <keep-alive> не працюватимуть з <router-view>, доки ви не оновите до vue-router v4.

  7. Оновіть назви класів в <transition>. Це єдина функція, яка не має попередження під час виконання. Ви можете виконати пошук у всьому проєкті за назвами класів CSS .*-enter і .*-leave.

    Приклад змін

  8. Оновіть запис програми, щоб використовувати новий глобальний API монтування.

    Приклад змін

  9. Оновіть vuex до v4.

    Приклад змін

  10. Оновіть vue-router до v4. Якщо ви також використовуєте vuex-router-sync, ви можете замінити його засобом отримання сховища vuex.

    Після оновлення для використання <transition> і <keep-alive> з <router-view> потрібен новий синтаксис на основі області дії.

    Приклад змін

  11. Виділіть окремі попередження. Зауважте, що деякі функції мають конфліктну поведінку між Vue 2 і Vue 3 - наприклад, API функції візуалізації або зміна функціонального компонента проти асинхронного компонента. Щоб перейти на API Vue 3, не впливаючи на решту програми, ви можете вибрати поведінку Vue 3 для кожного компонента за допомогою параметра compatConfig.

    Приклад змін

  12. Коли всі попередження виправлено, ви можете видалити збірку міграції та переключитися на належну Vue 3. Зауважте, що ви, можливо, не зможете це зробити, якщо у вас все ще є залежності, які покладаються на поведінку Vue 2.

    Приклад змін

Конфігурація суміснності

Глобальна конфігурація

Функції сумісності можна вимкнути окремо:

js
import { configureCompat } from 'vue'

// вимкнути сумісність для певних функцій
configureCompat({
  FEATURE_ID_A: false,
  FEATURE_ID_B: false
})

Крім того, уся програма може за замовчуванням використовувати поведінку Vue 3, увімкнувши лише певні функції сумісності:

js
import { configureCompat } from 'vue'

// за замовчуванням все працює як Vue 3 і вмикає лише сумісність
// для певних особливостей
configureCompat({
  MODE: 3,
  FEATURE_ID_A: true,
  FEATURE_ID_B: true
})

Покомпонентна конфігурація

Компонент може використовувати параметр compatConfig, який очікує тих самих параметрів, що й глобальний метод configureCompat:

js
export default {
  compatConfig: {
    MODE: 3, // увімкнути поведінку Vue 3 лише для цього компонента
    FEATURE_ID_A: true // функції також можна перемикати на рівні компонентів
  }
  // ...
}

Конфігурація компілятора

Функції, які починаються з COMPILER_, залежать від компілятора: якщо ви використовуєте повну збірку (з компілятором у браузері), їх можна налаштувати під час виконання. Однак якщо використовується налаштування збірки, їх потрібно налаштувати за допомогою compilerOptions у конфігурації збірки (див. приклади конфігурацій вище).

Посилання на функції

Типи сумісності

  • ✔ Повністю сумісний
  • ◐ Частково сумісний із застереженнями
  • ⨂ Несумісний (лише попередження)
  • ⭘ Тільки режим сумісності (без попередження)

Несумісний

Має бути виправлено заздалегідь, інакше, ймовірно, призведе до помилок

IDТипОписДокументація
GLOBAL_MOUNT_CONTAINERЗмонтована програма не замінює елемент, до якого вона змонтованаlink
CONFIG_DEVTOOLSproduction devtools тепер є прапором під час збіркиlink
COMPILER_V_IF_V_FOR_PRECEDENCEПріоритет v-if і v-for при використанні для того самого елемента зміненоlink
COMPILER_V_IF_SAME_KEYГілки v-if більше не можуть мати однаковий ключlink
COMPILER_V_FOR_TEMPLATE_KEY_PLACEMENTКлюч <template v-for> тепер має бути поміщений у <template>link
COMPILER_SFC_FUNCTIONAL<template functional> більше не підтримується в однофайлових компонентахlink

Частково сумісний із застереженнями

IDТипОписДокументація
CONFIG_IGNORED_ELEMENTSconfig.ignoredElements тепер є config.compilerOptions.isCustomElement (лише у збірці компілятора браузера). Якщо використовується налаштування збірки, isCustomElement має бути передано через конфігурацію збірки.link
COMPILER_INLINE_TEMPLATEinline-template видалено (сумісність підтримується лише у збірці компілятора браузера)link
PROPS_DEFAULT_THISреквізити фабрики за замовчанням більше не мають доступу до this (у режимі compat this не є реальним екземпляром - він надає лише властивості, $options та ін’єкції)link
INSTANCE_DESTROYВидалено метод екземпляра $destroy (у режимі сумісності, підтримується лише в кореневому екземплярі)
GLOBAL_PRIVATE_UTILVue.util є приватним і більше не доступний
CONFIG_PRODUCTION_TIPconfig.productionTip більше не потрібенlink
CONFIG_SILENTconfig.silent видалено

Тільки режим сумісності (без попередження)

IDТипОписДокументація
TRANSITION_CLASSESПерехід до занять/залишення зміненоlink

Повністю сумісний

IDТипОписДокументація
GLOBAL_MOUNTnew Vue() -> createApplink
GLOBAL_EXTENDVue.extend видалено (використовуйте опцію defineComponent або extends)link
GLOBAL_PROTOTYPEVue.prototype -> app.config.globalPropertieslink
GLOBAL_SETVue.set видалено (більше не потрібен)
GLOBAL_DELETEVue.delete видалено (більше не потрібен)
GLOBAL_OBSERVABLEVue.observable видалено (використовуйте reactive)link
CONFIG_KEY_CODESconfig.keyCodes видаленоlink
CONFIG_WHITESPACEУ Vue 3 пробіл за замовчуванням `"condense".
INSTANCE_SETvm.$set видалено (більше не потрібен)
INSTANCE_DELETEvm.$delete видалено (більше не потрібен)
INSTANCE_EVENT_EMITTERvm.$on, vm.$off, vm.$once видаленоlink
INSTANCE_EVENT_HOOKSЕкземпляр більше не генерує події hook:xlink
INSTANCE_CHILDRENvm.$children видаленоlink
INSTANCE_LISTENERSvm.$listeners видаленоlink
INSTANCE_SCOPED_SLOTSvm.$scopedSlots видалено; vm.$slots тепер відкриває функціїlink
INSTANCE_ATTRS_CLASS_STYLE$attrs тепер включає class і stylelink
OPTIONS_DATA_FNdata має бути функцією в усіх випадкахlink
OPTIONS_DATA_MERGEdata з mixin або розширення тепер неглибоко об’єднаніlink
OPTIONS_BEFORE_DESTROYbeforeDestroy -> beforeUnmount
OPTIONS_DESTROYEDdestroyed -> unmounted
WATCH_ARRAYперегляд масиву більше не запускає мутацію, якщо вона не глибокаlink
V_ON_KEYCODE_MODIFIERv-on більше не підтримує модифікатори keyCodelink
CUSTOM_DIRНазви користувацьких директив зміненоlink
ATTR_FALSE_VALUEБільше не видаляється атрибут, якщо значення прив’язки є логічним falselink
ATTR_ENUMERATED_COERCIONБільше не перераховуються атрибути спеціального регіструlink
TRANSITION_GROUP_ROOT<transition-group> більше не рендерить кореневий елемент за замовчуваннямlink
COMPONENT_ASYNCAPI асинхронного компонента змінено (тепер потрібен defineAsyncComponent)link
COMPONENT_FUNCTIONALЗмінено API функціонального компонента (тепер мають бути звичайні функції)link
COMPONENT_V_MODELv-model компонента переробленоlink
RENDER_FUNCTIONAPI рендер функції зміненоlink
FILTERSФільтри видалено (цей параметр впливає лише на API фільтрів під час виконання)link
COMPILER_IS_ON_ELEMENTВикористання is обмежено лише до <component>link
COMPILER_V_BIND_SYNCv-bind.sync замінено на v-model з аргументамиlink
COMPILER_V_BIND_PROPМодифікатор v-bind.prop видалено
COMPILER_V_BIND_OBJECT_ORDERv-bind="object" тепер чутливий до порядкуlink
COMPILER_V_ON_NATIVEМодифікатор v-on.native видаленоlink
COMPILER_V_FOR_REFref в v-for (підтримка компілятора)
COMPILER_NATIVE_TEMPLATE<template> без спеціальних директив тепер відображається як рідний елемент
COMPILER_FILTERSфільтри (підтримка компілятора)