# Изменена обработка пользовательских элементов
кардинальное изменение

# Обзор

  • КАРДИНАЛЬНОЕ ИЗМЕНЕНИЕ: Проверка для определения какие теги следует рассматривать как пользовательские элементы теперь происходит на этапе компиляции шаблона, поэтому теперь настраиваются в опциях компилятора, а не в конфигурации выполнения.
  • КАРДИНАЛЬНОЕ ИЗМЕНЕНИЕ: Использование специального атрибута is теперь допускается только на теге <component>.
  • НОВОЕ: Для поддержки случаев, когда в версиях 2.x is использовался на нативных элементах для обхода ограничений парсинга HTML, теперь необходимо добавлять префикс vue: для обработки его как компонента Vue.

# Автономные пользовательские элементы

Если требуется использовать пользовательский элемент, определённый вне Vue (например, используя Web Components API), необходимо «проинструктировать» Vue обрабатывать его как пользовательский элемент. Рассмотрим следующий шаблон в качестве примера.

<plastic-button></plastic-button>
1

# Синтаксис в 2.x

Во Vue 2.x, установка какие теги должны рассматриваться как пользовательские элементы выполнялась с помощью опции Vue.config.ignoredElements:

// В этом случае Vue игнорирует пользовательский элемент, определённый вне Vue
// (например, при использовании Web Components API)

Vue.config.ignoredElements = ['plastic-button']
1
2
3
4

# Синтаксис в 3.x

Во Vue 3.0 эта проверка выполняется на этапе компиляции шаблона. Чтобы компилятор обрабатывал <plastic-button> как пользовательский элемент:

  • При наличии шага сборки необходимо передать функцию isCustomElement в компилятор шаблонов Vue. А при использовании vue-loader через его опцию compilerOptions:

    // в конфигурации webpack
    rules: [
      {
        test: /\.vue$/,
        use: 'vue-loader',
        options: {
          compilerOptions: {
            isCustomElement: tag => tag === 'plastic-button'
          }
        }
      }
      // ...
    ]
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
  • При компиляции шаблонов на лету нужно передавать через app.config.compilerOptions.isCustomElement:

    const app = Vue.createApp({})
    
    app.config.compilerOptions.isCustomElement = tag => tag === 'plastic-button'
    
    1
    2
    3

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

# Модифицированные встроенные элементы

Спецификация пользовательских элементов позволяет использовать их как модифицированные встроенные элементы (opens new window) добавив атрибут is на встроенный элемент:

<button is="plastic-button">Нажми меня!</button>
1

Vue использовал специальный атрибут is для симуляции поведения родного атрибута до того, как он станет доступен в браузерах. Однако, в версиях 2.x он интерпретируется как отрисовываемый компонент Vue с именем plastic-button. Это блокирует использование нативного варианта модифицированных встроенных элементов, упомянутого выше.

С версии 3.0 специальная обработка атрибута is ограничена только тегом <component>.

  • При использовании на зарезервированном теге <component>, поведение будет как в 2.x;

  • При использовании на обычном компоненте будет считаться обычным атрибутом:

    <foo is="bar" />
    
    1
    • Поведение в 2.x: будет отрисован компонент bar.
    • Поведение в 3.x: будет отрисован компонент foo и передан атрибут is.
  • При использовании на обычных элементах, будет передаваться в вызов createElement в качестве атрибута is, а также отрисован как нативный атрибут. Это добавляет поддержку использования модифицированных встроенных элементов.

    <button is="plastic-button">Нажми меня!</button>
    
    1
    • Поведение в 2.x: будет отрисован компонент plastic-button.

    • Поведение в 3.x: будет отрисована нативная кнопка с помощью вызова

      document.createElement('button', { is: 'plastic-button' })
      
      1

Флаги сборки для миграции: COMPILER_IS_ON_ELEMENT

# Префикс vue: для обхода ограничений парсинга шаблонов в DOM

Примечание: этот раздел затрагивает только те случаи, когда шаблоны Vue находятся непосредственно в HTML страницы.

При использовании шаблонов в DOM, они будут подчиняться нативным правилам парсинга HTML. Некоторые HTML-элементы, такие как <ul>, <ol>, <table> и <select>, имеют ограничения на то, какие элементы могут быть внутри них, а некоторые элементы, такие как <li>, <tr> и <option> могут быть указаны только внутри определённых элементов.

# Синтаксис в 2.x

Во Vue 2 для обхода этих ограничений рекомендовалось использовать атрибут is на нативном теге:

<table>
  <tr is="blog-post-row"></tr>
</table>
1
2
3

# Синтаксис в 3.x

С изменением поведения is, теперь требуется указывать префикс vue: для обработки элемента как компонента Vue:

<table>
  <tr is="vue:blog-post-row"></tr>
</table>
1
2
3

# Стратегия миграции

  • Заменить config.ignoredElements на compilerOptions для vue-loader (при наличии шага сборки) или на app.config.compilerOptions.isCustomElement (при компиляции шаблонов на лету)

  • Изменить все не-<component> теги с использованием is на <component is="..."> (для шаблонов в однофайловых компонентах) или добавить к ним префикс vue: (для шаблонов в DOM).