Skip to content

Commit 7527267

Browse files
author
李磊
committed
fix: Vue3 组件属性(Props)辅助
1 parent bc04347 commit 7527267

File tree

2 files changed

+255
-0
lines changed

2 files changed

+255
-0
lines changed

apps/docs/.vitepress/config/zh.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,7 @@ export const zh = defineConfig({
8181
{ text: 'Vue大数据量渲染优化', link: '/blog/vueLargeDataRenderingOptimization' },
8282
{ text: 'vite 使用 monaco-Editor', link: '/blog/monacoEditor' },
8383
{ text: 'Monorepo 多项目 Nginx 配置', link: '/blog/monorepoNginx' },
84+
{ text: 'Vue3 组件属性(Props)辅助工具详解', link: '/blog/vueProps' },
8485
],
8586
},
8687
],

apps/docs/zh/blog/vueProps.md

Lines changed: 254 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,254 @@
1+
# Vue3 组件属性(Props)辅助工具详解
2+
3+
> 本文介绍一套高效、类型安全的 Vue3 组件属性(props)辅助工具,帮助你用更少的代码实现更强大的属性定义,提升开发效率,减少包体积。
4+
5+
## 目录
6+
7+
- [引言](#引言)
8+
- [核心工具函数与用法](#核心工具函数与用法)
9+
- [unknownProp](#unknownprop)
10+
- [numericProp](#numericprop)
11+
- [truthProp / lieProp](#truthprop--lieprop)
12+
- [makeRequiredProp](#makerequiredprop)
13+
- [makeNumericProp / makeStringProp / makeNumberProp](#makenumericprop--makestringprop--makenumberprop)
14+
- [makeArrayProp / makeObjectProp / makeFuncProp](#makearrayprop--makeobjectprop--makefuncprop)
15+
- [makeUniteProp](#makeuniteprop)
16+
- [实际用例](#实际用例)
17+
- [最佳实践与建议](#最佳实践与建议)
18+
- [常见问题与对比](#常见问题与对比)
19+
- [总结](#总结)
20+
21+
## 引言
22+
23+
在 Vue3 组件开发中,合理定义 props 能提升组件的健壮性和可维护性。手写 props 类型繁琐且易出错,本工具集通过类型推导和工厂函数,极大简化了 props 的声明方式。
24+
25+
---
26+
27+
## 核心工具函数与用法
28+
29+
### unknownProp
30+
31+
```ts
32+
export const unknownProp = null as unknown as PropType<unknown>;
33+
```
34+
35+
**用途**:用于声明类型未知的 prop,适合兜底场景。
36+
37+
---
38+
39+
### numericProp
40+
41+
```ts
42+
export const numericProp = [Number, String];
43+
```
44+
45+
**用途**:允许 prop 同时接受数字和字符串,常用于宽高、padding 等场景。
46+
47+
---
48+
49+
### truthProp / lieProp
50+
51+
```ts
52+
export const truthProp = { type: Boolean, default: true as const };
53+
export const lieProp = { type: Boolean, default: false as const };
54+
```
55+
56+
**用途**:快速声明布尔型 prop,分别默认 true/false。
57+
58+
**示例**
59+
60+
```ts
61+
props: {
62+
visible: truthProp, // 默认 true
63+
disabled: lieProp // 默认 false
64+
}
65+
```
66+
67+
---
68+
69+
### makeRequiredProp
70+
71+
```ts
72+
export const makeRequiredProp = <T>(type: T) => ({ type, required: true as const });
73+
```
74+
75+
**用途**:声明必填 prop,自动推断类型。
76+
77+
**示例**
78+
79+
```ts
80+
props: {
81+
label: makeRequiredProp(String);
82+
}
83+
```
84+
85+
---
86+
87+
### makeNumericProp / makeStringProp / makeNumberProp
88+
89+
```ts
90+
export const makeNumericProp = <T>(defVal: T) => ({ type: numericProp, default: defVal });
91+
export const makeStringProp = <T>(defVal: T) => ({
92+
type: String as unknown as PropType<T>,
93+
default: defVal,
94+
});
95+
export const makeNumberProp = <T>(defVal: T) => ({
96+
type: Number as unknown as PropType<T>,
97+
default: defVal,
98+
});
99+
```
100+
101+
**用途**:快速声明带默认值的数字/字符串/数字或字符串类型 prop。
102+
103+
**示例**
104+
105+
```ts
106+
props: {
107+
size: makeNumericProp('small'),
108+
title: makeStringProp('标题'),
109+
count: makeNumberProp(0)
110+
}
111+
```
112+
113+
---
114+
115+
### makeArrayProp / makeObjectProp / makeFuncProp
116+
117+
```ts
118+
export const makeArrayProp = <T>(defVal: T[]) => ({
119+
type: Array as PropType<T[]>,
120+
default: () => defVal,
121+
});
122+
export const makeObjectProp = <T>(defVal: T) => ({
123+
type: Object as PropType<T>,
124+
default: () => defVal,
125+
});
126+
export const makeFuncProp = <T>(defVal: T) => ({ type: Function as PropType<T>, default: defVal });
127+
```
128+
129+
**用途**:声明数组、对象、函数类型 prop,默认值用工厂函数返回,避免引用类型共享。
130+
131+
**示例**
132+
133+
```ts
134+
props: {
135+
list: makeArrayProp<string>([]),
136+
config: makeObjectProp({}),
137+
onClick: makeFuncProp(() => {})
138+
}
139+
```
140+
141+
---
142+
143+
### makeUniteProp
144+
145+
```ts
146+
export const makeUniteProp = <T, V>(type: T[], defVal: V) => ({ type, default: () => defVal });
147+
```
148+
149+
**用途**:声明联合类型 prop,适合枚举值场景。
150+
151+
**示例**
152+
153+
```ts
154+
props: {
155+
status: makeUniteProp(['success', 'error', 'info'], 'info');
156+
}
157+
```
158+
159+
---
160+
161+
## 实际用例
162+
163+
```ts
164+
export const props = {
165+
prop1: makeRequiredProp(String),
166+
prop2: makeArrayProp<string>(['a', 'b', 'c']),
167+
prop3: makeArrayProp<Record<string, unknown>>([]),
168+
};
169+
170+
export type Props = ExtractPropTypes<typeof props>;
171+
```
172+
173+
## 最佳实践与建议
174+
175+
- 优先使用工厂函数声明 props,减少样板代码。
176+
- 引用类型(Array/Object)默认值必须用函数返回,避免数据污染。
177+
- 合理利用类型推断,提升类型安全。
178+
- 对于布尔、枚举、必填等常见场景,优先用 truthProp、lieProp、makeUniteProp、makeRequiredProp。
179+
- 复杂类型建议单独定义类型,增强可读性。
180+
181+
## 常见问题与对比
182+
183+
- **手写 props 对比**:手写 props 易遗漏类型、required、default,且冗长。
184+
- **工厂函数优势**:统一风格、类型安全、易维护。
185+
- **错误用法**:引用类型默认值直接赋值会导致所有组件实例共享同一份数据。
186+
187+
## 总结
188+
189+
本工具集极大简化了 Vue3 组件属性声明,提升了开发效率和代码健壮性。建议在团队项目中推广使用,结合类型系统和最佳实践,打造高质量组件库。
190+
191+
```ts
192+
/**
193+
* 组件属性辅助
194+
* 🙌 能够使用更少的代码编写,有助于减少包体积
195+
*/
196+
import type { PropType } from 'vue';
197+
198+
export const unknownProp = null as unknown as PropType<unknown>;
199+
200+
export const numericProp = [Number, String];
201+
202+
export const truthProp = {
203+
type: Boolean,
204+
default: true as const,
205+
};
206+
207+
export const lieProp = {
208+
type: Boolean,
209+
default: false as const,
210+
};
211+
212+
export const makeRequiredProp = <T>(type: T) => {
213+
return { type, required: true as const };
214+
};
215+
216+
export const makeNumericProp = <T>(defVal: T) => {
217+
return { type: numericProp, default: defVal };
218+
};
219+
220+
export const makeStringProp = <T>(defVal: T) => {
221+
return { type: String as unknown as PropType<T>, default: defVal };
222+
};
223+
224+
export const makeNumberProp = <T>(defVal: T) => {
225+
return { type: Number as unknown as PropType<T>, default: defVal };
226+
};
227+
228+
export const makeArrayProp = <T>(defVal: T[]) => {
229+
return { type: Array as PropType<T[]>, default: () => defVal };
230+
};
231+
232+
export const makeObjectProp = <T>(defVal: T) => {
233+
return { type: Object as PropType<T>, default: () => defVal };
234+
};
235+
236+
export const makeFuncProp = <T>(defVal: T) => {
237+
return { type: Function as PropType<T>, default: defVal };
238+
};
239+
240+
// 联和类型属性
241+
export const makeUniteProp = <T, V>(type: T[], defVal: V) => {
242+
return { type, default: () => defVal };
243+
};
244+
245+
import type { PropType, ExtractPropTypes } from 'vue';
246+
247+
export const props = {
248+
prop1: makeRequiredProp(String),
249+
prop2: makeArrayProp<string>(['a', 'b', 'c']),
250+
prop3: makeArrayProp<Record<string, unknown>[]>([]),
251+
};
252+
253+
export type Props = ExtractPropTypes<typeof props>;
254+
```

0 commit comments

Comments
 (0)