Current status: experimental
This repository contains a collection of codemod scripts for use with JSCodeshift that help update Vue.js APIs.
Inspired by react-codemod.
npx vue-codemod <path> -t <transformation> --params [transformation params] [...additional options]
transformation
(required) - name of transformation, see available transformations below; or you can provide a path to a custom transformation module.path
(required) - files or directory to transform.--params
(optional) - additional transformation specific args.runTransformation(fileInfo, transformation, params)
jscodeshift
codemods to .vue
filesvue-cli-plugin-vue-next
vue-eslint-parser
for this)yarn playground
and visit http://localhost:3000The migration path (to be integrated in a new version of vue-migration-helper
):
vue3-essential
category (maybe a few exceptions like vue/no-deprecated-dollar-scopedslots-api
)eslint --fix
to fix all auto-fixable issues; if there are any remaining errors, fix them manuallyNote: even though most of the migration process can be automated, please be aware there might still be subtle differences between Vue 3 and Vue 2 runtime, and the codemods may have uncovered edge cases. Please double check before deploying your Vue 3 app into production.
Legend of annotations:
Mark | Description |
---|---|
🔴 | work not started |
🔵 | needs to or can be implemented in the compat runtime |
v-bind
's .sync
with a v-model
argument
vue/no-deprecated-v-bind-sync
ESLint rulekeyCode
support in v-on
vue/no-deprecated-v-on-number-modifiers
ESLint ruleconfig.keyCode
can be supported in the compat build. It is also detectable with the vue/no-deprecated-vue-config-keycodes
ESLint ruledata
object declaration
vue/no-shared-component-data
and the vue/no-deprecated-data-object-declaration
ESLint rulesvue/no-deprecated-slot-attribute
and vue/no-deprecated-slot-scope-attribute
this.$slots
, recommending this.$scopedSlots
as a replacement.$scopedSlots
occurrences with .$slots
(should pass the abovementioned ESLint checks before running this codemod) (implemented as scoped-slots-to-slots
)new-global-api
import Vue from 'vue'
-> import * as Vue from 'vue'
(implemented as vue-as-namespace-import
)Vue.extend
-> defineComponent
(implemented as define-component
)new Vue()
-> Vue.createApp()
(implemented as new-vue-to-create-app
)
new Vue({ el })
, new Vue().$mount
-> Vue.createApp().mount
new HelloWorld({ el })
, new HelloWorld().$mount
-> createApp(HelloWorld).mount
render(h)
-> render()
and import { h } from 'vue'
(implemented as remove-contextual-h-from-render
)Vue.config.productionTip
-> removed (implemented as remove-production-tip
)global-to-per-app-api
)
Vue.config
, Vue.use
, Vue.mixin
, Vue.component
, Vue.directive
, etc -> app.**
(It's possible to provide a runtime compatibility layer for single-root apps)Vue.prototype.customProperty
-> app.config.globalProperties.customProperty
Vue.config.ignoredElements
-> app.config.isCustomElement
Vue.*
, then transform the entry file to export the root instance, import it in other files and transform them with the imported root instance;optionMergeStrategies
behavior changevue/no-deprecated-functional-template
ESLint rule<template functional>
should be converted to normal SFCsh
h
calls to use the new VNode data format, since the mapping is pretty mechanical.bind
-> beforeMount
inserted
-> mounted
update
hook and insert a comment to note the user about the changecomponentUpdated
-> updated
unbind
-> unmounted
import ... from '@vue/composition-api'
-> import ... from 'vue'
(implemented as import-composition-api-from-vue
)inline-template
vue/no-deprecated-inline-template
ESLint rule<Teleport>
component
vue/no-reserved-component-names
ESLint rule<Teleport>
components to some other name like <TeleportComp>
.import
call to .vue
filescomponent
property being a dynamic import
call.resolve/reject
instead of returning promises. Manual upgrade will be required for such cases but they should be relatively rare.emits
component option
emits
options, so we need to scan and warn on such usagesemits
option, we can provide a codemod that automatically scans all instances of $emit
calls in a component and generate the emits
optionnew-global-api
and vuex-v4
Vue.use(Vuex)
& new Vue({ store })
-> app.use(store)
new Store()
-> createStore()
new-global-api
and vue-router-v4
Vue.use(VueRouter)
& new Vue({ router })
-> app.use(router)
new VueRouter()
-> createRouter()
mode: 'history', base: BASE_URL
etc. -> history: createWebHistory(BASE_URL)
etc.router-link
router-link
vue-class-component
7.x to 8
import { Component } from 'vue-class-component'
-> import { Options as Component } from 'vue-class-component'
import Vue from 'vue'
-> import { Vue } from 'vue-class-component'
(Need to avoid name collision if there's any reference to Vue
besides extends Vue
)Component.registerHooks
-> Vue.registerHooks
transition
as root
vue/require-toggle-inside-transition
ESLint rulemeta
fields from parent to child in RouteLocation
$listeners
and .native
usage@vue/composition-api
and the Vue 3 implementation are listed in the @vue/composition-api
READMEv-if
and v-for
have been flipped when using both on the same element.v-for
and ref
.$destroy
, $children
Note: there are just rough ideas. Amendments may or may not be proposed, depending on the implementation progress of this repo.
Vue.extend
can be supported in a compat runtime as an alias to defineComponent
v-model
API change
v-model
API because both the author and consumer of the components need to change their ways to use this API, according to the current RFC. So we might need a compatibility layer in the runtime.These features are only deprecated but still supported in the compatiblity builds. There will be runtime warnings and ESLint rules to detect their usages. Some of them can be automatically migrated with the help of codemods.
vue/no-deprecated-filter
ESLint rule<transition>
components with custom enter-class
or leave-class
:
enter-class
-> enter-from-class
leave-class
-> leave-from-class
.v-enter
and .v-leave
selector in the stylesheets to .v-enter-from
and .v-leave-from
enter-from-class="v-enter v-enter-from" leave-from-class="v-leave v-leave-from"
to these <transition>
components. Users can delete these attributes after they updated the corresponding stylesheetsvue/no-deprecated-events-api
ESLint ruleVue.config.ignoredElements
-> app.config.isCustomElement
<component>
tags with is
usage ->
<component is>
(for SFC templates).v-is
(for in-DOM templates).vue/no-deprecated-html-element-is
ESLint rule can be used to detect usage for is
usage on built-in HTML tags.set
and delete
instance or global methods will be supported only in IE compat builds.
remove-vue-set-and-delete
Aside from migrating Vue 2 apps to Vue 3, this repository also includes some generic transformations that can help clean up your codebase.
remove-trivial-root
{ render: () => h(App) }
and use App
as the direct rootdefine-component
--param.useCompositionAPI
: false
by default. When set to true
, it will import the defineComponent
helper from @vue/composition-api
instead of vue
defineComponent()
wrapper to .vue
file exports, and replaces Vue.extend
calls to defineComponent
See https://github.com/facebook/jscodeshift#transform-module
eslint --fix
.git diff --ignore-blank-lines | git apply --cached
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。