Quickly transform your vue3 script to setup mode
快速将 vue3 script 转换为 setup 模式
origin code
<script lang="ts">
import { defineComponent, PropType, ref } from "vue"
import Header from "../components/Header.vue"
import Tab from "../components/Tab.vue"
import touchdir from "vtouchdir"
export default defineComponent({
name: 'App',
components: {
Header,
Tab,
},
directives: {
force: {},
touchdir,
},
props: {
items: Array as PropType<number[]>
},
emit: ["click"],
setup(props, { emit, attrs, slots: mySlots, expose }) {
const bar = ref(0)
expose({ bar })
emit("change");
return {
bar
}
}
})
</script>
<template>
<div>App</div>
</template>
npx tosetup /src/App.vue
transform code
<script lang="ts" setup>
import { ref, useAttrs, useSlots, } from "vue";
import Header from "../components/Header.vue";
import Tab from "../components/Tab.vue";
import vTouchdir from "vtouchdir";
const props = defineProps<{items?: number[]; }>();
const emit = defineEmits(["click", "change"]);
// custom directive
const vForce = {};
const attrs = useAttrs();
const mySlots = useSlots();
const bar = ref(0);
emit("change");
defineExpose({ bar });
</script>
<template>
<div>App</div>
</template>
npm install --save-dev vue3-script-to-setup
yarn add vue3-script-to-setup -D
pnpm add vue3-script-to-setup -D
npx tosetup [filePath]
example
npx tosetup /src/App.vue --propsNotOnlyTs
A new App.new.vue
file will be created in the same directory
将会在同目录下创建一个 App.new.vue
的新文件
options | english | chinese |
---|---|---|
--propsNotOnlyTs | props not using TypeScript-only Features |
props 不使用 TypeScript-only Features |
--notUseNewFile | instead of creating a new file, replace the contents of the file directly with the setup mode |
不创建一个新文件,而是将文件中的内容直接替换为 setup 模式 |
Create a tosetup.config.ts/tosetup.config.js
file in the root directory
在根目录下创建一个 tosetup.config.ts/tosetup.config.js
文件
import { defineConfig } from "vue3-script-to-setup";
export default defineConfig({
propsNotOnlyTs: true,
notUseNewFile: true,
path: {
"example/src": {
mode: "*",
excludes: [],
},
"example/src/components": {
mode: "*",
excludes: "Header.vue",
}, // Find the .vue file in the example/src directory, exclude Header.vue files
"example/src/views": ["404.vue"], // transform only the 404.vue in the example/src/views directory
},
});
npx tosetup
defaultOption
interface DefaultOption {
propsNotOnlyTs?: boolean;
notUseNewFile?: boolean;
path: {
[key: string]:
| string
| string[]
| {
mode: "*" | "**";
excludes: string | string[];
};
};
}
Unable to transform TypeScript-only Features
of defineEmits
, support only
无法将 defineEmits
转换为 TypeScript-only Features
模式,仅支持转换为数组
const emit = defineEmits(['change', 'delete'])
If expose
is not specified, the reference may fail in the outer layer.
如果在 script
代码下子组件没有通过 expose
暴露内部状态,转换为 setup
代码后父组件将引用失败。
// Child.vue
export default {
setup() {
function foo() {}
return { foo }
}
}
// Parent.vue
export default {
mounted() {
// Child.vue is script code, it`s work
// Child.vue is setup code, foo is undefined, need `expose({ foo })`
this.$refs.child.foo()
}
}
export default defineComponent({
name: 'App',
...optoons, // ❌
directives: {
...directives, // ❌
},
emit: ["click"],
// ...options ❌
setup(props, { emit, ...options }) {
const obj = reactive({ a, b, c })
options.expose() // ❌
const { ... } = toRefs(obj) // ✅
function handle() {} // ✅
return {
...toRefs(obj), // ❌
handle() {}, // ❌
}
}
})