当前位置: 首页 > news >正文

Vue3核心语法进阶(Props)

 Vue3 中的 Props:父子组件的“传话筒”详解

接下来我们来聊聊 Vue3 中一个超级基础但又极其重要的概念——Props

如果你已经会用 Vue 写组件,那你一定用过 props。但你真的完全理解它吗?比如:

  • 为什么子组件不能直接改 props?
  • 什么时候该用 .sync 或 v-model
  • 如何给 props 加类型验证和默认值?

别急!今天我就用比喻,带你彻底搞懂 Vue3 的 Props,让你从“会用”变成“精通”!


什么是 Props?(一句话说清)

Props 就是父组件传给子组件的数据,相当于“父子之间的传话筒”。

想象一下:你爸(父组件)想让你(子组件)去超市买牛奶,他会告诉你:

  • 买什么?—— 牛奶
  • 买几瓶?—— 2 瓶
  • 什么牌子?—— 蒙牛

这些信息,就是 Props

<!-- 父组件 App.vue -->
<template><BuyMilk item="牛奶" count="2" brand="蒙牛" />
</template>
<!-- 子组件 BuyMilk.vue -->
<script setup>
// 接收父组件传来的数据
defineProps(['item', 'count', 'brand'])
</script><template><div>我要去买 {{ count }} 瓶 {{ brand }} {{ item }}!</div>
</template>

输出结果:我要去买 2 瓶 蒙牛 牛奶!

这就是 Props 的最基本用法:父传子,单向数据流


如何在 Vue3 中定义 Props?

Vue3 推荐使用 <script setup> + defineProps(),它是一个编译宏(不需要引入),写起来超简单!

方式一:数组写法(简单场景)

defineProps(['title', 'content', 'author'])

适合快速原型,但不推荐生产环境用,因为没类型、没默认值。

方式二:对象写法(推荐!)

defineProps({title: String,content: String,author: {type: String,default: '匿名用户'},likes: {type: Number,default: 0},isActive: {type: Boolean,default: true}
})

 这才是专业写法!支持类型、默认值、必填校验等。


讲解:Props 的“只读性”(为什么不能改?)

这是新手最容易踩的坑!

错误示范:

const props = defineProps(['count'])// 想要增加数量?
props.count++ //  警告!不要直接修改 props!

为什么不能改?

因为 Props 是“只读”的,就像你爸告诉你“买 2 瓶牛奶”,你不能偷偷改成“买 3 瓶”然后说“爸说的”!

Vue 的设计哲学是:数据流向要清晰。父组件传数据,子组件只能用,不能私自篡改。


那我想改怎么办?—— 用 emit 反向通知!

正确的做法是:子组件通过 emit 告诉父组件:“我想改数据”,然后由父组件决定是否修改。

示例:一个可增减的计数器

<!-- 子组件 Counter.vue -->
<script setup>
const props = defineProps(['count'])
const emit = defineEmits(['update:count'])const increase = () => {emit('update:count', props.count + 1)
}const decrease = () => {emit('update:count', props.count - 1)
}
</script><template><div><button @click="decrease">-</button>{{ count }}<button @click="increase">+</button></div>
</template>
<!-- 父组件 App.vue -->
<script setup>
import { ref } from 'vue'
import Counter from './Counter.vue'const myCount = ref(5)
</script><template><Counter :count="myCount" @update:count="myCount = $event"/>
</template>

看到了吗?子组件不能自己改,但可以“申请修改”,父组件同意了才算数!


语法糖:v-model 和 .sync 的秘密

上面的 @update:count 写起来有点啰嗦?Vue 提供了语法糖!

方式一:用 v-model(最常用)

<!-- 父组件 -->
<Counter v-model="myCount" /><!-- 等价于 -->
<Counter :count="myCount" @update:count="myCount = $event"
/>

注意:默认 v-model 对应的是 modelValueupdate:modelValue

如果你想用别的名字,比如 v-model:count

<!-- 子组件 -->
defineProps(['count'])
defineEmits(['update:count'])<!-- 父组件 -->
<Counter v-model:count="myCount" />

方式二:.sync 修饰符(Vue2 遗留,Vue3 仍支持)

<!-- 父组件 -->
<Counter :count.sync="myCount" /><!-- 等价于 -->
<Counter :count="myCount" @update:count="myCount = $event"
/>

推荐用 v-model,更现代、更清晰。


Props 高级用法:类型、默认值、验证

1. 支持复杂类型

defineProps({userInfo: {type: Object,default: () => ({ name: '张三', age: 20 })},tags: {type: Array,default: () => ['前端', 'Vue']}
})

 对象和数组的 default 必须是函数,否则会共享引用!

2. 自定义验证函数

defineProps({status: {type: String,validator(value) {// 只允许这几个值return ['active', 'inactive', 'pending'].includes(value)}}
})

传错会直接在控制台报错,开发时非常有用!

3. 必填项

defineProps({requiredId: {type: Number,required: true}
})

如果父组件没传,Vue 会警告你。


常见问题 & 最佳实践

Q1:Props 是响应式的吗?

是的! 只要父组件的数据变了,子组件的 props 会自动更新。

但记住:不要在子组件中直接修改它

Q2:我可以给 Props 加 ref 吗?

不要这么做!比如:

const myProp = ref(props.count) // 错误!断开了响应式连接

如果你需要基于 props 做计算,用 computed

import { computed } from 'vue'
const doubleCount = computed(() => props.count * 2)

最佳实践总结

建议说明
用对象形式定义 Props支持类型、默认值、验证
对象/数组 default 写成函数避免引用共享
不要直接修改 Props用 emit 通知父组件
复杂逻辑用 computed 或 watch保持响应式
用 v-model 简化双向绑定代码更简洁

总结:Props 核心要点

概念说明
作用父组件向子组件传递数据
特性单向数据流、只读
修改方式子组件 emit,父组件修改
语法糖v-model.sync 简化写法
安全支持类型、默认值、自定义验证

最后一句话

Props 是组件通信的“高速公路”,但它是单行道——数据只能从父到子。

想要“反向开车”?请走 emit 的“匝道”,由父组件决定是否放行!

掌握好 Props,你的组件才能既灵活安全

http://www.dtcms.com/a/315716.html

相关文章:

  • C语言:选择排序算法深度剖析!
  • nodejs 编码初体验
  • JAVA无人共享球杆柜系统球杆柜租赁系统源码支持微信小程序
  • 嵌入式硬件中运放的基本控制原理
  • 基于k8s环境下的pulsar常用命令(上)
  • 达梦分布式集群DPC_分布式任务执行拆分流程_yxy
  • 安全测绘之敏感网络资产排查指南
  • 在Linux上部署RabbitMQ、Redis、ElasticSearch
  • Taro Hooks 完整分类详解
  • 深度解析随机森林 API:参数奥秘与调优指南
  • 在AI时代,如何制定有效的职业规划?AI时代职业规划+AI产品经理角色
  • 【学习笔记】NTP时间同步验证
  • Kali Linux 2025.2基于MITRE ATTCK框架
  • DPU(数据处理单元)架构中,SoC(系统级芯片)与FPGA(现场可编程门阵列)之间的数据交互
  • 山东移动e企组网技术分析:底层架构与实现方式
  • 第12届蓝桥杯Scratch_选拔赛_初级组_真题2020年11月21日
  • SpringBoot3.x入门到精通系列:4.2 整合 Kafka 详解
  • Linux第十二讲:线程概念与控制
  • 前端保持和服务器时间同步的方法【使用vue3举例】
  • Qt 音频播放全攻略:常用函数、实战示例与资源获取
  • 升级 Elasticsearch 到新的 AWS Java SDK
  • 基于LDA主题的网络舆情与情感分析——以云南某景区话题为例
  • 8.5 CSS3多列布局
  • 继承知识总结
  • 【AI】提示词与自然语言处理:从NLP视角看提示词的作用机制
  • 【Lua】题目小练8
  • TrackVLA——开放世界下的四足具身视觉跟踪EVT(智能跟随):集目标识别与轨迹规划为一体的VLA,不怕高动态与遮挡
  • JavaWeb02——基础标签及样式(黑马视频笔记)
  • 扩展欧拉定理以及练习题
  • 嵌入式 - 数据结构:循环链表和内核链表