Skip to content

Vue3 组件属性(Props)辅助工具详解

本文介绍一套高效、类型安全的 Vue3 组件属性(props)辅助工具,帮助你用更少的代码实现更强大的属性定义,提升开发效率,减少包体积。

目录

引言

在 Vue3 组件开发中,合理定义 props 能提升组件的健壮性和可维护性。手写 props 类型繁琐且易出错,本工具集通过类型推导和工厂函数,极大简化了 props 的声明方式。


核心工具函数与用法

unknownProp

ts
export const unknownProp = null as unknown as PropType<unknown>;

用途:用于声明类型未知的 prop,适合兜底场景。


numericProp

ts
export const numericProp = [Number, String];

用途:允许 prop 同时接受数字和字符串,常用于宽高、padding 等场景。


truthProp / lieProp

ts
export const truthProp = { type: Boolean, default: true as const };
export const lieProp = { type: Boolean, default: false as const };

用途:快速声明布尔型 prop,分别默认 true/false。

示例

ts
props: {
  visible: truthProp, // 默认 true
  disabled: lieProp   // 默认 false
}

makeRequiredProp

ts
export const makeRequiredProp = <T>(type: T) => ({ type, required: true as const });

用途:声明必填 prop,自动推断类型。

示例

ts
props: {
  label: makeRequiredProp(String);
}

makeNumericProp / makeStringProp / makeNumberProp

ts
export const makeNumericProp = <T>(defVal: T) => ({ type: numericProp, default: defVal });
export const makeStringProp = <T>(defVal: T) => ({
  type: String as unknown as PropType<T>,
  default: defVal,
});
export const makeNumberProp = <T>(defVal: T) => ({
  type: Number as unknown as PropType<T>,
  default: defVal,
});

用途:快速声明带默认值的数字/字符串/数字或字符串类型 prop。

示例

ts
props: {
  size: makeNumericProp('small'),
  title: makeStringProp('标题'),
  count: makeNumberProp(0)
}

makeArrayProp / makeObjectProp / makeFuncProp

ts
export const makeArrayProp = <T>(defVal: T[]) => ({
  type: Array as PropType<T[]>,
  default: () => defVal,
});
export const makeObjectProp = <T>(defVal: T) => ({
  type: Object as PropType<T>,
  default: () => defVal,
});
export const makeFuncProp = <T>(defVal: T) => ({ type: Function as PropType<T>, default: defVal });

用途:声明数组、对象、函数类型 prop,默认值用工厂函数返回,避免引用类型共享。

示例

ts
props: {
  list: makeArrayProp<string>([]),
  config: makeObjectProp({}),
  onClick: makeFuncProp(() => {})
}

makeUniteProp

ts
export const makeUniteProp = <T, V>(type: T[], defVal: V) => ({ type, default: () => defVal });

用途:声明联合类型 prop,适合枚举值场景。

示例

ts
props: {
  status: makeUniteProp(['success', 'error', 'info'], 'info');
}

实际用例

ts
export const props = {
  prop1: makeRequiredProp(String),
  prop2: makeArrayProp<string>(['a', 'b', 'c']),
  prop3: makeArrayProp<Record<string, unknown>>([]),
};

export type Props = ExtractPropTypes<typeof props>;

最佳实践与建议

  • 优先使用工厂函数声明 props,减少样板代码。
  • 引用类型(Array/Object)默认值必须用函数返回,避免数据污染。
  • 合理利用类型推断,提升类型安全。
  • 对于布尔、枚举、必填等常见场景,优先用 truthProp、lieProp、makeUniteProp、makeRequiredProp。
  • 复杂类型建议单独定义类型,增强可读性。

常见问题与对比

  • 手写 props 对比:手写 props 易遗漏类型、required、default,且冗长。
  • 工厂函数优势:统一风格、类型安全、易维护。
  • 错误用法:引用类型默认值直接赋值会导致所有组件实例共享同一份数据。

总结

本工具集极大简化了 Vue3 组件属性声明,提升了开发效率和代码健壮性。建议在团队项目中推广使用,结合类型系统和最佳实践,打造高质量组件库。

ts
/**
 * 组件属性辅助
 * 🙌 能够使用更少的代码编写,有助于减少包体积
 */
import type { PropType } from 'vue';

export const unknownProp = null as unknown as PropType<unknown>;

export const numericProp = [Number, String];

export const truthProp = {
  type: Boolean,
  default: true as const,
};

export const lieProp = {
  type: Boolean,
  default: false as const,
};

export const makeRequiredProp = <T>(type: T) => {
  return { type, required: true as const };
};

export const makeNumericProp = <T>(defVal: T) => {
  return { type: numericProp, default: defVal };
};

export const makeStringProp = <T>(defVal: T) => {
  return { type: String as unknown as PropType<T>, default: defVal };
};

export const makeNumberProp = <T>(defVal: T) => {
  return { type: Number as unknown as PropType<T>, default: defVal };
};

export const makeArrayProp = <T>(defVal: T[]) => {
  return { type: Array as PropType<T[]>, default: () => defVal };
};

export const makeObjectProp = <T>(defVal: T) => {
  return { type: Object as PropType<T>, default: () => defVal };
};

export const makeFuncProp = <T>(defVal: T) => {
  return { type: Function as PropType<T>, default: defVal };
};

// 联和类型属性
export const makeUniteProp = <T, V>(type: T[], defVal: V) => {
  return { type, default: () => defVal };
};

import type { PropType, ExtractPropTypes } from 'vue';

export const props = {
  prop1: makeRequiredProp(String),
  prop2: makeArrayProp<string>(['a', 'b', 'c']),
  prop3: makeArrayProp<Record<string, unknown>[]>([]),
};

export type Props = ExtractPropTypes<typeof props>;