create-component-template-cli 1.0.0 → 1.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.changeset/config.json +1 -1
- package/AGENTS.md +114 -0
- package/CHANGELOG.md +13 -1
- package/CLAUDE.md +20 -8
- package/README.md +49 -21
- package/bin/cli.mjs +38 -29
- package/docs/2026-05-11T10-04-44-/344/270/211/345/245/227/346/250/241/346/235/277/351/207/215/346/236/204/2026-05-11T10-04-44-/344/270/211/345/245/227/346/250/241/346/235/277/351/207/215/346/236/204-/346/200/235/350/267/257/346/226/207/346/241/243.md +167 -0
- package/docs/2026-05-11T10-04-44-/344/270/211/345/245/227/346/250/241/346/235/277/351/207/215/346/236/204/2026-05-11T10-04-44-/344/270/211/345/245/227/346/250/241/346/235/277/351/207/215/346/236/204-/346/200/273/347/273/223/346/226/207/346/241/243.md +80 -0
- package/docs/2026-05-11T10-04-44-/344/270/211/345/245/227/346/250/241/346/235/277/351/207/215/346/236/204/2026-05-11T10-04-44-/344/270/211/345/245/227/346/250/241/346/235/277/351/207/215/346/236/204-/350/256/276/350/256/241/346/226/271/346/241/210.md +477 -0
- package/docs/2026-05-11T12-35-00-npx/346/211/247/350/241/214/345/205/245/345/217/243/344/277/256/345/244/215/2026-05-11T12-35-00-npx/346/211/247/350/241/214/345/205/245/345/217/243/344/277/256/345/244/215-/345/256/236/346/226/275/346/226/271/346/241/210.md +66 -0
- package/docs/2026-05-11T12-35-00-npx/346/211/247/350/241/214/345/205/245/345/217/243/344/277/256/345/244/215/2026-05-11T12-35-00-npx/346/211/247/350/241/214/345/205/245/345/217/243/344/277/256/345/244/215-/346/200/235/350/267/257/346/226/207/346/241/243.md +69 -0
- package/docs/2026-05-11T12-35-00-npx/346/211/247/350/241/214/345/205/245/345/217/243/344/277/256/345/244/215/2026-05-11T12-35-00-npx/346/211/247/350/241/214/345/205/245/345/217/243/344/277/256/345/244/215-/346/200/273/347/273/223/346/226/207/346/241/243.md +27 -0
- package/package.json +4 -3
- package/plop-templates/general/data.ts.hbs +16 -0
- package/plop-templates/general/hook.ts.hbs +11 -0
- package/plop-templates/general/index.normal.vue.hbs +28 -0
- package/plop-templates/general/index.scss.hbs +5 -0
- package/plop-templates/general/index.setup.vue.hbs +20 -0
- package/plop-templates/{index.ts.hbs → general/index.ts.hbs} +2 -1
- package/plop-templates/general/typing.ts.hbs +13 -0
- package/plop-templates/multiple-pick/data.ts.hbs +20 -0
- package/plop-templates/multiple-pick/hook.ts.hbs +11 -0
- package/plop-templates/multiple-pick/index.normal.vue.hbs +37 -0
- package/plop-templates/multiple-pick/index.scss.hbs +5 -0
- package/plop-templates/multiple-pick/index.setup.vue.hbs +22 -0
- package/plop-templates/multiple-pick/index.ts.hbs +4 -0
- package/plop-templates/multiple-pick/typing.ts.hbs +13 -0
- package/plop-templates/single-pick/data.ts.hbs +16 -0
- package/plop-templates/single-pick/hook.ts.hbs +11 -0
- package/plop-templates/single-pick/index.normal.vue.hbs +36 -0
- package/plop-templates/single-pick/index.scss.hbs +5 -0
- package/plop-templates/single-pick/index.setup.vue.hbs +23 -0
- package/plop-templates/single-pick/index.ts.hbs +4 -0
- package/plop-templates/single-pick/typing.ts.hbs +13 -0
- package/plopfile.mjs +68 -59
- package/src/generate.mjs +101 -31
- package/tmp-output/GeneralNormalDemo/index.ts +4 -0
- package/tmp-output/GeneralNormalDemo/src/data.ts +16 -0
- package/tmp-output/GeneralNormalDemo/src/hook.ts +11 -0
- package/tmp-output/GeneralNormalDemo/src/index.scss +5 -0
- package/tmp-output/GeneralNormalDemo/src/index.vue +28 -0
- package/tmp-output/GeneralNormalDemo/src/typing.ts +13 -0
- package/tmp-output/GeneralSetupDemo/index.ts +4 -0
- package/tmp-output/GeneralSetupDemo/src/data.ts +16 -0
- package/tmp-output/GeneralSetupDemo/src/hook.ts +11 -0
- package/tmp-output/GeneralSetupDemo/src/index.scss +5 -0
- package/tmp-output/GeneralSetupDemo/src/index.vue +20 -0
- package/tmp-output/GeneralSetupDemo/src/typing.ts +13 -0
- package/tmp-output/MultiplePickNormalDemo/index.ts +4 -0
- package/tmp-output/MultiplePickNormalDemo/src/data.ts +20 -0
- package/tmp-output/MultiplePickNormalDemo/src/hook.ts +11 -0
- package/tmp-output/MultiplePickNormalDemo/src/index.scss +5 -0
- package/tmp-output/MultiplePickNormalDemo/src/index.vue +37 -0
- package/tmp-output/MultiplePickNormalDemo/src/typing.ts +13 -0
- package/tmp-output/MultiplePickSetupDemo/index.ts +4 -0
- package/tmp-output/MultiplePickSetupDemo/src/data.ts +20 -0
- package/tmp-output/MultiplePickSetupDemo/src/hook.ts +11 -0
- package/tmp-output/MultiplePickSetupDemo/src/index.scss +5 -0
- package/tmp-output/MultiplePickSetupDemo/src/index.vue +22 -0
- package/tmp-output/MultiplePickSetupDemo/src/typing.ts +13 -0
- package/tmp-output/SinglePickNormalDemo/index.ts +4 -0
- package/tmp-output/SinglePickNormalDemo/src/data.ts +16 -0
- package/tmp-output/SinglePickNormalDemo/src/hook.ts +11 -0
- package/tmp-output/SinglePickNormalDemo/src/index.scss +5 -0
- package/tmp-output/SinglePickNormalDemo/src/index.vue +36 -0
- package/tmp-output/SinglePickNormalDemo/src/typing.ts +13 -0
- package/tmp-output/SinglePickSetupDemo/index.ts +4 -0
- package/tmp-output/SinglePickSetupDemo/src/data.ts +16 -0
- package/tmp-output/SinglePickSetupDemo/src/hook.ts +11 -0
- package/tmp-output/SinglePickSetupDemo/src/index.scss +5 -0
- package/tmp-output/SinglePickSetupDemo/src/index.vue +23 -0
- package/tmp-output/SinglePickSetupDemo/src/typing.ts +13 -0
- package/plop-templates/data.ts.hbs +0 -7
- package/plop-templates/hook.ts.hbs +0 -29
- package/plop-templates/index.scss.hbs +0 -1
- package/plop-templates/index.setup.vue.hbs +0 -25
- package/plop-templates/index.vue.hbs +0 -38
- package/plop-templates/typing.ts.hbs +0 -14
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div class="{{ class }}"></div>
|
|
3
|
+
</template>
|
|
4
|
+
|
|
5
|
+
<script lang="ts">
|
|
6
|
+
import { defineComponent, PropType } from 'vue'
|
|
7
|
+
import { {{ componentName }}Props } from './typing'
|
|
8
|
+
import { use{{ componentName }} } from './hook'
|
|
9
|
+
|
|
10
|
+
export default defineComponent({
|
|
11
|
+
name: '{{ componentName }}',
|
|
12
|
+
props: {
|
|
13
|
+
user: {
|
|
14
|
+
type: Object as PropType<{{ componentName }}Props['user']>,
|
|
15
|
+
required: false,
|
|
16
|
+
},
|
|
17
|
+
},
|
|
18
|
+
setup(props) {
|
|
19
|
+
const {} = use{{ componentName }}(props as {{ componentName }}Props)
|
|
20
|
+
|
|
21
|
+
return {}
|
|
22
|
+
},
|
|
23
|
+
})
|
|
24
|
+
</script>
|
|
25
|
+
|
|
26
|
+
<style lang="scss" scoped>
|
|
27
|
+
@import './index.scss';
|
|
28
|
+
</style>
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div class="{{ class }}"></div>
|
|
3
|
+
</template>
|
|
4
|
+
|
|
5
|
+
<script setup lang="ts">
|
|
6
|
+
import { {{ componentName }}Props } from './typing'
|
|
7
|
+
import { use{{ componentName }} } from './hook'
|
|
8
|
+
|
|
9
|
+
defineOptions({
|
|
10
|
+
name: '{{ componentName }}',
|
|
11
|
+
})
|
|
12
|
+
|
|
13
|
+
const props = defineProps<{{ componentName }}Props>()
|
|
14
|
+
|
|
15
|
+
const {} = use{{ componentName }}(props)
|
|
16
|
+
</script>
|
|
17
|
+
|
|
18
|
+
<style lang="scss" scoped>
|
|
19
|
+
@import './index.scss';
|
|
20
|
+
</style>
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { DataType } from './typing'
|
|
2
|
+
|
|
3
|
+
const data: Array<DataType> = [
|
|
4
|
+
{
|
|
5
|
+
label: '多选项1',
|
|
6
|
+
value: 'multiple-1',
|
|
7
|
+
},
|
|
8
|
+
{
|
|
9
|
+
label: '多选项2',
|
|
10
|
+
value: 'multiple-2',
|
|
11
|
+
},
|
|
12
|
+
{
|
|
13
|
+
label: '多选项3',
|
|
14
|
+
value: 'multiple-3',
|
|
15
|
+
},
|
|
16
|
+
]
|
|
17
|
+
|
|
18
|
+
export {
|
|
19
|
+
data,
|
|
20
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { ref } from 'vue'
|
|
2
|
+
import { data } from './data'
|
|
3
|
+
import type { {{ componentName }}Props } from './typing'
|
|
4
|
+
|
|
5
|
+
export const use{{ componentName }} = (props: {{ componentName }}Props) => {
|
|
6
|
+
const selectedValues = ref(props.modelValue ?? data.slice(0, 2).map((item) => item.value))
|
|
7
|
+
|
|
8
|
+
return {
|
|
9
|
+
selectedValues,
|
|
10
|
+
}
|
|
11
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div class="{{ class }}">
|
|
3
|
+
<div v-for="item in selectedValues" :key="item">{{ item }}</div>
|
|
4
|
+
</div>
|
|
5
|
+
</template>
|
|
6
|
+
|
|
7
|
+
<script lang="ts">
|
|
8
|
+
import { defineComponent, PropType } from 'vue'
|
|
9
|
+
import { {{ componentName }}Props } from './typing'
|
|
10
|
+
import { use{{ componentName }} } from './hook'
|
|
11
|
+
|
|
12
|
+
export default defineComponent({
|
|
13
|
+
name: '{{ componentName }}',
|
|
14
|
+
props: {
|
|
15
|
+
user: {
|
|
16
|
+
type: Object as PropType<{{ componentName }}Props['user']>,
|
|
17
|
+
required: false,
|
|
18
|
+
},
|
|
19
|
+
modelValue: {
|
|
20
|
+
type: Array as PropType<{{ componentName }}Props['modelValue']>,
|
|
21
|
+
required: false,
|
|
22
|
+
default: () => [],
|
|
23
|
+
},
|
|
24
|
+
},
|
|
25
|
+
setup(props) {
|
|
26
|
+
const { selectedValues } = use{{ componentName }}(props as {{ componentName }}Props)
|
|
27
|
+
|
|
28
|
+
return {
|
|
29
|
+
selectedValues,
|
|
30
|
+
}
|
|
31
|
+
},
|
|
32
|
+
})
|
|
33
|
+
</script>
|
|
34
|
+
|
|
35
|
+
<style lang="scss" scoped>
|
|
36
|
+
@import './index.scss';
|
|
37
|
+
</style>
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div class="{{ class }}">
|
|
3
|
+
<div v-for="item in selectedValues" :key="item">{{ item }}</div>
|
|
4
|
+
</div>
|
|
5
|
+
</template>
|
|
6
|
+
|
|
7
|
+
<script setup lang="ts">
|
|
8
|
+
import { {{ componentName }}Props } from './typing'
|
|
9
|
+
import { use{{ componentName }} } from './hook'
|
|
10
|
+
|
|
11
|
+
defineOptions({
|
|
12
|
+
name: '{{ componentName }}',
|
|
13
|
+
})
|
|
14
|
+
|
|
15
|
+
const props = defineProps<{{ componentName }}Props>()
|
|
16
|
+
|
|
17
|
+
const { selectedValues } = use{{ componentName }}(props)
|
|
18
|
+
</script>
|
|
19
|
+
|
|
20
|
+
<style lang="scss" scoped>
|
|
21
|
+
@import './index.scss';
|
|
22
|
+
</style>
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { ref } from 'vue'
|
|
2
|
+
import { data } from './data'
|
|
3
|
+
import type { {{ componentName }}Props } from './typing'
|
|
4
|
+
|
|
5
|
+
export const use{{ componentName }} = (props: {{ componentName }}Props) => {
|
|
6
|
+
const selectedValue = ref(props.modelValue ?? data[0]?.value ?? '')
|
|
7
|
+
|
|
8
|
+
return {
|
|
9
|
+
selectedValue,
|
|
10
|
+
}
|
|
11
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div class="{{ class }}">
|
|
3
|
+
<SinglePickButtonGroup />
|
|
4
|
+
</div>
|
|
5
|
+
</template>
|
|
6
|
+
|
|
7
|
+
<script lang="ts">
|
|
8
|
+
import { defineComponent, PropType } from 'vue'
|
|
9
|
+
import SinglePickButtonGroup from '@/components/common/SinglePickButtonGroup'
|
|
10
|
+
import { {{ componentName }}Props } from './typing'
|
|
11
|
+
import { use{{ componentName }} } from './hook'
|
|
12
|
+
|
|
13
|
+
export default defineComponent({
|
|
14
|
+
name: '{{ componentName }}',
|
|
15
|
+
components: {
|
|
16
|
+
SinglePickButtonGroup,
|
|
17
|
+
},
|
|
18
|
+
props: {
|
|
19
|
+
user: {
|
|
20
|
+
type: Object as PropType<{{ componentName }}Props['user']>,
|
|
21
|
+
required: false,
|
|
22
|
+
},
|
|
23
|
+
},
|
|
24
|
+
setup(props) {
|
|
25
|
+
const { selectedValue } = use{{ componentName }}(props as {{ componentName }}Props)
|
|
26
|
+
|
|
27
|
+
return {
|
|
28
|
+
selectedValue,
|
|
29
|
+
}
|
|
30
|
+
},
|
|
31
|
+
})
|
|
32
|
+
</script>
|
|
33
|
+
|
|
34
|
+
<style lang="scss" scoped>
|
|
35
|
+
@import './index.scss';
|
|
36
|
+
</style>
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div class="{{ class }}">
|
|
3
|
+
<SinglePickButtonGroup />
|
|
4
|
+
</div>
|
|
5
|
+
</template>
|
|
6
|
+
|
|
7
|
+
<script setup lang="ts">
|
|
8
|
+
import SinglePickButtonGroup from '@/components/common/SinglePickButtonGroup'
|
|
9
|
+
import { {{ componentName }}Props } from './typing'
|
|
10
|
+
import { use{{ componentName }} } from './hook'
|
|
11
|
+
|
|
12
|
+
defineOptions({
|
|
13
|
+
name: '{{ componentName }}',
|
|
14
|
+
})
|
|
15
|
+
|
|
16
|
+
const props = defineProps<{{ componentName }}Props>()
|
|
17
|
+
|
|
18
|
+
const { selectedValue } = use{{ componentName }}(props)
|
|
19
|
+
</script>
|
|
20
|
+
|
|
21
|
+
<style lang="scss" scoped>
|
|
22
|
+
@import './index.scss';
|
|
23
|
+
</style>
|
package/plopfile.mjs
CHANGED
|
@@ -5,85 +5,110 @@ import fs from 'node:fs';
|
|
|
5
5
|
|
|
6
6
|
const __filename = fileURLToPath(import.meta.url);
|
|
7
7
|
const __dirname = path.dirname(__filename);
|
|
8
|
-
|
|
8
|
+
|
|
9
|
+
const BUSINESS_TEMPLATE_CHOICES = [
|
|
10
|
+
{ name: '通用模板', value: 'general' },
|
|
11
|
+
{ name: '产品组单选模板', value: 'single-pick' },
|
|
12
|
+
{ name: '产品组多选模板', value: 'multiple-pick' },
|
|
13
|
+
];
|
|
14
|
+
|
|
15
|
+
const VUE_TEMPLATE_STYLE_CHOICES = [
|
|
16
|
+
{ name: 'script setup 风格', value: 'setup' },
|
|
17
|
+
{ name: 'defineComponent 风格', value: 'normal' },
|
|
18
|
+
];
|
|
19
|
+
|
|
20
|
+
const BUSINESS_TEMPLATE_DIR_MAP = {
|
|
21
|
+
general: 'general',
|
|
22
|
+
'single-pick': 'single-pick',
|
|
23
|
+
'multiple-pick': 'multiple-pick',
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
const VUE_TEMPLATE_FILE_MAP = {
|
|
27
|
+
setup: 'index.setup.vue.hbs',
|
|
28
|
+
normal: 'index.normal.vue.hbs',
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
const TEMPLATE_FILES = [
|
|
32
|
+
{ file: 'index.scss', output: 'src/index.scss', templateFile: 'index.scss.hbs', getData: (componentName, className) => ({ class: className, componentName }) },
|
|
33
|
+
{ file: 'index.vue', output: 'src/index.vue', type: 'vue-entry', getData: (componentName, className) => ({ class: className, componentName }) },
|
|
34
|
+
{ file: 'typing.ts', output: 'src/typing.ts', templateFile: 'typing.ts.hbs', getData: (componentName) => ({ interfaceName: componentName, componentName }) },
|
|
35
|
+
{ file: 'hook.ts', output: 'src/hook.ts', templateFile: 'hook.ts.hbs', getData: (componentName) => ({ componentName }) },
|
|
36
|
+
{ file: 'data.ts', output: 'src/data.ts', templateFile: 'data.ts.hbs', getData: (componentName) => ({ componentName }) },
|
|
37
|
+
{ file: 'index.ts', output: 'index.ts', templateFile: 'index.ts.hbs', getData: (componentName) => ({ componentName }) },
|
|
38
|
+
];
|
|
9
39
|
|
|
10
40
|
export default (plop) => {
|
|
11
41
|
plop.setGenerator('create-component-template', {
|
|
12
|
-
description: '
|
|
42
|
+
description: '----组件模板生成器---',
|
|
13
43
|
prompts: [
|
|
14
44
|
{
|
|
15
45
|
type: 'input',
|
|
16
46
|
name: 'rootPath',
|
|
17
47
|
message: '请输入组件生成路径:',
|
|
18
|
-
|
|
19
|
-
default: (data) => data.rootPath || `src/components/platform`,
|
|
48
|
+
default: (data) => data.rootPath || 'src/components/platform',
|
|
20
49
|
},
|
|
21
50
|
{
|
|
22
51
|
type: 'list',
|
|
23
52
|
name: 'templateType',
|
|
24
|
-
message: '
|
|
25
|
-
choices:
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
53
|
+
message: '请选择业务模板类型:',
|
|
54
|
+
choices: BUSINESS_TEMPLATE_CHOICES,
|
|
55
|
+
default: 'general',
|
|
56
|
+
},
|
|
57
|
+
{
|
|
58
|
+
type: 'list',
|
|
59
|
+
name: 'vueTemplateType',
|
|
60
|
+
message: '请选择 index.vue 的 Vue 语法风格:',
|
|
61
|
+
choices: VUE_TEMPLATE_STYLE_CHOICES,
|
|
62
|
+
default: 'setup',
|
|
30
63
|
},
|
|
31
64
|
{
|
|
32
65
|
type: 'input',
|
|
33
66
|
name: 'name',
|
|
34
|
-
message: '请输入组件名称
|
|
35
|
-
// 逻辑:如果命令行传入了 --name,则使用它,否则使用 'CustomComponent'
|
|
67
|
+
message: '请输入组件名称(大驼峰):',
|
|
36
68
|
default: (data) => data.name || 'CustomComponent',
|
|
37
69
|
},
|
|
38
70
|
{
|
|
39
|
-
type: 'list',
|
|
71
|
+
type: 'list',
|
|
40
72
|
name: 'collisionStrategy',
|
|
41
|
-
message: (data) => `目录 ${data.rootPath}/${data.name}
|
|
73
|
+
message: (data) => `目录 ${data.rootPath}/${data.name} 已存在,请选择处理方式:`,
|
|
42
74
|
choices: [
|
|
43
75
|
{ name: '覆盖', value: 'overwrite' },
|
|
44
76
|
{ name: '重新输入名称', value: 'retry' },
|
|
45
77
|
],
|
|
46
|
-
// 关键:只有当目录存在时才触发
|
|
47
78
|
when: (data) => {
|
|
48
79
|
const targetPath = path.join(process.cwd(), data.rootPath, data.name);
|
|
49
80
|
return fs.existsSync(targetPath);
|
|
50
81
|
},
|
|
51
82
|
},
|
|
52
83
|
{
|
|
53
|
-
// 关键点:如果用户选择 'retry',我们通过 validate 拦截并强制用户回到上一步
|
|
54
84
|
type: 'input',
|
|
55
85
|
name: 'retryName',
|
|
56
|
-
message: '
|
|
86
|
+
message: '请输入新的组件名称:',
|
|
57
87
|
when: (data) => data.collisionStrategy === 'retry',
|
|
58
88
|
validate: (value, data) => {
|
|
59
|
-
// 这里利用 validate 的特性:
|
|
60
|
-
// 我们直接修改上层 data.name,然后返回一个错误信息,
|
|
61
|
-
// 实际上会迫使 Inquirer 停留在这里,但此时 data.name 已经被修正
|
|
62
89
|
if (value && value !== data.name) {
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
return true;
|
|
90
|
+
data.name = value;
|
|
91
|
+
const newPath = path.join(process.cwd(), data.rootPath, value);
|
|
92
|
+
if (fs.existsSync(newPath)) {
|
|
93
|
+
return '新名称仍然已存在,请再次输入或 Ctrl+C 退出';
|
|
94
|
+
}
|
|
95
|
+
return true;
|
|
70
96
|
}
|
|
71
|
-
return '
|
|
72
|
-
}
|
|
73
|
-
}
|
|
97
|
+
return '请输入一个新的组件名称以避开冲突';
|
|
98
|
+
},
|
|
99
|
+
},
|
|
74
100
|
],
|
|
75
101
|
|
|
76
102
|
actions: (data) => {
|
|
77
103
|
const actions = [];
|
|
78
|
-
|
|
79
|
-
const
|
|
80
|
-
|
|
81
|
-
const
|
|
82
|
-
const componentName = changeCase.pascalCase(camelCase);
|
|
83
|
-
const className = changeCase.kebabCase(camelCase);
|
|
104
|
+
const finalName = data.name;
|
|
105
|
+
const camelName = changeCase.camelCase(finalName);
|
|
106
|
+
const componentName = changeCase.pascalCase(camelName);
|
|
107
|
+
const className = changeCase.kebabCase(camelName);
|
|
84
108
|
const targetFolder = `${data.rootPath}/${componentName}`;
|
|
109
|
+
const businessTemplateDir = BUSINESS_TEMPLATE_DIR_MAP[data.templateType];
|
|
110
|
+
const vueTemplateFile = VUE_TEMPLATE_FILE_MAP[data.vueTemplateType];
|
|
85
111
|
|
|
86
|
-
// 1. 如果选择了覆盖,执行删除动作
|
|
87
112
|
if (data.collisionStrategy === 'overwrite') {
|
|
88
113
|
actions.push({
|
|
89
114
|
type: 'deleteTargetDir',
|
|
@@ -91,29 +116,14 @@ export default (plop) => {
|
|
|
91
116
|
});
|
|
92
117
|
}
|
|
93
118
|
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
// 2. 生成文件列表 (统一配置)
|
|
97
|
-
const templates = [
|
|
98
|
-
{ file: 'index.scss', data: { class: className } },
|
|
99
|
-
{
|
|
100
|
-
file: 'index.vue',
|
|
101
|
-
templateFile: vueTemplateFile,
|
|
102
|
-
data: { class: className, componentName }
|
|
103
|
-
},
|
|
104
|
-
{ file: 'typing.ts', data: { interfaceName: componentName } },
|
|
105
|
-
{ file: 'hook.ts', data: { componentName } },
|
|
106
|
-
{ file: 'index.ts', data: { componentName } },
|
|
107
|
-
{ file: 'data.ts' },
|
|
108
|
-
];
|
|
109
|
-
|
|
110
|
-
templates.forEach(item => {
|
|
119
|
+
TEMPLATE_FILES.forEach((item) => {
|
|
120
|
+
const templateFile = item.type === 'vue-entry' ? vueTemplateFile : item.templateFile;
|
|
111
121
|
actions.push({
|
|
112
122
|
type: 'add',
|
|
113
|
-
force: true,
|
|
114
|
-
path:
|
|
115
|
-
templateFile: `${__dirname}/plop-templates/${
|
|
116
|
-
data: item.
|
|
123
|
+
force: true,
|
|
124
|
+
path: `${targetFolder}/${item.output}`,
|
|
125
|
+
templateFile: `${__dirname}/plop-templates/${businessTemplateDir}/${templateFile}`,
|
|
126
|
+
data: item.getData(componentName, className),
|
|
117
127
|
});
|
|
118
128
|
});
|
|
119
129
|
|
|
@@ -121,7 +131,6 @@ export default (plop) => {
|
|
|
121
131
|
},
|
|
122
132
|
});
|
|
123
133
|
|
|
124
|
-
// 注册自定义 Action:删除目录
|
|
125
134
|
plop.setActionType('deleteTargetDir', (answers, config) => {
|
|
126
135
|
const targetDir = path.join(process.cwd(), config.path);
|
|
127
136
|
if (fs.existsSync(targetDir)) {
|