This project is based on the fork of https://github.com/originjs/vue-codemod and was modified and further developed by Deutsche Bahn Fernverkehr AG.
Cloned from https://github.com/originjs/vue-codemod
vue-class-style-codemod
is a Vue 2 to Vue 3 migration tool based on vue-codemod
adding support to convert Vue Class-based components defined with vue-class-component
and vue-property-decorator
to the script setup
component syntax.
Install all dependencies and make vue-class-style-codemod available globally
npm run setup
(Please use only npm and not yarn)
Transformation of projects and individual files with the help of vue-class-style-codemod.
vue-class-style-codemod -t/-a [transformation params]
or
npx vue-class-style-codemod -t/-a [transformation params]
Please note that the transformation completely replaces the old file
Having already the rule vue-class-component-v8
available in vue-class-style-codemod
, this projects adds the two rules property-decorator
and define-component-to-script-setup
.
The rule converts most decorators of vue-property-decorator
. The following table shows some exemplary conversions.
import { Vue, Component } from 'vue-property-decorator';
@Component
export default class CreatedInput extends Vue {
public created(): void {
this.groupControls.register(this.id);
}
public beforeCreated(): void {
this.groupControls.register(this.id);
}
}
groupControls.register(id);
groupControls.register(id);
@Emit('reset')
resetCount() {
this.count = 0;
}
const emit = defineEmits<{
(e: 'reset'): void
}>();
function resetCount() {
count = 0;
emit("reset");
}
@Inject() readonly foo!: string
@Inject('bar') readonly bar!: string
@Inject({ from: 'optional', default: 'default' }) readonly optional!: string
@Inject(symbol) readonly baz!: string
@Inject({ from: 'optional', default: () => 'Hello World' }) readonly optional!: string
const foo: string = inject('foo');
const bar: string = inject('bar');
const optional: string = inject('optional', 'default');
const baz: string = inject(symbol);
const optional: string = inject('optional', () => 'Hello World');
await this.$nextTick();
await nextTick();
public get cancelButtonText(): string {
// Cancel button text comment
return this.$gettext('Cancel');
}
const cancelButtonText = computed<string>(() => {
// Cancel button translation comment
return $gettext('Cancel');
});
@Prop(Number) readonly propA: number | undefined
@Prop({ default: 'default value' }) readonly propB: string
@Prop({ type: String }) readonly propC!: string
@Prop([String, Boolean]) readonly propD: string | boolean | undefined
@Prop(Number) readonly propE!: number | undefined
@Prop([String, Boolean]) readonly propF!: string | boolean | undefined
const props = withDefaults(defineProps<{
propA?: number | undefined,
propB?: string,
propC: string,
propD?: string | boolean | undefined,
propE: number | undefined,
propF: string | boolean | undefined
}>(), {
propB: 'default value'
});
@Provide() foo = 'foo';
@Provide('bar') baz = 'bar';
const foo = reactive('foo');
provide('foo', foo);
const baz = reactive('bar');
provide('bar', baz);
@Ref() readonly anotherComponent!: AnotherComponent
@Ref('aButton') readonly button!: HTMLButtonElement
const anotherComponent = ref<AnotherComponent>();
const aButton = ref<HTMLButtonElement>();
export class AnyComponent extends Vue {
private static readonly noScrollClass: string = 'util__noscroll-xs';
public static addNoScrollXs(): void {
document.documentElement.classList.add(AnyComponent.noScrollClass);
}
}
const noScrollClass: string = 'util__noscroll-xs';
function addNoScrollXs(): void {
document.documentElement.classList.add(noScrollClass);
}
methodA() {
return this.$route.params.id
}
methodB() {
return this.$router.back()
}
const router = useRouter();
const route = useRoute();
function methodA() {
return route.params.id;
}
function methodB() {
return router.back();
}
methodC() {
return this.$store.commit('increment')
}
function methodC() {
return store.commit('increment');
}
@Watch('person', { immediate: true, deep: true })
onPersonChanged(val: Person, oldVal: Person) {}
function onPersonChanged(val: Person, oldVal: Person) {}
watch(person, onPersonChanged);
This rule converts the defineComponent
syntax to the script setup
syntax.
<script lang="ts">
import { defineComponent } from 'vue';
export default defineComponent({
name: 'test',
components: {
testComponent
},
emit: ['change','input'],
props: {
counter: {
required: false,
type: Boolean
},
},
setup(props, ctx) {
ctx.emit('changeValue');
return {
test,
title: computed(() => 'Hello World'),
}
},
methods: {
doIt() {
console.log(`Hello ${this.name}`);
},
},
});
</script>
<script setup lang="ts">
const emit = defineEmits<{
(e: 'change'): void,
(e: 'input'): void
}>();
const props = defineProps<{
counter?: Boolean
}>();
const title = computed(() => 'Hello World');
emit('changeValue');
function doIt() {
console.log(`Hello ${name}`);
}
</script>
License Information:
The copyright of the original repo licensed under the copyright of vuejs and the changes under the copyright of DB Fernverkehr. All code and modifications are licensed under the MIT license.