vue中的props详解

一、props 的作用与设计目标

props 是父组件向子组件传递数据的唯一官方通道,其核心设计原则是:

  • 单向数据流:父 → 子

  • 子组件不得直接修改 props

  • props 主要用于数据展示和配置,而非业务状态管理

典型使用场景:

  • 表单组件接收初始值

  • 列表组件接收数据源

  • 通用组件接收配置项(如 size、type、disabled)


二、props 的两种定义方式(Vue 3)

1️⃣ 数组形式(不推荐在生产中使用)

javascript 复制代码
export default {
  props: ['title', 'count']
}

特点:

  • 无类型校验

  • 无默认值

  • 仅适合 demo 或极简组件


2️⃣ 对象形式(推荐)

javascript 复制代码
export default {
  props: {
    title: String,
    count: Number
  }
}

这是最常用、最安全的方式。


三、完整 props 定义(工程级写法)

javascript 复制代码
export default {
  props: {
    title: {
      type: String,
      required: true
    },
    count: {
      type: Number,
      default: 0
    },
    list: {
      type: Array,
      default: () => []
    },
    user: {
      type: Object,
      default: () => ({})
    },
    status: {
      type: String,
      validator(value) {
        return ['success', 'error', 'warning'].includes(value)
      }
    }
  }
}

关键字段说明

字段 说明
type 类型校验
required 是否必传
default 默认值
validator 自定义校验

四、支持的 type 类型

复制代码
javascript 复制代码
String
Number
Boolean
Array
Object
Date
Function
Symbol

多类型支持

javascript 复制代码
props: { id: [String, Number] }

五、default 的正确写法(高频坑点)

❌ 错误写法(引用类型)

javascript 复制代码
default: []
default: {}

✅ 正确写法

javascript 复制代码
default: () => []
default: () => ({})

原因:

  • 防止多个组件实例共享同一引用对象

六、父组件如何传递 props

1️⃣ 静态传值

javascript 复制代码
<Child title="hello" />

2️⃣ 动态绑定(最常用)

javascript 复制代码
<Child :count="num" />

3️⃣ 对象展开(批量传递)

html 复制代码
<Child v-bind="userInfo" />
javascript 复制代码
const userInfo = {
  name: 'Tom',
  age: 18
}

七、子组件中使用 props(Vue 3)

1️⃣ Options API

javascript 复制代码
export default {
  props: {
    title: String
  },
  mounted() {
    console.log(this.title)
  }
}

2️⃣ Composition API(推荐)

javascript 复制代码
<script setup>
const props = defineProps({
  title: String,
  count: Number
})
</script>

也可以解构(注意响应性):

javascript 复制代码
const { title } = defineProps({
  title: String
})

⚠ 解构后不是响应式(除非使用 toRefs

javascript 复制代码
import { toRefs } from 'vue'
const props = defineProps({ title: String })
const { title } = toRefs(props)

八、props 是只读的(非常重要)

❌ 错误:直接修改 props

javascript 复制代码
props.count++

Vue 会警告:

Avoid mutating a prop directly


✅ 正确方式 1:使用本地状态

javascript 复制代码
const localCount = ref(props.count)

✅ 正确方式 2:通过事件通知父组件

javascript 复制代码
<Child :count="count" @update="count++" />

九、props 与 v-model(Vue 3 本质)

html 复制代码
<Child v-model="value" />

等价于:

html 复制代码
<Child :modelValue="value" @update:modelValue="($event)=>(value = $event)" />

子组件:

javascript 复制代码
const props = defineProps({
  modelValue: String
})

const emit = defineEmits(['update:modelValue'])

emit('update:modelValue', newValue)

十、props 的响应式特性

  • 父组件数据变化 → 子组件 props 自动更新

  • props 本身是 浅只读响应式

  • 引用类型内部属性可变,但不建议直接改

javascript 复制代码
props.user.name = 'Jack' // 不推荐,破坏数据流

十一、props 常见错误总结

错误 说明
修改 props 破坏单向数据流
default 使用对象 引用共享
解构 props 丢响应式 需要 toRefs
props 承担业务状态 应使用 state / store
传值与接收命名不一致 kebab-case / camelCase

十二、最佳实践建议(非常重要)

  1. props 只负责展示和配置

  2. 复杂交互通过 emit / v-model

  3. 引用类型 default 必须是函数

  4. 对外组件必须写完整 props 校验

  5. 不要在子组件修改父状态


十三、与 Vue 2 的主要区别(简述)

Vue 2 Vue 3
setup
defineProps
v-model value + input modelValue + update
TS 支持 一般 非常好
相关推荐
CHANG_THE_WORLD15 分钟前
PDF文档结构分析 一
前端·pdf
2601_9498333926 分钟前
flutter_for_openharmony口腔护理app实战+知识实现
android·javascript·flutter
东东51630 分钟前
果园预售系统的设计与实现spingboot+vue
前端·javascript·vue.js·spring boot·个人开发
rainbow688932 分钟前
Python学生管理系统:JSON持久化实战
java·前端·python
打小就很皮...35 分钟前
React Router 7 全局路由保护
前端·react.js·router
起风的蛋挞1 小时前
Matlab提示词语法
前端·javascript·matlab
有味道的男人1 小时前
1688获得商品类目调取商品榜单
java·前端·spring
txwtech1 小时前
第20篇esp32s3小智设置横屏
前端·html
Exquisite.1 小时前
企业高性能web服务器---Nginx(2)
服务器·前端·nginx
怪兽毕设1 小时前
基于SpringBoot的选课调查系统
java·vue.js·spring boot·后端·node.js·选课调查系统