Vue3 用对 defineProps,写出优雅组件

564 阅读2分钟

前言

Vue3 的 Composition API 让开发者能够更灵活地组织逻辑,但很多人在使用 defineProps 时,还停留在 Vue2 的思维模式。这篇文章将带你了解如何正确使用 defineProps,写出专业、高效的 Vue3 组件。

图片

一、defineProps 的三种正确写法

(一)声明式类型推导(推荐)

这是 TypeScript 驱动的写法,无需运行时校验:

interface Props {
  title: string;
  count?: number;
}

const props = defineProps<Props>();

这种方式能自动获得类型推导,与 withDefaults 配合还可补充默认值。

(二)运行时代码校验(Options 式)

适合 JS 项目:

const props = defineProps({
  title: {
    type: String,
    required: true
  },
  count: {
    type: Number,
    default: 0
  }
});

保留 Vue2 的校验逻辑,但类型推导不如泛型直观。

(三)与 withDefaults 配合

这是实战中最常见的写法:

const props = withDefaults(defineProps<{
  title?: string;
  count?: number;
}>(), {
  title: '默认标题',
  count: 1
});

既获得类型推导,又可写默认值,简洁易维护。

二、高发误区及解决方法

(一)直接解构导致响应性丢失

错误写法:

const { title, count } = defineProps<{ title: string; count: number }>();

应改为使用 toRefs

const props = defineProps<{ title: string; count: number }>();
const { title, count } = toRefs(props);

这样可确保响应性。

(二)类型和默认值重复声明

在 TS 项目中,避免以下写法:

const props = defineProps({
  title: {
    type: String as PropType<string>,
    default: 'Hello'
  }
});

建议用泛型 + withDefaults,让 IDE 自动推导类型。

(三)未区分开发期类型检查与运行时校验

Vue3 的 Props 有 TypeScript 模式和 Options 模式。推荐生产环境靠 TypeScript 检查,提高性能。

三、defineProps 的进阶技巧

(一)使用类型别名

type Size = 'sm' | 'md' | 'lg';

withDefaults(defineProps<{
  size?: Size;
}>(), {
  size: 'md'
});

可让 props.size 具备完整类型提示。

(二)配合 defineEmits

const emit = defineEmits<{
  (e: 'submit', value: number): void;
  (e: 'cancel'): void;
}>();

让组件的输入输出都具备契约,便于 IDE 识别。

(三)确保类型推导

正确写法能让 IDE 在 <MyComponent :title="xx" /> 中提供类型提示。保持结构清晰是关键。

四、总结

  • • 避免不加泛型、直接解构、类型+default 双声明等错误。
  • • 推荐采用 defineProps<T>() + withDefaults() 写法。

正确的组件开发应做到

  • • 使用泛型 + withDefaults
  • • 保持 props 和 emits 的契约完整
  • • 清晰的类型提示和响应性解构