Skip to content
On this page

props — 父传子的"快递通道"

props 是父组件向子组件传递数据的机制,单向:父传子,子不能直接改。

父组件(有数据)

  │  props(单向)

子组件(接收数据,用在自己的模板里)

最简单的例子

父组件

vue
<template>
  <Child title="来自父组件的数据" />
</template>
<script>
import Child from './Child.vue'
export default {
  components: { Child }
}
</script>

子组件(Child.vue)

vue
<template>
  <p>父组件说的是:{{ title }}</p>
</template>
<script>
export default {
  props: ['title']
}
</script>

动态绑定 — 传变量而不是固定值

传变量时加冒号:

vue
<Child :title="parentMsg" />
写法传给子组件的
title="hello"字符串 "hello"
:title="hello"变量 hello 的值
:title="'hello'"字符串 "hello"(表达式)

加了冒号,等号后面的是 JavaScript 表达式,不是字符串。

单向数据流

props 是单向的,子不能直接改父传过来的值:

javascript
// ❌ 错误
this.title = '新标题'      // 会导致 Vue 报错

子组件确实需要改时:

  1. 把 prop 赋给本地 data(子组件内部自己用)
  2. 通过事件通知父组件改

传递多种数据类型

规则:传非字符串类型必须加冒号 :

数字

vue
<Child :age="25" />           <!-- ✅ 传数字 -->
<Child age="25" />            <!-- ❌ 传字符串 "25" -->

数组

vue
<Child :names="['张三', '李四', '王五']" />

对象

vue
<Child :user="userInfo" />

布尔值

vue
<Child :is-admin="true" />

Props 校验

给 prop 加上类型、必填、默认值等规则,让组件更健壮。

从简单到完整

javascript
// 第 1 级:只声明名字
props: ['title']

// 第 2 级:指定类型
props: {
  title: String
}

// 第 3 级:加更多规则
props: {
  title: {
    type: String,
    required: true,
    default: '默认标题'
  }
}

完整示例

javascript
props: {
  title: {
    type: String,
    required: true
  },
  age: {
    type: Number,
    default: 18
  },
  tags: {
    type: Array,
    default() {              // ⚠️ 对象/数组必须用函数返回
      return []
    }
  },
  status: {
    type: String,
    validator(value) {
      return ['active', 'inactive'].includes(value)
    }
  }
}
选项作用
type期望的类型:String, Number, Boolean, Array, Object, Date, Function
required是否必传
default默认值(对象/数组必须用函数返回)
validator自定义校验函数,返回 true 通过

支持多种类型

javascript
width: {
  type: [Number, String],
  default: 100
}

类型校验

当 prop 类型不对时,控制台会打印 warning(不是 error,页面仍能运行):

[Vue warn]: Invalid prop: type check failed for prop "age".
Expected Number, got String with value "25".

💡 Tip:type 校验只在开发环境生效,不影响生产性能。

新手常见问题

Q:我的 prop 传了但子组件拿不到?

  • 子组件有没有在 props 里声明
  • 父组件传的时候有没有写冒号
  • prop 名字拼写是否一致

Q:prop 名字在父模板里怎么写?

  • 父模板用小写横杠:my-title
  • 子组件 JS 用驼峰:myTitle

Q:为什么对象/数组的 default 必须是函数?

  • 确保每个组件实例拿到的是独立副本,而不是共享同一个引用