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

理解 Props(父传子)和 Emit(子传父)的底层逻辑

在 Vue.js 开发中,构建应用的过程就像是搭建乐高积木。每个组件(积木块)都封装了自己的逻辑和样式,但为了让它们组合成一个功能完整的城堡,它们必须能够相互交流。

Vue 提倡一种非常严格且清晰的通信模式:数据向下流动 (Data Down),事件向上冒泡 (Events Up)。

这篇文章将带你深入理解 Props(父传子)和 Emit(子传父)的底层逻辑,掌握类型验证等进阶技巧,并解释为什么 Vue 如此坚持“单向数据流”。

  1. 核心概念:单向数据流 (One-Way Data Flow)

这是 Vue 组件通信的第一条铁律,也是理解 Vue 数据流向的基石。

1.1 数据的“所有权”

在组件树中,父组件 拥有数据的所有权。数据应当由父组件维护,并通过 Props 流向子组件。

父组件:数据的生产者和管理者。

子组件:数据的消费者。

1.2 禁止反向修改

子组件绝不应该直接修改收到的 Props。

如果你尝试在子组件里写 props.title = '新标题',Vue 会在控制台抛出黄色警告。

为什么?
如果子组件可以随意修改父组件的数据,当应用变复杂时(例如一个数据被多个子组件共享),你将无法追踪数据到底是在哪里被改变的。这会导致数据状态变得不可预测,引发难以调试的 Bug。

1.3 常见的“对象引用”陷阱

需要特别注意的是,在 JavaScript 中,对象和数组是按“引用”传递的。
虽然 Vue 禁止你重新赋值 prop(例如 props.user = {}),但它无法完全阻止你修改对象内部的属性(例如 props.user.name = 'Bob')。

⚠️ 警告:虽然这样做不会报错,但它依然违背了单向数据流原则。因为它会悄悄地改变父组件的状态,导致数据流向混乱。正确的做法始终是抛出事件 (emit),让父组件自己去修改。

  1. Props:父传子 (Data Down)

Props 是子组件接收外部数据的自定义属性/接口。

2.1 声明与传递

传递:父组件在模板中通过 :prop-name="value" 的形式传递动态数据,或者 prop-name="value" 传递静态字符串。

声明:子组件必须显式声明它接受哪些 props。

2.2 进阶:Props 验证 (Prop Validation)

在生产环境中,只声明 props 的名称是不够的。为了让组件更健壮,你需要为 props 指定类型、默认值甚至自定义验证函数。

props: {
// 基础类型检查
title: String,

// 必填项
price: {type: Number,required: true
},
http://www.baidu.com/link?url=UK9M1kYPo9nuMx1XaXo4eSngXtmNqc6y19LbKAnD_hBUHfvpc9EzrR5yzqyjJJbKRV8LOHFunrx_607wHRPVtK
// 带有默认值的对象
// 注意:对象或数组的默认值必须从一个工厂函数返回
config: {type: Object,default(rawProps) {return { theme: 'dark' }}
},// 自定义验证函数
status: {type: String,validator(value) {// 这个值必须匹配下列字符串中的一个return ['success', 'warning', 'danger'].includes(value)}
}

}

2.3 命名规范

在 JavaScript 中:使用 camelCase (驼峰命名法),例如 props.productName。

在 HTML 模板中:使用 kebab-case (短横线命名法),例如 。
Vue 会自动处理这两者之间的转换。

  1. Emit:子传父 (Events Up)

既然子组件不能修改 props,那它想改变数据怎么办?(比如用户点击了子组件里的“删除”按钮)。
它必须通知父组件,请求父组件来执行修改。

3.1 触发与监听

触发:子组件使用 $emit('event-name', payload) 抛出一个事件。payload 是可选的参数,用于传递具体的数据。

监听:父组件像监听原生 DOM 事件(如 click)一样,使用 @event-name="handler" 监听这个自定义事件。

3.2 声明 Emits (Vue 3 推荐)

为了让组件的行为更清晰,Vue 3 建议我们在组件中显式声明它会抛出哪些事件。这不仅有助于文档化,还能让 Vue 自动校验事件。

// 声明该组件会触发的事件
emits: ['add-to-cart', 'delete-item'],
// 或者对象语法进行验证
emits: {
'add-to-cart': (id) => {
if (id) return true; // 验证通过
console.warn('add-to-cart 事件缺少 id 参数');
return false;
}
}

  1. 实战案例:购物车计数器

我们将构建一个简单的父子组件系统,演示完整的交互流程。

父组件 (App):维护一个商品列表和总价。它是数据的“单一事实来源”。

子组件 (ProductItem):展示单个商品,并包含“加入购物车”按钮。它只负责展示和通知。

我们将代码逻辑拆解为三个部分:

4.1 子组件逻辑 (ProductItem)

子组件负责声明它需要什么数据 (props),验证这些数据,并在用户交互时发送通知 (emit)。

const ProductItem = {
// 1. 严格的 Props 声明
props: {
id: {
type: Number,
required: true
},
name: {
type: String,
required: true
},
price: {
type: Number,
required: true
}
},
// 2. 声明抛出的事件
emits: ['add-to-cart'],

// setup 函数的第二个参数 context 中包含 emit 方法
setup(props, { emit }) {const notifyParent = () => {// 核心:子组件不直接修改数据,而是发出通知// 我们把商品的 id 和 price 打包发给父组件// 这里的 { id: ..., price: ... } 就是 payloademit('add-to-cart', { id: props.id, price: props.price });};return { notifyParent };
},// 子组件模板
template: `<div class="product-item"><h3>{{ name }}</h3><p>单价: ¥{{ price }}</p><!-- 点击按钮,触发 emit --><button @click="notifyParent">加入购物车</button></div>
`

};

4.2 父组件逻辑 (App)

父组件负责持有真实的数据源,并定义处理函数来响应子组件的请求。

const { ref } = Vue;

const App = {
components: {
ProductItem // 注册子组件
},
setup() {
// 父组件拥有的数据 (Source of Truth)
const products = ref([
{ id: 1, name: '机械键盘', price: 399 },
{ id: 2, name: '无线鼠标', price: 129 },
{ id: 3, name: '显示器支架', price: 199 }
]);

    const totalPrice = ref(0);const lastAddedItem = ref('');// 处理函数:当接收到子组件的 'add-to-cart' 事件时执行// payload 参数就是子组件 emit 出来的那个对象const handleAddToCart = (payload) => {console.log(`收到通知,商品ID: ${payload.id}, 价格: ${payload.price}`);// 父组件执行修改数据的逻辑totalPrice.value += payload.price;lastAddedItem.value = `刚刚添加了 ID 为 ${payload.id} 的商品`;};return {products,totalPrice,lastAddedItem,handleAddToCart};
}

};

4.3 模板结合 (HTML Usage)

在 HTML 中,我们通过属性绑定 (😃 和事件监听 (@) 将两者连接起来。

http://www.baidu.com/link?url=9WkWJwt4mjF9CWZ9c3Z4YRR9Uy8feU7uJx5U5P0Zbij9tr_W-EvonnlBWdIIWrTA
<div class="header"><h2>商品列表</h2><div class="status-bar"><span class="total-price">购物车总额: ¥{{ totalPrice }}</span><span class="last-log" v-if="lastAddedItem">{{ lastAddedItem }}</span></div>
</div><!-- 核心交互:1. :name="item.name"        -> 数据向下传递 (Props)2. @add-to-cart="handle..." -> 事件向上传递 (Emit)注意:我们把 item.id 既作为 key 使用,也作为 prop 传给子组件
-->
<product-item v-for="item in products" :key="item.id":id="item.id":name="item.name":price="item.price"@add-to-cart="handleAddToCart"

 

https://weibo.com/ttarticle/p/show?id=2309405298433107034115
https://weibo.com/ttarticle/p/show?comment=1&id=2309405298433107034115
https://weibo.com/ttarticle/p/show?id=2309405298433224736947
https://weibo.com/ttarticle/p/show?comment=1&id=2309405298433224736947
https://weibo.com/ttarticle/p/show?id=2309405298433509949553
https://weibo.com/ttarticle/p/show?comment=1&id=2309405298433509949553
https://weibo.com/ttarticle/p/show?id=2309405298433652555890
https://weibo.com/ttarticle/p/show?comment=1&id=2309405298433652555890
https://weibo.com/ttarticle/p/show?id=2309405298433773928485
https://weibo.com/ttarticle/p/show?comment=1&id=2309405298433773928485
https://weibo.com/ttarticle/p/show?id=2309405298433908146394
https://weibo.com/ttarticle/p/show?comment=1&id=2309405298433908146394
https://weibo.com/ttarticle/p/show?id=2309405298434046820514
https://weibo.com/ttarticle/p/show?comment=1&id=2309405298434046820514
https://weibo.com/ttarticle/p/show?id=2309405298434206203970
https://weibo.com/ttarticle/p/show?comment=1&id=2309405298434206203970
https://weibo.com/ttarticle/p/show?id=2309405298457316556973
https://weibo.com/ttarticle/p/show?comment=1&id=2309405298457316556973
https://weibo.com/ttarticle/p/show?id=2309405298457425608756
https://weibo.com/ttarticle/p/show?comment=1&id=2309405298457425608756
https://weibo.com/ttarticle/p/show?id=2309405298457513689247
https://weibo.com/ttarticle/p/show?comment=1&id=2309405298457513689247
https://weibo.com/ttarticle/p/show?id=2309405298457618546739
https://weibo.com/ttarticle/p/show?comment=1&id=2309405298457618546739
https://weibo.com/ttarticle/p/show?id=2309405298457719210343
https://weibo.com/ttarticle/p/show?comment=1&id=2309405298457719210343
https://weibo.com/ttarticle/p/show?id=2309405298457853427724
https://weibo.com/ttarticle/p/show?comment=1&id=2309405298457853427724
https://weibo.com/ttarticle/p/show?id=2309405298458008879279
https://weibo.com/ttarticle/p/show?comment=1&id=2309405298458008879279
https://weibo.com/ttarticle/p/show?id=2309405298458185039886
https://weibo.com/ttarticle/p/show?comment=1&id=2309405298458185039886
https://weibo.com/ttarticle/p/show?id=2309405298458318995493
https://weibo.com/ttarticle/p/show?comment=1&id=2309405298458318995493
https://weibo.com/ttarticle/p/show?id=2309405298458436698286
https://weibo.com/ttarticle/p/show?comment=1&id=2309405298458436698286
https://weibo.com/ttarticle/p/show?id=2309405298458524516418
https://weibo.com/ttarticle/p/show?comment=1&id=2309405298458524516418
https://weibo.com/ttarticle/p/show?id=2309405298458608664585
https://weibo.com/ttarticle/p/show?comment=1&id=2309405298458608664585
https://weibo.com/ttarticle/p/show?id=2309405298458700677245
https://weibo.com/ttarticle/p/show?comment=1&id=2309405298458700677245
https://weibo.com/ttarticle/p/show?id=2309405298458771980319
https://weibo.com/ttarticle/p/show?comment=1&id=2309405298458771980319
https://weibo.com/ttarticle/p/show?id=2309405298458855866428
https://weibo.com/ttarticle/p/show?comment=1&id=2309405298458855866428
https://weibo.com/ttarticle/p/show?id=2309405298458964918455
https://weibo.com/ttarticle/p/show?comment=1&id=2309405298458964918455
https://weibo.com/ttarticle/p/show?id=2309405298459036483694
https://weibo.com/ttarticle/p/show?comment=1&id=2309405298459036483694
https://weibo.com/ttarticle/p/show?id=2309405298459103592459
https://weibo.com/ttarticle/p/show?comment=1&id=2309405298459103592459
https://weibo.com/ttarticle/p/show?id=2309405298459174895829
https://weibo.com/ttarticle/p/show?comment=1&id=2309405298459174895829
https://weibo.com/ttarticle/p/show?id=2309405298459304919081
https://weibo.com/ttarticle/p/show?comment=1&id=2309405298459304919081
https://weibo.com/ttarticle/p/show?id=2309405298459493662879
https://weibo.com/ttarticle/p/show?comment=1&id=2309405298459493662879
https://weibo.com/ttarticle/p/show?id=2309405298459606909097
https://weibo.com/ttarticle/p/show?comment=1&id=2309405298459606909097
https://weibo.com/ttarticle/p/show?id=2309405298459996979253
https://weibo.com/ttarticle/p/show?comment=1&id=2309405298459996979253
https://weibo.com/ttarticle/p/show?id=2309405298460496101464
https://weibo.com/ttarticle/p/show?comment=1&id=2309405298460496101464
https://weibo.com/ttarticle/p/show?id=2309405298460831383672
https://weibo.com/ttarticle/p/show?comment=1&id=2309405298460831383672
https://weibo.com/ttarticle/p/show?id=2309405298461498540222
https://weibo.com/ttarticle/p/show?comment=1&id=2309405298461498540222
https://weibo.com/ttarticle/p/show?id=2309405298461716381843
https://weibo.com/ttarticle/p/show?comment=1&id=2309405298461716381843
https://weibo.com/ttarticle/p/show?id=2309405298461779296296
https://weibo.com/ttarticle/p/show?comment=1&id=2309405298461779296296
https://weibo.com/ttarticle/p/show?id=2309405298461842210842
https://weibo.com/ttarticle/p/show?comment=1&id=2309405298461842210842
https://weibo.com/ttarticle/p/show?id=2309405298461901193526
https://weibo.com/ttarticle/p/show?comment=1&id=2309405298461901193526
https://weibo.com/ttarticle/p/show?id=2309405298461964108057
https://weibo.com/ttarticle/p/show?comment=1&id=2309405298461964108057
https://weibo.com/ttarticle/p/show?id=2309405298462027022480
https://weibo.com/ttarticle/p/show?comment=1&id=2309405298462027022480
https://weibo.com/ttarticle/p/show?id=2309405298462089936994
https://weibo.com/ttarticle/p/show?comment=1&id=2309405298462089936994
https://weibo.com/ttarticle/p/show?id=2309405298462152589352
https://weibo.com/ttarticle/p/show?comment=1&id=2309405298462152589352
https://weibo.com/ttarticle/p/show?id=2309405298462215503877
https://weibo.com/ttarticle/p/show?comment=1&id=2309405298462215503877
https://weibo.com/ttarticle/p/show?id=2309405298462278680957
https://weibo.com/ttarticle/p/show?comment=1&id=2309405298462278680957
https://weibo.com/ttarticle/p/show?id=2309405298462341333267
https://weibo.com/ttarticle/p/show?comment=1&id=2309405298462341333267
https://weibo.com/ttarticle/p/show?id=2309405298462404247654
https://weibo.com/ttarticle/p/show?comment=1&id=2309405298462404247654
https://weibo.com/ttarticle/p/show?id=2309405298462467424479
https://weibo.com/ttarticle/p/show?comment=1&id=2309405298462467424479
https://weibo.com/ttarticle/p/show?id=2309405298462530338930
https://weibo.com/ttarticle/p/show?comment=1&id=2309405298462530338930
https://weibo.com/ttarticle/p/show?id=2309405298462592991550
https://weibo.com/ttarticle/p/show?comment=1&id=2309405298462592991550
https://weibo.com/ttarticle/p/show?id=2309405298462656168096
https://weibo.com/ttarticle/p/show?comment=1&id=2309405298462656168096
https://weibo.com/ttarticle/p/show?id=2309405298462723014716
https://weibo.com/ttarticle/p/show?comment=1&id=2309405298462723014716
https://weibo.com/ttarticle/p/show?id=2309405298462786191407
https://weibo.com/ttarticle/p/show?comment=1&id=2309405298462786191407
https://weibo.com/ttarticle/p/show?id=2309405298462844649787
https://weibo.com/ttarticle/p/show?comment=1&id=2309405298462844649787
https://weibo.com/ttarticle/p/show?id=2309405298462907826321
https://weibo.com/ttarticle/p/show?comment=1&id=2309405298462907826321
https://weibo.com/ttarticle/p/show?id=2309405298462974672908
https://weibo.com/ttarticle/p/show?comment=1&id=2309405298462974672908
https://weibo.com/ttarticle/p/show?id=2309405298463037587478
https://weibo.com/ttarticle/p/show?comment=1&id=2309405298463037587478
https://weibo.com/ttarticle/p/show?id=2309405298463117279306
https://weibo.com/ttarticle/p/show?comment=1&id=2309405298463117279306
https://weibo.com/ttarticle/p/show?id=2309405298463184388157
https://weibo.com/ttarticle/p/show?comment=1&id=2309405298463184388157
https://weibo.com/ttarticle/p/show?id=2309405298463247564942
https://weibo.com/ttarticle/p/show?comment=1&id=2309405298463247564942
https://weibo.com/ttarticle/p/show?id=2309405298463310217322
https://weibo.com/ttarticle/p/show?comment=1&id=2309405298463310217322
https://weibo.com/ttarticle/p/show?id=2309405298463373394012
https://weibo.com/ttarticle/p/show?comment=1&id=2309405298463373394012
https://weibo.com/ttarticle/p/show?id=2309405298463436308539
https://weibo.com/ttarticle/p/show?comment=1&id=2309405298463436308539
https://weibo.com/ttarticle/p/show?id=2309405298463499223279
https://weibo.com/ttarticle/p/show?comment=1&id=2309405298463499223279
https://weibo.com/ttarticle/p/show?id=2309405298463570526284
https://weibo.com/ttarticle/p/show?comment=1&id=2309405298463570526284
https://weibo.com/ttarticle/p/show?id=2309405298463637635277
https://weibo.com/ttarticle/p/show?comment=1&id=2309405298463637635277
https://weibo.com/ttarticle/p/show?id=2309405298463725453405
https://weibo.com/ttarticle/p/show?comment=1&id=2309405298463725453405
https://weibo.com/ttarticle/p/show?id=2309405298463817728185
https://weibo.com/ttarticle/p/show?comment=1&id=2309405298463817728185
https://weibo.com/ttarticle/p/show?id=2309405298463889293438
https://weibo.com/ttarticle/p/show?comment=1&id=2309405298463889293438
https://weibo.com/ttarticle/p/show?id=2309405298463972917332
https://weibo.com/ttarticle/p/show?comment=1&id=2309405298463972917332
https://weibo.com/ttarticle/p/show?id=2309405298464107135105
https://weibo.com/ttarticle/p/show?comment=1&id=2309405298464107135105
https://weibo.com/ttarticle/p/show?id=2309405298464187088959
https://weibo.com/ttarticle/p/show?comment=1&id=2309405298464187088959
https://weibo.com/ttarticle/p/show?id=2309405298464291684520
https://weibo.com/ttarticle/p/show?comment=1&id=2309405298464291684520
https://weibo.com/ttarticle/p/show?id=2309405298464379764814
https://weibo.com/ttarticle/p/show?comment=1&id=2309405298464379764814
https://weibo.com/ttarticle/p/show?id=2309405298464446873636
https://weibo.com/ttarticle/p/show?comment=1&id=2309405298464446873636
https://weibo.com/ttarticle/p/show?id=2309405298464522633237
https://weibo.com/ttarticle/p/show?comment=1&id=2309405298464522633237
https://weibo.com/ttarticle/p/show?id=2309405298464669433983
https://weibo.com/ttarticle/p/show?comment=1&id=2309405298464669433983
https://weibo.com/ttarticle/p/show?id=2309405298464753057808
https://weibo.com/ttarticle/p/show?comment=1&id=2309405298464753057808
https://weibo.com/ttarticle/p/show?id=2309405298464824623206
https://weibo.com/ttarticle/p/show?comment=1&id=2309405298464824623206
https://weibo.com/ttarticle/p/show?id=2309405298465164099706
https://weibo.com/ttarticle/p/show?comment=1&id=2309405298465164099706
https://weibo.com/ttarticle/p/show?id=2309405298465227014270
https://weibo.com/ttarticle/p/show?comment=1&id=2309405298465227014270
https://weibo.com/ttarticle/p/show?id=2309405298465415757862
https://weibo.com/ttarticle/p/show?comment=1&id=2309405298465415757862
https://weibo.com/ttarticle/p/show?id=2309405298465533198374
https://weibo.com/ttarticle/p/show?comment=1&id=2309405298465533198374
https://weibo.com/ttarticle/p/show?id=2309405298465726398585
https://weibo.com/ttarticle/p/show?comment=1&id=2309405298465726398585
https://weibo.com/ttarticle/p/show?id=2309405298465818411073
https://weibo.com/ttarticle/p/show?comment=1&id=2309405298465818411073
https://weibo.com/ttarticle/p/show?id=2309405298465915142318
https://weibo.com/ttarticle/p/show?comment=1&id=2309405298465915142318
https://weibo.com/ttarticle/p/show?id=2309405298466099691694
https://weibo.com/ttarticle/p/show?comment=1&id=2309405298466099691694
https://weibo.com/ttarticle/p/show?id=2309405298466217132174
https://weibo.com/ttarticle/p/show?comment=1&id=2309405298466217132174
https://weibo.com/ttarticle/p/show?id=2309405298466321727578
https://weibo.com/ttarticle/p/show?comment=1&id=2309405298466321727578

http://www.jsqmd.com/news/815482/

相关文章:

  • 新手必看:用Silvaco TCAD跑通你的第一个电阻仿真(附完整代码与TonyPlot出图指南)
  • 三态电路:数字电路中的高阻态原理与应用实践
  • Cursor免费VIP配置工具完全指南:如何优化你的AI编程助手体验
  • DialOp:面向协作决策的对话环境设计与智能体开发实践
  • MediaPipe手势识别实战:用Python+OpenCV快速搭建一个手势控制PPT翻页器
  • 昆仑芯天池256卡超节点上个月点亮,将于6月正式上市
  • 百度网盘Mac版终极加速指南:三步破解限速,免费享受SVIP极速下载
  • TuxGuitar免费吉他谱编辑器:5分钟快速上手指南
  • 终极B站视频下载教程:3分钟学会免费下载4K高清内容
  • 酷跑咔叮为何选择基于 LikeShop 搭建自己的私域数字化平台?——从“租用 SaaS”到“拥有完整卡丁车业务系统”的一次数字化升级实践
  • 别再死记硬背公式了!用Python的NumPy库5分钟搞定逆矩阵、伴随矩阵计算
  • 基于Firecracker的微虚拟机沙箱vmsan:兼顾安全隔离与毫秒级启动
  • 斗鱼股权曝光:腾讯持股40% 陈少杰持股18%
  • 基于Feast构建实时特征存储:架构解析与生产实践指南
  • SQL Server 2022 保姆级安装指南:从下载到配置的完整图解
  • 让STM32的printf也能“上网”:串口重定向后,如何用VS Code+PlatformIO实现无线调试打印?
  • Next.js身份验证实战:基于Auth.js的认证系统设计与实现
  • 响应式编程-Flux 背压机制与操作符链式调用源码剖析
  • Garmin健康数据自动化同步与AI集成实战指南
  • 【RT-DETR实战】030、注意力机制改进:引入SimAM,EMA等无参注意力
  • 终极React Markdown渲染指南:安全高效构建现代内容应用
  • Windows 10/11下用Hydra v9.1测试SSH弱口令?手把手教你搭建本地靶场(附字典避坑指南)
  • 专业PDF文档处理实战指南:掌握高效管理技巧
  • Sora 2生成素材在Final Cut中丢失元数据?揭秘Apple ProRes+JSON Schema双嵌入方案(附可直接导入的XMP模板)
  • 2026临夏市黄金回收白银回收铂金回收店铺哪家好 靠谱门店推荐及联系方式_转自TXT - 盛世金银回收
  • 终极Windows APK安装指南:5分钟快速上手安卓应用安装
  • 如何快速掌握HTTrack网站镜像工具:完整实战指南
  • Windows系统优化终极指南:使用Chris Titus Tech WinUtil一键搞定所有设置
  • DRAM缓存ECC技术:混合方案与直接比较优化
  • 彩云之南常驻春光,昆明大理丽江一路皆风景