Vue3 Props 属性

一、Props 是什么?

想象一下,你正在组装一个乐高机器人。机器人的头部、手臂、腿部都是独立的组件。为了让手臂知道它应该连接在身体的哪个位置,你需要给它一个"连接点"的指令。在 Vue3 中,Props 就是这个"指令",它是父组件向子组件传递数据的一种方式

简单来说:Props 是组件的自定义属性,父组件通过它来给子组件"喂"数据。

二、Props 的核心作用

Props 主要解决组件间的通信问题,具体作用如下:

  • 数据传递:父组件可以把数据(字符串、数字、数组、对象等)传递给子组件。
  • 配置组件:通过传递不同的 Props 值,可以让同一个子组件呈现不同的状态或行为,实现复用。
  • 单向数据流:数据只能从父组件流向子组件,这保证了数据变化的可预测性,便于调试。
  • 类型检查 :Vue3 的 Composition API 和 `<script setup>` 语法支持对 Props 进行类型定义,提升代码健壮性。

三、Props 的属性(Props 选项)

在 Vue3 中,定义 Props 时可以配置多种属性来约束和描述数据。以下是常用的 Props 属性:

  • type :指定 Prop 的数据类型,如 StringNumberBooleanArrayObjectDateFunctionSymbol,或自定义构造函数。
  • required:布尔值,表示该 Prop 是否为必传项。
  • default:指定 Prop 的默认值。可以是固定值,也可以是一个返回默认值的函数。
  • validator:自定义验证函数,用于校验传入的 Prop 值是否有效。

四、如何接受和使用 Props(代码案例)

1. 使用 `<script setup>` 语法(推荐)

这是 Vue3 组合式 API 中最简洁的写法。

提示:带有define开头的都是宏声明属性,不需要引入

html 复制代码
<!-- 子组件 ChildComponent.vue -->
<template>
  <div>
    <h3>子组件</h3>
    <p>接收到的标题:{{ title }}</p>
    <p>接收到的数量:{{ count }}</p>
    <p>用户信息:{{ user.name }} ({{ user.age }}岁)</p>
    <ul>
      <li v-for="item in items" :key="item">{{ item }}</li>
    </ul>
  </div>
</template>

<script setup>
// 使用 defineProps 宏来声明 Props
const props = defineProps({
  // 类型 + 必填
  title: {
    type: String,
    required: true
  },
  // 类型 + 默认值
  count: {
    type: Number,
    default: 0
  },
  // 对象类型 + 默认值函数
  user: {
    type: Object,
    default: () => ({ name: '匿名', age: 18 })
  },
  // 数组类型
  items: {
    type: Array,
    default: () => []
  },
  // 自定义验证器
  score: {
    type: Number,
    validator: (value) => {
      return value >= 0 && value <= 100;
    }
  }
});

// 在模板或逻辑中直接使用 props.title, props.count 等
console.log(props.title);
</script>
html 复制代码
<!-- 父组件 ParentComponent.vue -->
<template>
  <div>
    <h2>父组件</h2>
    <ChildComponent
      title="用户列表"
      :count="userCount"
      :user="currentUser"
      :items="todoList"
      :score="85"
    />
  </div>
</template>

<script setup>
import { ref } from 'vue';
import ChildComponent from './ChildComponent.vue';

const userCount = ref(5);
const currentUser = ref({ name: '张三', age: 25 });
const todoList = ref(['学习 Vue', '写代码', '阅读文档']);
</script>

补充:数组形式的 defineProps

除了使用对象形式 定义 Props 外,defineProps 也支持简单的数组形式。

defineProps 是有返回值的

javascript 复制代码
<script setup>
// 数组形式:仅声明属性名,所有属性类型默认为任意类型
const props = defineProps(['title', 'count', 'user']);

// 在模板中可以直接使用
console.log(props.title); // 来自父组件传递的值
console.log(props.count);
</script>
  • 推荐做法: 在正式项目中,为了更好的代码健壮性和开发体验,建议使用对象形式(如上方示例)或 TypeScript 泛型形式来定义 Props,以便获得完整的类型检查和 IDE 提示。

2. 使用 TypeScript 与类型标注

结合 TypeScript 可以获得更完善的类型提示和检查。

typescript 复制代码
<!-- 子组件 ChildComponent.vue -->
<template>
  <!-- 同上 -->
</template>

<script setup lang="ts">
interface User {
  name: string;
  age: number;
}

// 使用接口定义 Props 类型
interface Props {
  title: string;
  count?: number; // 可选
  user: User;
  items: string[];
  score?: number;
}

// 使用泛型 defineProps
const props = defineProps<Props>();

// 或者提供默认值(需要 withDefaults 辅助函数)
const propsWithDefaults = withDefaults(defineProps<Props>(), {
  count: 0,
  user: () => ({ name: '匿名', age: 18 }),
  items: () => [],
});
</script>

3. 使用选项式 API

这是 Vue2 风格的写法,在 Vue3 中仍然兼容。

javascript 复制代码
<!-- 子组件 ChildComponent.vue -->
<template>
  <!-- 同上 -->
</template>

<script>
export default {
  name: 'ChildComponent',
  // 在 props 选项中声明
  props: {
    title: {
      type: String,
      required: true
    },
    count: {
      type: Number,
      default: 0
    },
    user: {
      type: Object,
      default: () => ({ name: '匿名', age: 18 })
    },
    items: {
      type: Array,
      default: () => []
    },
    score: {
      type: Number,
      validator: function(value) {
        return value >= 0 && value <= 100;
      }
    }
  },
  setup(props) {
    // 在 setup 函数中访问 props
    console.log(props.title);
    return {};
  }
}
</script>

五、使用 Props 的注意事项

  • 单向数据流 :不要在子组件内部直接修改 Props(Vue 会警告)。如果需要修改,应该在子组件内定义一个新的响应式数据(如使用 refcomputed)来接收 Prop 的初始值。
  • Prop 命名 :在 JavaScript 中使用 camelCase(如 userName),在模板中建议使用 kebab-case(如 user-name)。
  • 动态与静态传递 :使用 : 绑定是动态传递(响应式),不使用 : 是静态字符串传递。
  • 复杂对象默认值 :对象或数组的 default 必须是一个工厂函数返回新对象,避免多个组件实例共享同一引用。
相关推荐
醉城夜风~2 小时前
CSS元素显示模式(display)
前端·css
AI大模型-小华3 小时前
Codex 三方充值快速入门指南
java·前端·数据库·chatgpt·ai编程·codex·chatgpt pro
做前端的娜娜子5 小时前
同一链接实现 PC Web 与移动 H5 自适应
前端·掘金·金石计划
小帅不太帅5 小时前
架构没变、规模没变,DeepSeek V4 Flash 正式版凭什么暴涨 47 分?
前端·aigc·deepseek
jarvisuni5 小时前
DeepSeekFlash前端依旧拉垮,而且变慢了很多!
前端·javascript·算法
卷福同学7 小时前
AI编程出海第二步:验证关键词能否做站
前端·人工智能·后端
赵庆明老师7 小时前
Vben精讲:21-详解web-antd:tsconfig.json
前端·json·vim
wc887 小时前
微软EDGE浏览器功能学习
前端·学习·edge