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.
Files changed (78) hide show
  1. package/.changeset/config.json +1 -1
  2. package/AGENTS.md +114 -0
  3. package/CHANGELOG.md +13 -1
  4. package/CLAUDE.md +20 -8
  5. package/README.md +49 -21
  6. package/bin/cli.mjs +38 -29
  7. 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
  8. 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
  9. 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
  10. 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
  11. 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
  12. 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
  13. package/package.json +4 -3
  14. package/plop-templates/general/data.ts.hbs +16 -0
  15. package/plop-templates/general/hook.ts.hbs +11 -0
  16. package/plop-templates/general/index.normal.vue.hbs +28 -0
  17. package/plop-templates/general/index.scss.hbs +5 -0
  18. package/plop-templates/general/index.setup.vue.hbs +20 -0
  19. package/plop-templates/{index.ts.hbs → general/index.ts.hbs} +2 -1
  20. package/plop-templates/general/typing.ts.hbs +13 -0
  21. package/plop-templates/multiple-pick/data.ts.hbs +20 -0
  22. package/plop-templates/multiple-pick/hook.ts.hbs +11 -0
  23. package/plop-templates/multiple-pick/index.normal.vue.hbs +37 -0
  24. package/plop-templates/multiple-pick/index.scss.hbs +5 -0
  25. package/plop-templates/multiple-pick/index.setup.vue.hbs +22 -0
  26. package/plop-templates/multiple-pick/index.ts.hbs +4 -0
  27. package/plop-templates/multiple-pick/typing.ts.hbs +13 -0
  28. package/plop-templates/single-pick/data.ts.hbs +16 -0
  29. package/plop-templates/single-pick/hook.ts.hbs +11 -0
  30. package/plop-templates/single-pick/index.normal.vue.hbs +36 -0
  31. package/plop-templates/single-pick/index.scss.hbs +5 -0
  32. package/plop-templates/single-pick/index.setup.vue.hbs +23 -0
  33. package/plop-templates/single-pick/index.ts.hbs +4 -0
  34. package/plop-templates/single-pick/typing.ts.hbs +13 -0
  35. package/plopfile.mjs +68 -59
  36. package/src/generate.mjs +101 -31
  37. package/tmp-output/GeneralNormalDemo/index.ts +4 -0
  38. package/tmp-output/GeneralNormalDemo/src/data.ts +16 -0
  39. package/tmp-output/GeneralNormalDemo/src/hook.ts +11 -0
  40. package/tmp-output/GeneralNormalDemo/src/index.scss +5 -0
  41. package/tmp-output/GeneralNormalDemo/src/index.vue +28 -0
  42. package/tmp-output/GeneralNormalDemo/src/typing.ts +13 -0
  43. package/tmp-output/GeneralSetupDemo/index.ts +4 -0
  44. package/tmp-output/GeneralSetupDemo/src/data.ts +16 -0
  45. package/tmp-output/GeneralSetupDemo/src/hook.ts +11 -0
  46. package/tmp-output/GeneralSetupDemo/src/index.scss +5 -0
  47. package/tmp-output/GeneralSetupDemo/src/index.vue +20 -0
  48. package/tmp-output/GeneralSetupDemo/src/typing.ts +13 -0
  49. package/tmp-output/MultiplePickNormalDemo/index.ts +4 -0
  50. package/tmp-output/MultiplePickNormalDemo/src/data.ts +20 -0
  51. package/tmp-output/MultiplePickNormalDemo/src/hook.ts +11 -0
  52. package/tmp-output/MultiplePickNormalDemo/src/index.scss +5 -0
  53. package/tmp-output/MultiplePickNormalDemo/src/index.vue +37 -0
  54. package/tmp-output/MultiplePickNormalDemo/src/typing.ts +13 -0
  55. package/tmp-output/MultiplePickSetupDemo/index.ts +4 -0
  56. package/tmp-output/MultiplePickSetupDemo/src/data.ts +20 -0
  57. package/tmp-output/MultiplePickSetupDemo/src/hook.ts +11 -0
  58. package/tmp-output/MultiplePickSetupDemo/src/index.scss +5 -0
  59. package/tmp-output/MultiplePickSetupDemo/src/index.vue +22 -0
  60. package/tmp-output/MultiplePickSetupDemo/src/typing.ts +13 -0
  61. package/tmp-output/SinglePickNormalDemo/index.ts +4 -0
  62. package/tmp-output/SinglePickNormalDemo/src/data.ts +16 -0
  63. package/tmp-output/SinglePickNormalDemo/src/hook.ts +11 -0
  64. package/tmp-output/SinglePickNormalDemo/src/index.scss +5 -0
  65. package/tmp-output/SinglePickNormalDemo/src/index.vue +36 -0
  66. package/tmp-output/SinglePickNormalDemo/src/typing.ts +13 -0
  67. package/tmp-output/SinglePickSetupDemo/index.ts +4 -0
  68. package/tmp-output/SinglePickSetupDemo/src/data.ts +16 -0
  69. package/tmp-output/SinglePickSetupDemo/src/hook.ts +11 -0
  70. package/tmp-output/SinglePickSetupDemo/src/index.scss +5 -0
  71. package/tmp-output/SinglePickSetupDemo/src/index.vue +23 -0
  72. package/tmp-output/SinglePickSetupDemo/src/typing.ts +13 -0
  73. package/plop-templates/data.ts.hbs +0 -7
  74. package/plop-templates/hook.ts.hbs +0 -29
  75. package/plop-templates/index.scss.hbs +0 -1
  76. package/plop-templates/index.setup.vue.hbs +0 -25
  77. package/plop-templates/index.vue.hbs +0 -38
  78. package/plop-templates/typing.ts.hbs +0 -14
package/src/generate.mjs CHANGED
@@ -7,24 +7,45 @@ const __filename = fileURLToPath(import.meta.url);
7
7
  const __dirname = path.dirname(__filename);
8
8
  const TEMPLATES_DIR = path.join(__dirname, '..', 'plop-templates');
9
9
 
10
- const VALID_TEMPLATE_TYPES = ['setup', 'normal'];
10
+ const BUSINESS_TEMPLATE_MAP = {
11
+ general: {
12
+ label: '通用模板',
13
+ templateDir: 'general',
14
+ },
15
+ 'single-pick': {
16
+ label: '产品组单选模板',
17
+ templateDir: 'single-pick',
18
+ },
19
+ 'multiple-pick': {
20
+ label: '产品组多选模板',
21
+ templateDir: 'multiple-pick',
22
+ },
23
+ };
24
+
25
+ const VUE_TEMPLATE_STYLE_MAP = {
26
+ setup: {
27
+ label: 'script setup 风格',
28
+ templateFile: 'index.setup.vue.hbs',
29
+ },
30
+ normal: {
31
+ label: 'defineComponent 风格',
32
+ templateFile: 'index.normal.vue.hbs',
33
+ },
34
+ };
35
+
11
36
  const VALID_COLLISION_STRATEGIES = ['skip', 'overwrite'];
12
37
 
13
- const TEMPLATE_CONFIG = [
14
- { file: 'index.scss', dest: 'src', templateFile: 'index.scss.hbs', getData: (cn, cl) => ({ class: cl }) },
15
- { file: 'index.vue', dest: 'src', getData: (cn, cl, tt) => ({
16
- templateFile: tt === 'setup' ? 'index.setup.vue.hbs' : 'index.vue.hbs',
17
- data: { class: cl, componentName: cn },
18
- })},
19
- { file: 'typing.ts', dest: 'src', templateFile: 'typing.ts.hbs', getData: (cn) => ({ interfaceName: cn }) },
20
- { file: 'hook.ts', dest: 'src', templateFile: 'hook.ts.hbs', getData: (cn) => ({ componentName: cn }) },
21
- { file: 'data.ts', dest: 'src', templateFile: 'data.ts.hbs', getData: () => ({}) },
22
- { file: 'index.ts', dest: '', templateFile: 'index.ts.hbs', getData: (cn) => ({ componentName: cn }) },
38
+ const TEMPLATE_FILES = [
39
+ { output: 'src/index.scss', templateFile: 'index.scss.hbs', getData: (componentName, className) => ({ class: className, componentName }) },
40
+ { output: 'src/index.vue', type: 'vue-entry', getData: (componentName, className) => ({ class: className, componentName }) },
41
+ { output: 'src/typing.ts', templateFile: 'typing.ts.hbs', getData: (componentName) => ({ interfaceName: componentName, componentName }) },
42
+ { output: 'src/hook.ts', templateFile: 'hook.ts.hbs', getData: (componentName) => ({ componentName }) },
43
+ { output: 'src/data.ts', templateFile: 'data.ts.hbs', getData: (componentName) => ({ componentName }) },
44
+ { output: 'index.ts', templateFile: 'index.ts.hbs', getData: (componentName) => ({ componentName }) },
23
45
  ];
24
46
 
25
- function renderTemplate(templateName, data) {
26
- const filePath = path.join(TEMPLATES_DIR, templateName);
27
- const source = fs.readFileSync(filePath, 'utf-8');
47
+ function renderTemplate(templatePath, data) {
48
+ const source = fs.readFileSync(templatePath, 'utf-8');
28
49
  let result = source;
29
50
  for (const [key, value] of Object.entries(data)) {
30
51
  result = result.replaceAll(`{{ ${key} }}`, String(value));
@@ -33,18 +54,56 @@ function renderTemplate(templateName, data) {
33
54
  return result;
34
55
  }
35
56
 
36
- export function generateComponent({ name, rootPath, templateType = 'setup', collisionStrategy = 'skip' }) {
57
+ function resolveTemplateOptions({ templateType, vueTemplateType }) {
58
+ const businessTemplate = BUSINESS_TEMPLATE_MAP[templateType];
59
+ const vueTemplateStyle = VUE_TEMPLATE_STYLE_MAP[vueTemplateType];
60
+
61
+ if (!businessTemplate) {
62
+ return {
63
+ success: false,
64
+ error: `无效的 templateType: "${templateType}",可选值: ${Object.keys(BUSINESS_TEMPLATE_MAP).join(', ')}`,
65
+ };
66
+ }
67
+
68
+ if (!vueTemplateStyle) {
69
+ return {
70
+ success: false,
71
+ error: `无效的 vueTemplateType: "${vueTemplateType}",可选值: ${Object.keys(VUE_TEMPLATE_STYLE_MAP).join(', ')}`,
72
+ };
73
+ }
74
+
75
+ return {
76
+ success: true,
77
+ businessTemplate,
78
+ vueTemplateStyle,
79
+ };
80
+ }
81
+
82
+ export function generateComponent({
83
+ name,
84
+ rootPath,
85
+ templateType = 'general',
86
+ vueTemplateType = 'setup',
87
+ collisionStrategy = 'skip',
88
+ }) {
37
89
  if (!name || typeof name !== 'string') {
38
90
  return { success: false, error: '缺少必填参数: --name (组件名称)' };
39
91
  }
92
+
40
93
  if (!rootPath || typeof rootPath !== 'string') {
41
94
  return { success: false, error: '缺少必填参数: --rootPath (组件生成路径)' };
42
95
  }
43
- if (!VALID_TEMPLATE_TYPES.includes(templateType)) {
44
- return { success: false, error: `无效的 templateType: "${templateType}",可选值: ${VALID_TEMPLATE_TYPES.join(', ')}` };
96
+
97
+ const resolvedOptions = resolveTemplateOptions({ templateType, vueTemplateType });
98
+ if (!resolvedOptions.success) {
99
+ return resolvedOptions;
45
100
  }
101
+
46
102
  if (!VALID_COLLISION_STRATEGIES.includes(collisionStrategy)) {
47
- return { success: false, error: `无效的 collisionStrategy: "${collisionStrategy}",可选值: ${VALID_COLLISION_STRATEGIES.join(', ')}` };
103
+ return {
104
+ success: false,
105
+ error: `无效的 collisionStrategy: "${collisionStrategy}",可选值: ${VALID_COLLISION_STRATEGIES.join(', ')}`,
106
+ };
48
107
  }
49
108
 
50
109
  const camelName = changeCase.camelCase(name);
@@ -55,31 +114,42 @@ export function generateComponent({ name, rootPath, templateType = 'setup', coll
55
114
 
56
115
  if (fs.existsSync(fullTargetPath)) {
57
116
  if (collisionStrategy === 'skip') {
58
- return { success: false, error: `目录已存在: ${targetFolder}(使用 --collisionStrategy=overwrite 覆盖)` };
117
+ return {
118
+ success: false,
119
+ error: `目录已存在: ${targetFolder}(使用 --collisionStrategy=overwrite 覆盖)`,
120
+ };
59
121
  }
122
+
60
123
  if (collisionStrategy === 'overwrite') {
61
124
  fs.rmSync(fullTargetPath, { recursive: true, force: true });
62
125
  }
63
126
  }
64
127
 
128
+ const { businessTemplate, vueTemplateStyle } = resolvedOptions;
65
129
  const generatedFiles = [];
66
130
 
67
- for (const item of TEMPLATE_CONFIG) {
68
- const itemResult = item.getData(componentName, className, templateType);
69
- const templateFile = itemResult.templateFile || item.templateFile;
70
- const templateData = itemResult.data || itemResult;
71
-
72
- const destDir = item.dest === ''
73
- ? fullTargetPath
74
- : path.join(fullTargetPath, item.dest);
75
- const destFile = path.join(destDir, item.file);
131
+ for (const item of TEMPLATE_FILES) {
132
+ const templateFile = item.type === 'vue-entry' ? vueTemplateStyle.templateFile : item.templateFile;
133
+ const templatePath = path.join(TEMPLATES_DIR, businessTemplate.templateDir, templateFile);
134
+ const templateData = item.getData(componentName, className);
135
+ const destFile = path.join(fullTargetPath, item.output);
136
+ const destDir = path.dirname(destFile);
76
137
 
77
138
  fs.mkdirSync(destDir, { recursive: true });
78
139
 
79
- const content = renderTemplate(templateFile, templateData);
140
+ const content = renderTemplate(templatePath, templateData);
80
141
  fs.writeFileSync(destFile, content, 'utf-8');
81
- generatedFiles.push(path.join(targetFolder, item.dest, item.file).replace(/\\/g, '/'));
142
+ generatedFiles.push(path.join(targetFolder, item.output).replace(/\\/g, '/'));
82
143
  }
83
144
 
84
- return { success: true, files: generatedFiles, componentName, targetFolder };
145
+ return {
146
+ success: true,
147
+ files: generatedFiles,
148
+ componentName,
149
+ targetFolder,
150
+ templateType,
151
+ vueTemplateType,
152
+ templateLabel: businessTemplate.label,
153
+ vueTemplateLabel: vueTemplateStyle.label,
154
+ };
85
155
  }
@@ -0,0 +1,4 @@
1
+ import GeneralNormalDemo from './src/index.vue'
2
+
3
+ export default GeneralNormalDemo
4
+ export * from './src/typing'
@@ -0,0 +1,16 @@
1
+ import type { DataType } from './typing'
2
+
3
+ const data: Array<DataType> = [
4
+ {
5
+ label: '示例项1',
6
+ value: 'option-1',
7
+ },
8
+ {
9
+ label: '示例项2',
10
+ value: 'option-2',
11
+ },
12
+ ]
13
+
14
+ export {
15
+ data,
16
+ }
@@ -0,0 +1,11 @@
1
+ import { ref } from 'vue'
2
+ import type { GeneralNormalDemoProps } from './typing'
3
+
4
+ export const useGeneralNormalDemo = (props: GeneralNormalDemoProps) => {
5
+ const visible = ref(true)
6
+
7
+ return {
8
+ props,
9
+ visible,
10
+ }
11
+ }
@@ -0,0 +1,5 @@
1
+ .general-normal-demo {
2
+ position: absolute;
3
+ top: 0;
4
+ left: 0;
5
+ }
@@ -0,0 +1,28 @@
1
+ <template>
2
+ <div class="general-normal-demo"></div>
3
+ </template>
4
+
5
+ <script lang="ts">
6
+ import { defineComponent, PropType } from 'vue'
7
+ import { GeneralNormalDemoProps } from './typing'
8
+ import { useGeneralNormalDemo } from './hook'
9
+
10
+ export default defineComponent({
11
+ name: 'GeneralNormalDemo',
12
+ props: {
13
+ user: {
14
+ type: Object as PropType<GeneralNormalDemoProps['user']>,
15
+ required: false,
16
+ },
17
+ },
18
+ setup(props) {
19
+ const {} = useGeneralNormalDemo(props as GeneralNormalDemoProps)
20
+
21
+ return {}
22
+ },
23
+ })
24
+ </script>
25
+
26
+ <style lang="scss" scoped>
27
+ @import './index.scss';
28
+ </style>
@@ -0,0 +1,13 @@
1
+ export enum GeneralNormalDemoEnum {
2
+ ENUM_KEY1 = 'ENUM_KEY1',
3
+ ENUM_KEY2 = 'ENUM_KEY2',
4
+ }
5
+
6
+ export interface GeneralNormalDemoProps {
7
+ user?: Record<string, any>
8
+ }
9
+
10
+ export interface DataType {
11
+ label: string
12
+ value: string
13
+ }
@@ -0,0 +1,4 @@
1
+ import GeneralSetupDemo from './src/index.vue'
2
+
3
+ export default GeneralSetupDemo
4
+ export * from './src/typing'
@@ -0,0 +1,16 @@
1
+ import type { DataType } from './typing'
2
+
3
+ const data: Array<DataType> = [
4
+ {
5
+ label: '示例项1',
6
+ value: 'option-1',
7
+ },
8
+ {
9
+ label: '示例项2',
10
+ value: 'option-2',
11
+ },
12
+ ]
13
+
14
+ export {
15
+ data,
16
+ }
@@ -0,0 +1,11 @@
1
+ import { ref } from 'vue'
2
+ import type { GeneralSetupDemoProps } from './typing'
3
+
4
+ export const useGeneralSetupDemo = (props: GeneralSetupDemoProps) => {
5
+ const visible = ref(true)
6
+
7
+ return {
8
+ props,
9
+ visible,
10
+ }
11
+ }
@@ -0,0 +1,5 @@
1
+ .general-setup-demo {
2
+ position: absolute;
3
+ top: 0;
4
+ left: 0;
5
+ }
@@ -0,0 +1,20 @@
1
+ <template>
2
+ <div class="general-setup-demo"></div>
3
+ </template>
4
+
5
+ <script setup lang="ts">
6
+ import { GeneralSetupDemoProps } from './typing'
7
+ import { useGeneralSetupDemo } from './hook'
8
+
9
+ defineOptions({
10
+ name: 'GeneralSetupDemo',
11
+ })
12
+
13
+ const props = defineProps<GeneralSetupDemoProps>()
14
+
15
+ const {} = useGeneralSetupDemo(props)
16
+ </script>
17
+
18
+ <style lang="scss" scoped>
19
+ @import './index.scss';
20
+ </style>
@@ -0,0 +1,13 @@
1
+ export enum GeneralSetupDemoEnum {
2
+ ENUM_KEY1 = 'ENUM_KEY1',
3
+ ENUM_KEY2 = 'ENUM_KEY2',
4
+ }
5
+
6
+ export interface GeneralSetupDemoProps {
7
+ user?: Record<string, any>
8
+ }
9
+
10
+ export interface DataType {
11
+ label: string
12
+ value: string
13
+ }
@@ -0,0 +1,4 @@
1
+ import MultiplePickNormalDemo from './src/index.vue'
2
+
3
+ export default MultiplePickNormalDemo
4
+ export * from './src/typing'
@@ -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 { MultiplePickNormalDemoProps } from './typing'
4
+
5
+ export const useMultiplePickNormalDemo = (props: MultiplePickNormalDemoProps) => {
6
+ const selectedValues = ref(props.modelValue ?? data.slice(0, 2).map((item) => item.value))
7
+
8
+ return {
9
+ selectedValues,
10
+ }
11
+ }
@@ -0,0 +1,5 @@
1
+ .multiple-pick-normal-demo {
2
+ position: absolute;
3
+ top: 0;
4
+ left: 0;
5
+ }
@@ -0,0 +1,37 @@
1
+ <template>
2
+ <div class="multiple-pick-normal-demo">
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 { MultiplePickNormalDemoProps } from './typing'
10
+ import { useMultiplePickNormalDemo } from './hook'
11
+
12
+ export default defineComponent({
13
+ name: 'MultiplePickNormalDemo',
14
+ props: {
15
+ user: {
16
+ type: Object as PropType<MultiplePickNormalDemoProps['user']>,
17
+ required: false,
18
+ },
19
+ modelValue: {
20
+ type: Array as PropType<MultiplePickNormalDemoProps['modelValue']>,
21
+ required: false,
22
+ default: () => [],
23
+ },
24
+ },
25
+ setup(props) {
26
+ const { selectedValues } = useMultiplePickNormalDemo(props as MultiplePickNormalDemoProps)
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,13 @@
1
+ export enum MultiplePickNormalDemoEnum {
2
+ DEFAULT = 'default',
3
+ }
4
+
5
+ export interface MultiplePickNormalDemoProps {
6
+ user?: Record<string, any>
7
+ modelValue?: string[]
8
+ }
9
+
10
+ export interface DataType {
11
+ label: string
12
+ value: string
13
+ }
@@ -0,0 +1,4 @@
1
+ import MultiplePickSetupDemo from './src/index.vue'
2
+
3
+ export default MultiplePickSetupDemo
4
+ export * from './src/typing'
@@ -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 { MultiplePickSetupDemoProps } from './typing'
4
+
5
+ export const useMultiplePickSetupDemo = (props: MultiplePickSetupDemoProps) => {
6
+ const selectedValues = ref(props.modelValue ?? data.slice(0, 2).map((item) => item.value))
7
+
8
+ return {
9
+ selectedValues,
10
+ }
11
+ }
@@ -0,0 +1,5 @@
1
+ .multiple-pick-setup-demo {
2
+ position: absolute;
3
+ top: 0;
4
+ left: 0;
5
+ }
@@ -0,0 +1,22 @@
1
+ <template>
2
+ <div class="multiple-pick-setup-demo">
3
+ <div v-for="item in selectedValues" :key="item">{{ item }}</div>
4
+ </div>
5
+ </template>
6
+
7
+ <script setup lang="ts">
8
+ import { MultiplePickSetupDemoProps } from './typing'
9
+ import { useMultiplePickSetupDemo } from './hook'
10
+
11
+ defineOptions({
12
+ name: 'MultiplePickSetupDemo',
13
+ })
14
+
15
+ const props = defineProps<MultiplePickSetupDemoProps>()
16
+
17
+ const { selectedValues } = useMultiplePickSetupDemo(props)
18
+ </script>
19
+
20
+ <style lang="scss" scoped>
21
+ @import './index.scss';
22
+ </style>
@@ -0,0 +1,13 @@
1
+ export enum MultiplePickSetupDemoEnum {
2
+ DEFAULT = 'default',
3
+ }
4
+
5
+ export interface MultiplePickSetupDemoProps {
6
+ user?: Record<string, any>
7
+ modelValue?: string[]
8
+ }
9
+
10
+ export interface DataType {
11
+ label: string
12
+ value: string
13
+ }
@@ -0,0 +1,4 @@
1
+ import SinglePickNormalDemo from './src/index.vue'
2
+
3
+ export default SinglePickNormalDemo
4
+ export * from './src/typing'
@@ -0,0 +1,16 @@
1
+ import type { DataType } from './typing'
2
+
3
+ const data: Array<DataType> = [
4
+ {
5
+ label: '单选项1',
6
+ value: 'single-1',
7
+ },
8
+ {
9
+ label: '单选项2',
10
+ value: 'single-2',
11
+ },
12
+ ]
13
+
14
+ export {
15
+ data,
16
+ }
@@ -0,0 +1,11 @@
1
+ import { ref } from 'vue'
2
+ import { data } from './data'
3
+ import type { SinglePickNormalDemoProps } from './typing'
4
+
5
+ export const useSinglePickNormalDemo = (props: SinglePickNormalDemoProps) => {
6
+ const selectedValue = ref(props.modelValue ?? data[0]?.value ?? '')
7
+
8
+ return {
9
+ selectedValue,
10
+ }
11
+ }
@@ -0,0 +1,5 @@
1
+ .single-pick-normal-demo {
2
+ position: absolute;
3
+ top: 0;
4
+ left: 0;
5
+ }
@@ -0,0 +1,36 @@
1
+ <template>
2
+ <div class="single-pick-normal-demo">
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 { SinglePickNormalDemoProps } from './typing'
11
+ import { useSinglePickNormalDemo } from './hook'
12
+
13
+ export default defineComponent({
14
+ name: 'SinglePickNormalDemo',
15
+ components: {
16
+ SinglePickButtonGroup,
17
+ },
18
+ props: {
19
+ user: {
20
+ type: Object as PropType<SinglePickNormalDemoProps['user']>,
21
+ required: false,
22
+ },
23
+ },
24
+ setup(props) {
25
+ const { selectedValue } = useSinglePickNormalDemo(props as SinglePickNormalDemoProps)
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,13 @@
1
+ export enum SinglePickNormalDemoEnum {
2
+ DEFAULT = 'default',
3
+ }
4
+
5
+ export interface SinglePickNormalDemoProps {
6
+ user?: Record<string, any>
7
+ modelValue?: string
8
+ }
9
+
10
+ export interface DataType {
11
+ label: string
12
+ value: string
13
+ }
@@ -0,0 +1,4 @@
1
+ import SinglePickSetupDemo from './src/index.vue'
2
+
3
+ export default SinglePickSetupDemo
4
+ export * from './src/typing'
@@ -0,0 +1,16 @@
1
+ import type { DataType } from './typing'
2
+
3
+ const data: Array<DataType> = [
4
+ {
5
+ label: '单选项1',
6
+ value: 'single-1',
7
+ },
8
+ {
9
+ label: '单选项2',
10
+ value: 'single-2',
11
+ },
12
+ ]
13
+
14
+ export {
15
+ data,
16
+ }
@@ -0,0 +1,11 @@
1
+ import { ref } from 'vue'
2
+ import { data } from './data'
3
+ import type { SinglePickSetupDemoProps } from './typing'
4
+
5
+ export const useSinglePickSetupDemo = (props: SinglePickSetupDemoProps) => {
6
+ const selectedValue = ref(props.modelValue ?? data[0]?.value ?? '')
7
+
8
+ return {
9
+ selectedValue,
10
+ }
11
+ }
@@ -0,0 +1,5 @@
1
+ .single-pick-setup-demo {
2
+ position: absolute;
3
+ top: 0;
4
+ left: 0;
5
+ }