Skip to content
The translation is synced to the docs on of which the commit hash is 8a7fb04.

Construção de Migração

Visão Geral

A @vue/compat (mais conhecida como "a construção de migração") é uma construção de Vue 3 que fornece comportamento compatível de Vue 2 configurável.

A migração de construção executa no modo de Vue 2 por padrão - a maioria das APIs públicas comportam-se exatamente como a Vue 2, com apenas algumas exceções. O uso de funcionalidades que mudaram ou foram depreciadas na Vue 3 emitirão avisos de execução. Uma compatibilidade da funcionalidade também pode ser ativada ou desativada numa base por componente.

Casos de Uso Destinados

  • Atualizar uma aplicação de Vue 2 para Vue 3 (com limitações)
  • Migrar uma biblioteca para suportar a Vue 3
  • Para programadores de Vue 2 experientes que ainda não experimentaram a Vue 3, a construção de migração pode ser usada no lugar da Vue 3 para ajudar a aprender a diferença entre as versões.

Limitações Conhecidas

Embora temos nos esforçado em fazer a construção de migração imitar o comportamento da Vue 2 o máximo possível, existem algumas limitações que podem impedir a nossa aplicação de ser elegível para a atualização:

  • Dependências que dependem de APIs internas da Vue 2 ou comportamentos não documentados. O caso mais comum é o uso de propriedades privadas em VNodes. Se o nosso projeto depende de bibliotecas como Vuetify, Quasar ou ElementUI, é melhor aguardar por suas versões compatíveis com a Vue 3.

  • Suporte de Internet Explorer 11: a Vue 3 abandonou oficialmente o plano para o suporte de IE11. Se ainda precisarmos de suportar o IE11 ou abaixo, teremos de continuar na Vue 2.

  • Interpretação no lado do servidor: a construção de migração pode ser usada para interpretação no lado do servidor, mas migrar uma configuração de interpretação no lado do servidor está muito mais complicado. A ideia geral é substituir vue-server-renderer pela @vue/server-renderer. A Vue 3 não mais fornece um interpretador de pacote e é recomendado usar a interpretação no lado do servidor da Vue 3 com a (https://pt.vitejs.dev/guide/ssr). Se estivermos a usar Nuxt.js, é provavelmente melhor esperar pela Nuxt 3.

Expectativas

Nota que a construção de migração tem por objetivo cobrir apenas as APIs e comportamento de Vue 2 publicamente documentado. Se a nossa aplicação reprovar executar sob a construção de migração devido a dependência de comportamento não documentado, é pouco provável que façamos pequenas melhorias na construção de migração para atender este caso específico. Considere refazê-la para remover a dependência sobre o comportamento em questão.

Uma palavra de advertência: se a nossa aplicação for grande e complexa, a migração provavelmente será um desafio mesmo com a construção de migração. Se a nossa aplicação não estiver lamentavelmente adequada para atualização, nota que estamos a planear adicionar o suporte a API de Composição e algumas outras funcionalidades da Vue 3 ao lançamento da 2.7 (estimada para final de 2021).

Se conseguirmos que a nossa aplicação execute na construção de migração, podemos enviá-la para produção antes da migração estiver completa. Embora exista um pequeno custo de desempenho ou tamanho, não deveria afetar visivelmente a experiência de uso de produção. Nós podemos ter que o fazer quando tens dependências que dependem do comportamento da Vue 2, e não podem ser atualizadas ou substituídas.

A construção de migração será fornecida começando com a 3.1, e continuará a ser publicada junto a linha de lançamento 3.2. Nós planeamos eventualmente parar de publicar a construção de migração numa futura versão secundária (não antes do final do ano de 2021), assim deveríamos ainda aspirar mudar para a construção padrão antes disto.

Fluxo de Trabalho da Atualização

O seguinte fluxo de trabalho percorre as etapas de migração duma aplicação de Vue 2 verdadeira (Vue HackerNews 2.0) para Vue 3. As consolidações completas podem ser encontradas nesta ligação. Nota que as etapas propriamente dita necessárias para o nosso projeto pode variar, estas etapas deveriam ser tratadas como orientações gerais ao invés de instruções estritas.

Preparações

Instalação

  1. Atualizar o ferramental se aplicável.

    • Se usamos configuração de Webpack personalizada: Atualize a vue-loader para ^16.0.0.
    • Se usamos a vue-cli: atualizar para a @vue/cli-service mais recente com vue upgrade
    • (Alternativa) migrar para Vite + vite-plugin-vue2. [Consolidação de exemplo]
  2. No package.json, atualizar vue para 3.1, instalar @vue/compat da mesma versão, e substituir vue-template-compiler (se presente) com @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"
    }

    Consolidação de exemplo

  3. Na etapa de construção, definir vue como pseudónimo para @vue/compact e ativar o modo de compatibilidade através de opções do compilador da Vue.

    Configurações de Exemplo

    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 Simples
    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. Se estivermos a usar a TypeScrip, também precisaremos modificar os tipos da vue para expor a exportação padrão (que não está mais presente na Vue 3) adicionando um ficheiro *.d.ts com o seguinte:

    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 }
    }

Notemos que esta declaração de módulo deve ser colocada num ficheiro *.d.ts que contém pelo menos outra importação ou exportação de alto nível (export {} é o suficiente) para estes tipos aumentarem o módulo em vez de sobreescrevê-lo.

  1. Neste ponto, a nossa aplicação pode deparar-se com alguns erros de tempo de compilação ou avisos (por exemplo, uso de filtros). Temos que os corrigir primeiro. Se todos os avisos do compilador forem solucionados, também podemos definir o compilador para o modo de Vue 3.

    Consolidação de exemplo

  2. Depois de corrigir os erros, a aplicação deveria ser capaz de executar se não estiver sujeita às limitações mencionadas acima.

    Nós provavelmente veremos muitos avisos a partir de ambas linha de comando e a consola do navegador. Cá estão algumas dicas gerais:

    • Nós podemos filtrar por avisos específicos na consola do navegador. É uma boa ideia usar o filtro e focar-se em corrigir um item de cada vez. Nós também podemos filtros negados como -GLOBAL_MOUNT.

    • Nós podemos suprimir depreciações específicas através da configuração de compatibilidade.

    • Alguns avisos podem ser causados por uma dependência que usamos (por exemplo, vue-router). Nós podemos verificar isto a partir do vestígio de componente do aviso ou vestígio da pilha (expandida no clique). Primeiro, nos concentramos em corrigir os avisos que tem origem no nosso próprio código-fonte.

    • Se estivermos a usar a vue-router, nota que <transition> e <keep-alive> não funcionarão com <router-view> até atualizarmos para a vue-router versão 4.

  3. Atualizar os nomes de classe do <transition>. Esta é a única funcionalidade que não tem um aviso de tempo de execução. Nós podemos fazer uma pesquisa completa no projeto para procurar pelos nomes de classe de CSS .*-enter e .*-leave.

    Consolidação do exemplo

  4. Atualizar a entrada da aplicação para usar a nova API de montagem global.

    Consolidação do exemplo

  5. Atualizar vuex para versão 4.

    Consolidação do exemplo

  6. Atualizar a vue-router para versão 4. Se também usamos vuex-router-sync, podemos substituí-la com um recuperador de memória.

    Depois de atualizar, para usar <transition> e <keep-alive> com <router-view> precisamos de usar a nova sintaxe baseada em ranhura isolada.

    Consolidação do exemplo

  7. Escolha avisos individuais. Nota que algumas funcionalidades têm comportamentos que entram em conflito entre a Vue 2 e Vue 3 - por exemplo, a API da função de interpretação, ou o componente funcional vs. componente assíncrono mudam. Para migrar para a API da Vue 3 sem afetar o resto da aplicação, podemos optar pelo comportamento da Vue 3 sobre um fundamento por componente com a opção compatConfig.

    Consolidação do exemplo

  8. Quando todos os avisos estiverem corrigidos, podemos remover a construção de migração e trocar para a própria Vue 3. Nota que podemos não ser capazes de fazer isto se ainda tivermos dependências que dependem do comportamento da Vue 2.

    Consolidação do exemplo

Configuração de Compatibilidade

Configuração Global

As funcionalidades de compatibilidade podem ser desativadas individualmente:

js
import { configureCompat } from 'vue'

// desativar a compatibilidade para certas funcionalidades
configureCompat({
  FEATURE_ID_A: false,
  FEATURE_ID_B: false
})

Alternativamente, a aplicação inteira pode predefinir para o comportamento da Vue 3, com apenas certas funcionalidades ativadas:

js
import { configureCompat } from 'vue'

// predefinir tudo para o comportamento da Vue 3,
// e apenas ativar compatibilidade para certas funcionalidades
configureCompat({
  MODE: 3,
  FEATURE_ID_A: true,
  FEATURE_ID_B: true
})

Configuração Por Componente

Um componente pode usar a opção compatConfig, a qual espera as mesmas opções que o método configureCompat global:

js
export default {
  compatConfig: {
    MODE: 3, // optar pelo comportamento da Vue 3 apenas para este componente
    FEATURE_ID_A: true // funcionalidades também podem ser alternadas ao nível do componente
  }
  // ...
}

Configuração Específica do Compilador

As funcionalidades que começam com COMPILER_ são específicas do compilador: se estivermos a usar a construção completa (com o compilador do navegador embutido), podem ser configuradas em tempo de execução. No entanto, se usarmos uma configuração de construção, devem ser configuradas através da compilerOptions na configuração de construção (consulte as configurações de exemplo acima).

Referência de Funcionalidade

Tipos de Compatibilidade

  • ✔ Completamente compatível
  • ◐ Parcialmente compatível com advertências
  • ⨂ Incompatível (aviso apenas)
  • ⭘ Apenas compatível (sem aviso)

Incompatível

Devem ser corregidas antecipadamente ou provavelmente conduzirão à erros

IDTipoDescriçãoDocumentação
GLOBAL_MOUNT_CONTAINERa aplicação montada não substitui o elemento em que está montadaligação
CONFIG_DEVTOOLSas ferramentas de programação de produção agora são uma opção de tempo de execuçãoligação
COMPILER_V_IF_V_FOR_PRECEDENCEa precedência de v-if e v-for quando usada sobre o mesmo elemento mudouligação
COMPILER_V_IF_SAME_KEYos ramos de v-if não podem mais ter a mesma chaveligação
COMPILER_V_FOR_TEMPLATE_KEY_PLACEMENTa chave de <template v-for> agora deve ser colocada sobre o <template>ligação
COMPILER_SFC_FUNCTIONALo <template functional> não é mais suportado nos componentes de ficheiro únicoligação

Parcialmente Compatível com Advertências

IDTipoDescriçãoDocumentação
CONFIG_IGNORED_ELEMENTSa config.ignoredElements agora é config.compilerOptions.isCustomElement (apenas na construção do compilador do navegador). Se estivermos a usar configuração de construção, isCustomElement deve ser passado através da configuração da construção.ligação
COMPILER_INLINE_TEMPLATEinline-template removido (compatibilidade apenas suportada na construção do compilador do navegador)ligação
PROPS_DEFAULT_THISa fábrica padrão de propriedades não mais tem acesso ao this (no modo de compatibilidade, this não é uma instância verdadeira - apenas expõe as propriedades, $options e injeções)ligação
INSTANCE_DESTROYmétodo de instância $destroy removido (no modo de compatibilidade, apenas suportado na instância de raiz)
GLOBAL_PRIVATE_UTILVue.util é privado e não está mais disponível
CONFIG_PRODUCTION_TIPconfig.productionTip não é mais necessárialigação
CONFIG_SILENTconfig.silent removida

Apenas Compatível (sem aviso)

IDTipoDescriçãoDocumentação
TRANSITION_CLASSESas classes enter e leave de transição mudaramligação

Completamente Compatível

IDTipoDescriçãoDocumentação
GLOBAL_MOUNTnew Vue() -> createAppligação
GLOBAL_EXTENDVue.extend removida (use defineComponent ou a opção extends)ligação
GLOBAL_PROTOTYPEVue.prototype -> app.config.globalPropertiesligação
GLOBAL_SETVue.set removida (não é mais necessária)
GLOBAL_DELETEVue.delete removida (não é mais necessária)
GLOBAL_OBSERVABLEVue.observable removida (use reactive)ligação
CONFIG_KEY_CODESconfig.keyCodes removidaligação
CONFIG_WHITESPACEna Vue 3 espaço em branco está predefinida para "condense"
INSTANCE_SETvm.$set removida (não é mais necessária)
INSTANCE_DELETEvm.$delete removida (não é mais necessária)
INSTANCE_EVENT_EMITTERvm.$on, vm.$off, vm.$once removidaligação
INSTANCE_EVENT_HOOKSa instância não emite mais eventos hook:xligação
INSTANCE_CHILDRENvm.$children removidaligação
INSTANCE_LISTENERSvm.$listeners removidaligação
INSTANCE_SCOPED_SLOTSvm.$scopedSlots removida; vm.$slots agora expõe funçõesligação
INSTANCE_ATTRS_CLASS_STYLE$attrs agora inclui class e styleligação
OPTIONS_DATA_FNdata deve ser uma função em todos os casosligação
OPTIONS_DATA_MERGEdata de mistura ou extensão agora é combinada superficialmenteligação
OPTIONS_BEFORE_DESTROYbeforeDestroy -> beforeUnmount
OPTIONS_DESTROYEDdestroyed -> unmounted
WATCH_ARRAYa observação dum vetor não mais aciona sobre mutação se não for profundaligação
V_ON_KEYCODE_MODIFIERv-on não mais suporta modificadores de código de tecla ou keyCodeligação
CUSTOM_DIRos nomes de gatilho de diretiva personalizada mudaramligação
ATTR_FALSE_VALUENão mais remove o atributo se valor de vínculo for false booleanoligação
ATTR_ENUMERATED_COERCIONjá não existem atributos enumerados de caso especialligação
TRANSITION_GROUP_ROOT<transition-group> não mais desenha um elemento raiz por padrãoligação
COMPONENT_ASYNCa API do componente assíncrono mudou (agora exige defineAsyncComponent)ligação
COMPONENT_FUNCTIONALa API do componente funcional mudou (agora devem ser funções simples)ligação
COMPONENT_V_MODELv-model do componente re-trabalhadoligação
RENDER_FUNCTIONa API da função de interpretação mudouligação
FILTERSfiltros removidos (esta opção afeta apenas as APIs de tempo de execução)ligação
COMPILER_IS_ON_ELEMENTo uso de is agora está restrito apenas ao <component>ligação
COMPILER_V_BIND_SYNCv-bind.sync substituído por v-model com argumentosligação
COMPILER_V_BIND_PROPmodificador v-bind.prop removido
COMPILER_V_BIND_OBJECT_ORDERv-bind="object" agora é sensível a ordemligação
COMPILER_V_ON_NATIVEmodificador v-on.native removidoligação
COMPILER_V_FOR_REFref no v-for (suporte de compilador)
COMPILER_NATIVE_TEMPLATE<template> sem diretivas especiais agora desenha-se como elemento nativo
COMPILER_FILTERSfiltros (suporte de compilador)