# Compilação de Migração
# Visão Geral
@vue/compat
(também conhecido como "a compilação de migração") é uma versão do Vue 3 que fornece um comportamento configurável compatível com Vue 2.
A compilação de migração é executada no modo Vue 2 por padrão - a maioria das APIs públicas se comportam exatamente como no Vue 2, com apenas algumas exceções. O uso de recursos que foram alterados ou obsoletos no Vue 3 emitirá avisos em tempo de execução. A compatibilidade de um recurso também pode ser ativada/desativada por componente.
# Casos de Uso Pretendidos
- Atualizando um aplicativo Vue 2 para Vue 3 (com limitações)
- Migrando uma biblioteca para suportar Vue 3
- Para desenvolvedores experientes do Vue 2 que ainda não experimentaram o Vue 3, a compilação de migração pode ser usada no lugar do Vue 3 para ajudar a aprender a diferença entre as versões.
# Limitações Conhecidas
Embora tenhamos nos esforçado para fazer a compilação de migração imitar o comportamento do Vue 2 o máximo possível, existem algumas limitações que podem impedir que seu aplicativo seja qualificado para atualização:
Dependências que dependem de APIs internas do Vue 2 ou comportamento não documentado. O caso mais comum é o uso de propriedades privadas em
VNodes
. Se o seu projeto depende de bibliotecas de componentes como Vuetify (opens new window), Quasar (opens new window) ou ElementUI (opens new window), é melhor esperar por suas versões compatíveis com Vue 3.Suporte ao Internet Explorer 11: O Vue 3 abandonou oficialmente o plano de suporte ao IE11 (opens new window). Se você ainda precisar dar suporte ao IE11 ou abaixo, terá que permanecer no Vue 2.
Renderização do lado do servidor: a compilação de migração pode ser usada para SSR, mas a migração de uma configuração de SSR personalizada é muito mais complexa. A ideia geral é substituir
vue-server-renderer
por@vue/server-renderer
(opens new window). O Vue 3 não fornece mais um renderizador de pacote (bundle) e é recomendado usar o Vue 3 SSR com Vite (opens new window). Se estiver usando Nuxt.js (opens new window), você pode testar Nuxt Bridge, uma camada de compatibilidade do Nuxt.js 2 para 3 (opens new window). Para projetos de produção complexos, provavelmente é melhor esperar pelo Nuxt 3 (atualmente em beta) (opens new window).
# Expectativas
Observe que a compilação de migração visa cobrir apenas as APIs e o comportamento do Vue 2 documentados publicamente. Se seu aplicativo não for executado na compilação de migração devido à dependência de comportamento não documentado, é improvável que ajustemos a compilação de migração para atender ao seu caso específico. Considere refatorar para remover a dependência do comportamento em questão.
Uma palavra de aviso: se seu aplicativo for grande e complexo, a migração provavelmente será um desafio mesmo com a compilação da migração. Se seu aplicativo infelizmente não for adequado para atualização, observe que estamos planejando fazer o backport da API de composição e alguns outros recursos do Vue 3 para a v2.7 (estimada para o terceiro trimestre de 2021).
Se você executar seu aplicativo na compilação de migração, pode enviá-lo para produção antes que a migração seja concluída. Embora haja uma pequena sobrecarga de desempenho/tamanho, ela não deve afetar visivelmente a UX de produção. Talvez você precise fazer isso quando tiver dependências que dependem do comportamento do Vue 2 e não podem ser atualizadas/substituídas.
A compilação de migração será fornecida a partir da v3.1 e continuará a ser publicada junto com a linha de lançamento da v3.2. Planejamos eventualmente parar de publicar a compilação de migração em uma versão menor futura (não antes do fim de 2021), portanto, você ainda deve tentar mudar para a compilação padrão antes disso.
# Fluxo de Trabalho da Atualização
O fluxo de trabalho a seguir percorre as etapas de migração de um aplicativo Vue 2 real (Vue HackerNews 2.0) para o Vue 3. Os commits completos podem ser encontrados aqui (opens new window). Observe que as etapas reais necessárias para o seu projeto podem variar, e essas etapas devem ser tratadas como orientação geral em vez de instruções estritas.
# Preparações
- Se você ainda estiver usando a sintaxe obsoleta de slot nomeado/com escopo (opens new window), atualize primeiro para a sintaxe mais recente (que já é suportada na 2.6).
# Instalação
Atualize as ferramentas, se aplicável.
- Se estiver usando uma configuração de webpack personalizada: Atualize o
vue-loader
para^16.0.0
. - Se estiver usando
vue-cli
: atualize para o@vue/cli-service
mais recente comvue upgrade
- (Alternativa) migrar para Vite (opens new window) + vite-plugin-vue2 (opens new window). [Commit de exemplo (opens new window)]
- Se estiver usando uma configuração de webpack personalizada: Atualize o
No
package.json
, atualizevue
para 3.1, instale@vue/compat
da mesma versão e substituavue-template-compiler
(se presente) por@vue/compiler-sfc
:"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" }
1
2
3
4
5
6
7
8
9
10Na configuração da compilação, crie o apelido
vue
para@vue/compat
e habilite o modo de compatibilidade através das opções do compilador Vue.Exemplos de Configurações
vue-cli
// 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 } } } }) } }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20Webpack puro
// webpack.config.js module.exports = { resolve: { alias: { vue: '@vue/compat' } }, module: { rules: [ { test: /\.vue$/, loader: 'vue-loader', options: { compilerOptions: { compatConfig: { MODE: 2 } } } } ] } }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23Vite
// vite.config.js export default { resolve: { alias: { vue: '@vue/compat' } }, plugins: [ vue({ template: { compilerOptions: { compatConfig: { MODE: 2 } } } }) ] }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19Se você estiver usando TypeScript, também precisará modificar a tipagem do
vue
para expor a exportação padrão (que não está mais presente no Vue 3) adicionando um arquivo*.d.ts
com o seguinte:declare module 'vue' { import { CompatVue } from '@vue/runtime-dom' const Vue: CompatVue export default Vue export * from '@vue/runtime-dom' }
1
2
3
4
5
6Neste ponto, seu aplicativo pode encontrar alguns erros/avisos em tempo de compilação (ex.: uso de filtros). Corrija-os primeiro. Se todos os avisos do compilador desaparecerem, você também poderá definir o compilador para o modo Vue 3.
Depois de corrigir os erros, o aplicativo poderá ser executado se não estiver sujeito às limitações mencionadas acima.
Você provavelmente verá MUITOS avisos na linha de comando e no console do navegador. Aqui estão algumas dicas gerais:
Você pode filtrar por avisos específicos no console do navegador. É uma boa ideia usar o filtro e focar na correção de um item de cada vez. Você também pode usar filtros negados como
-GLOBAL_MOUNT
.Você pode suprimir itens obsoletos específicos por meio de configuração de compatibilidade.
Alguns avisos podem ser causados por uma dependência que você usa (ex.:
vue-router
). Você pode verificar isso no rastro do componente com aviso ou rastro da pilha de erros (expandido ao clicar). Concentre-se primeiro em corrigir os avisos originados de seu próprio código-fonte.Se você estiver usando
vue-router
, observe que<transition>
e<keep-alive>
não funcionarão com<router-view>
até que você atualize paravue-router
v4.
Atualize nomes de classe em
<transition>
. Este é o único recurso que não possui um aviso de tempo de execução. Você pode fazer uma pesquisa em todo o projeto para nomes de classes CSS.*-enter
e.*-leave
.Atualize a entrada do aplicativo para usar a nova API de montagem global.
Atualize o
vue-router
para v4 (opens new window). Se você também usavuex-router-sync
, você pode substituí-lo por um store getter.Após a atualização, para usar
<transition>
e<keep-alive>
com<router-view>
requer o uso da nova sintaxe baseada em slot com escopo (opens new window).Retire os avisos individuais. Observe que alguns recursos têm comportamento conflitante entre o Vue 2 e o Vue 3 - por exemplo, a API da função de renderização ou o componente funcional vs. a alteração de componente assíncrona. Para migrar para a API do Vue 3 sem afetar o restante do aplicativo, você pode optar pelo comportamento do Vue 3 por componente com a opção
compatConfig
.Quando todos os avisos forem corrigidos, você poderá remover a compilação de migração e alternar para o Vue 3 propriamente dito. Observe que você pode não conseguir fazer isso se ainda tiver dependências que dependem do comportamento do Vue 2.
# Configuração de Compatibilidade
# Configuração Global
Os recursos da compatibilidade podem ser desativados individualmente:
import { configureCompat } from 'vue'
// desabilita a compatibilidade para certos recursos
configureCompat({
FEATURE_ID_A: false,
FEATURE_ID_B: false
})
2
3
4
5
6
7
Alternativamente, todo o aplicativo pode padronizar o comportamento do Vue 3, com apenas alguns recursos de compatibilidade ativados:
import { configureCompat } from 'vue'
// padroniza tudo para o comportamento do Vue 3 e habilita compatibilidade apenas
// para certos recursos
configureCompat({
MODE: 3,
FEATURE_ID_A: true,
FEATURE_ID_B: true
})
2
3
4
5
6
7
8
9
# Configuração por Componente
Um componente pode usar a opção compatConfig
, que espera as mesmas opções que o método global configureCompat
:
export default {
compatConfig: {
MODE: 3, // ativa o comportamento do Vue 3 apenas para este componente
FEATURE_ID_A: true // recursos também podem ser alternados no nível do componente
}
// ...
}
2
3
4
5
6
7
# Configuração Específica de Compilador
Os recursos que começam com COMPILER_
são específicos do compilador: se você estiver usando a compilação completa (com compilador in-browser), eles podem ser configurados em tempo de execução. No entanto, se estiver usando um ambiente de compilação, eles devem ser configurados por meio de compilerOptions
na configuração de compilação (veja as configurações de exemplo acima).
# Referência de Recurso
# Tipos de Compatibilidade
- ✔ Totalmente compatível
- ◐ Parcialmente compatível com ressalvas
- ⨂ Incompatível (somente aviso)
- ⭘ Somente modo de compatibilidade (sem aviso)
# Incompatível
Deve ser corrigido antecipadamente ou provavelmente levará a erros
ID | Tipo | Descrição | Documentação |
---|---|---|---|
GLOBAL_MOUNT_CONTAINER | ⨂ | O aplicativo montado não substitui o elemento no qual está montado | link |
CONFIG_DEVTOOLS | ⨂ | devtools de produção agora é um sinalizador em tempo de compilação | link (opens new window) |
COMPILER_V_IF_V_FOR_PRECEDENCE | ⨂ | A precedência v-if e v-for quando usada no mesmo elemento foi alterada | link |
COMPILER_V_IF_SAME_KEY | ⨂ | Ramos v-if não podem mais ter a mesma chave | link |
COMPILER_V_FOR_TEMPLATE_KEY_PLACEMENT | ⨂ | A chave de <template v-for> agora deve ser colocada no <template> | link |
COMPILER_SFC_FUNCTIONAL | ⨂ | <template functional> não é mais suportado em SFCs | link |
# Parcialmente Compatível com Ressalvas
ID | Tipo | Descrição | Documentação |
---|---|---|---|
CONFIG_IGNORED_ELEMENTS | ◐ | config.ignoredElements agora é config.compilerOptions.isCustomElement (somente na versão do compilador in-browser). Se estiver usando ambiente de compilação, isCustomElement deve ser passado na configuração da compilação. | link |
COMPILER_INLINE_TEMPLATE | ◐ | inline-template removido (compatibilidade suportada apenas na compilação in-browser) | link |
PROPS_DEFAULT_THIS | ◐ | Função-fábrica padrão de props não tem mais acesso a this (no modo de compatibilidade, this não é uma instância real - apenas expõe props, $options e injeções) | link |
INSTANCE_DESTROY | ◐ | Método de instância $destroy removido (no modo de compatibilidade, suportado apenas na instância raiz) | |
GLOBAL_PRIVATE_UTIL | ◐ | Vue.util é privado e não está mais disponível | |
CONFIG_PRODUCTION_TIP | ◐ | config.productionTip não é mais necessário | link |
CONFIG_SILENT | ◐ | config.silent removido |
# Somente Modo de Compatibilidade (sem aviso)
ID | Tipo | Descrição | Documentação |
---|---|---|---|
TRANSITION_CLASSES | ⭘ | Classes de entrada/saída da transição alteradas | link |
# Totalmente Compatível
ID | Tipo | Descrição | Documentação |
---|---|---|---|
GLOBAL_MOUNT | ✔ | new Vue() -> createApp | link |
GLOBAL_EXTEND | ✔ | Vue.extend removido (use a opção defineComponent ou extends ) | link |
GLOBAL_PROTOTYPE | ✔ | Vue.prototype -> app.config.globalProperties | link |
GLOBAL_SET | ✔ | Vue.set removido (não é mais necessário) | |
GLOBAL_DELETE | ✔ | Vue.delete removido (não é mais necessário) | |
GLOBAL_OBSERVÁVEL | ✔ | Vue.observable removido (use reactive ) | link |
CONFIG_KEY_CODES | ✔ | config.keyCodes removidos | link |
CONFIG_WHITESPACE | ✔ | No Vue 3, o espaço em branco padrão é "condense" | |
INSTANCE_SET | ✔ | vm.$set removido (não é mais necessário) | |
INSTANCE_DELETE | ✔ | vm.$delete removido (não é mais necessário) | |
INSTANCE_EVENT_EMITTER | ✔ | vm.$on , vm.$off , vm.$once removido | link |
INSTANCE_EVENT_HOOKS | ✔ | A instância não emite mais eventos hook:x | link |
INSTANCE_CHILDREN | ✔ | vm.$children removido | link |
INSTANCE_LISTENERS | ✔ | vm.$listeners removido | link |
INSTANCE_SCOPED_SLOTS | ✔ | vm.$scopedSlots removido; vm.$slots agora expõe funções | link |
INSTANCE_ATTRS_CLASS_STYLE | ✔ | $attrs agora inclui class e style | link |
OPTIONS_DATA_FN | ✔ | data deve ser uma função em todos os casos | link |
OPTIONS_DATA_MERGE | ✔ | data do mixin ou extensão agora é mesclado superficialmente | link |
OPTIONS_BEFORE_DESTROY | ✔ | beforeDestroy -> beforeUnmount | |
OPTIONS_DESTROYED | ✔ | destroyed -> unmounted | |
WATCH_ARRAY | ✔ | Observar um array não dispara mais na mutação, a menos que seja profundo | link |
V_FOR_REF | ✔ | ref dentro de v-for não registra mais array de refs | link |
V_ON_KEYCODE_MODIFIER | ✔ | v-on não suporta mais modificadores keyCode | link |
CUSTOM_DIR | ✔ | Nomes de gatilhos de diretiva personalizada alterados | link |
ATTR_FALSE_VALUE | ✔ | Não remove mais o atributo se o valor do vínculo for booleano false | link |
ATTR_ENUMERATED_COERCION | ✔ | Caso especial de atributos enumerados não funciona mais | link |
TRANSITION_GROUP_ROOT | ✔ | <transition-group> não renderiza mais um elemento raiz por padrão | link |
COMPONENT_ASYNC | ✔ | API do componente assíncrono alterada (agora requer defineAsyncComponent ) | link |
COMPONENT_FUNCTIONAL | ✔ | API de componente funcional alterada (agora devem ser funções simples) | link |
COMPONENT_V_MODEL | ✔ | Componente v-model retrabalhado | link |
RENDER_FUNCTION | ✔ | API da função de renderização alterada | link |
FILTROS | ✔ | Filtros removidos (afeta apenas APIs de filtro em tempo de execução) | link |
COMPILER_IS_ON_ELEMENT | ✔ | O uso de is agora está restrito apenas a <component> | link |
COMPILER_V_BIND_SYNC | ✔ | v-bind.sync substituído por v-model com argumentos | link |
COMPILER_V_BIND_PROP | ✔ | Modificador v-bind.prop removido | |
COMPILER_V_BIND_OBJECT_ORDER | ✔ | v-bind="object" agora é sensível à ordem | link |
COMPILER_V_ON_NATIVE | ✔ | Modificador v-on.native removido | link |
COMPILER_V_FOR_REF | ✔ | ref em v-for (suporte no compilador) | |
COMPILER_NATIVE_TEMPLATE | ✔ | <template> sem diretivas especiais agora renderiza como elemento nativo | |
COMPILER_FILTERS | ✔ | Filtros (suporte no compilador) |