☰
Vue3组件基础实战:Props、Emit、Slot综合案例
2026/9/30 8:58:09 网站建设 项目流程

Vue3组件基础实战:Props、Emit、Slot综合案例

  • Vue3组件基础实战:Props、Emit、Slot综合案例
    • 1 前言
    • 2 Vue组件通信基础知识点
      • 2.1 Props(父向子传数据)
      • 2.2 emit(子向父发送事件)
      • 2.3 Slot插槽
      • 2.4 深层组件通信
    • 3 实战需求
    • 4 完整代码实现
      • 4.1 子组件 CardItem.vue(默认插槽)
      • 4.2 子组件 BtnBox.vue(具名插槽)
      • 4.3 父组件 Parent.vue
    • 5 代码逻辑解析
    • 6 优缺点分析
      • 优点
      • 不足
      • 优化建议
    • 7 拓展:不同场景通信选型总结
    • 8 总结

Vue3组件基础实战:Props、Emit、Slot综合案例

1 前言

组件化是Vue框架的核心思想,把页面拆分成多个独立可复用的UI模块。组件之间需要进行数据通信,本文结合实战演示props父传子、emit子传父、slot插槽的使用,实现1个父组件,2个子组件综合案例,同时拓展深层组件通信方案。

2 Vue组件通信基础知识点

2.1 Props(父向子传数据)

父组件通过标签属性传递数据,子组件使用defineProps接收。

单向数据流原则:props为只读,子组件禁止直接修改props数据。

2.2 emit(子向父发送事件)

子组件使用defineEmits声明自定义事件,调用emit()触发事件并携带参数;父组件通过@事件名监听,接收子组件传回的数据。

2.3 Slot插槽

插槽实现父组件向子组件传入自定义模板内容。

  • 默认插槽:直接写在子组件标签内部;
  • 具名插槽:通过name命名,父组件使用#插槽名使用;
  • 插槽支持设置后备默认内容。

2.4 深层组件通信

当组件嵌套层级很深,props逐层传递会产生props透传问题:

  1. provide / inject:祖先组件向后代组件直接注入数据,跳过中间组件;
  2. Pinia:全局状态管理库,适合多组件、跨路由共享全局业务数据。

3 实战需求

  1. 创建父组件Parent.vue,两个子组件CardItem.vue、BtnBox.vue;
  2. 父组件使用props向两个子组件传递数据;
  3. 子组件通过emit事件,把操作结果回传给父组件;
  4. 使用默认插槽、具名插槽实现子组件内容自定义。

4 完整代码实现

4.1 子组件 CardItem.vue(默认插槽)

<template> <div class="card"> <!-- 默认插槽,父组件传入自定义内容 --> <slot></slot> <p>收到父组件数据:{{ info }}</p> <button @click="handleClick">提交反馈</button> </div> </template> <script setup> // props接收父组件传入数据 const props = defineProps({ info: { type: String, required: true } }) // 声明自定义事件 const emit = defineEmits(['sendResult']) // 点击按钮触发事件,把数据回传给父组件 const handleClick = () => { emit('sendResult', `【卡片组件】操作完成,收到内容:${props.info}`) } </script> <style scoped> .card { border: 1px solid #ccc; padding: 16px; margin:10px 0; border-radius:6px; } </style>

4.2 子组件 BtnBox.vue(具名插槽)

<template> <div class="btn-box"> <p>编号:{{ id }}</p> <!-- 具名插槽 --> <slot name="btn"></slot> </div> </template> <script setup> const props = defineProps({ id: Number }) const emit = defineEmits(['onOperate']) const handleClick = () => { emit('onOperate', `【按钮组件】操作完成,编号:${props.id}`) } </script> <style scoped> .btn-box { border:1px solid #42b983; padding:16px; margin:10px 0; border-radius:6px; } </style>

4.3 父组件 Parent.vue

<template> <h2>父组件</h2> <!-- CardItem:props传值,监听子组件sendResult事件,默认插槽填充内容 --> <CardItem :info="parentMsg" @sendResult="handleReceive"> <h3>父组件通过插槽自定义标题</h3> </CardItem> <!-- BtnBox:props传递id,#btn具名插槽,事件由子组件内部emit触发 --> <BtnBox :id="num" @onOperate="handleOperate"> <template #btn> <button>点击操作</button> </template> </BtnBox> <p style="margin-top:20px;">父组件接收子组件反馈:{{ res }}</p> </template> <script setup> import { ref } from 'vue' import CardItem from './CardItem.vue' import BtnBox from './BtnBox.vue' // 父组件状态数据 const parentMsg = ref('父组件传递的文本') const num = ref(1001) const res = ref('') // 接收CardItem回传的数据 const handleReceive = (val) => { res.value = val } // 接收BtnBox回传的数据 const handleOperate = (val) => { res.value = val } </script>

5 代码逻辑解析

  1. props 父传子:父组件通过:info、:id把数据下发,子组件defineProps接收并做类型校验,数据单向流动。
  2. emit 子传父:子组件触发自定义事件携带参数,父组件监听事件拿到子组件操作结果。
  3. 插槽使用
    • CardItem 使用默认插槽,父组件标签中间书写内容,渲染到子组件 slot 位置;
    • BtnBox 使用具名插槽name="btn",父组件使用#btn传入自定义按钮模板。
  4. 严格遵守单向数据流,子组件只读取 props,不在子组件内部直接修改 props。

6 优缺点分析

优点

  1. 技术栈现代:使用 Vue3 +<script setup>语法,紧跟当前主流开发模式。
  2. 结构清晰:目录导航完善,从概念到实战再到拓展,层次分明。
  3. 代码规范:代码块展示美观,变量命名语义化强,注释详细。
  4. 总结到位:提供了通信方式选型表,便于查阅记忆。

不足

  1. 缺视觉反馈:本文没有提供组件运行后的界面截图,读者无法直观看到插槽填充或样式渲染效果。
  2. 早期代码存在逻辑瑕疵:旧版本父组件中对同一个事件进行了双重绑定(组件 emit + 原生 click),容易造成逻辑混乱、重复触发的问题,现已修正。
  3. 非核心内容干扰:如果附带 CSDN 平台发布教程,会偏离技术分享主题,因此本文移除了发布相关操作内容。

优化建议

  1. 补充运行结果图:可以在本节之前,添加浏览器中的实际渲染效果图,标注 Props 传入文字、Slot 插入内容位置,增强直观性。
  2. 保证事件逻辑单一来源:事件触发逻辑统一放在子组件内部,父组件仅负责监听事件,避免多重绑定。
  3. 增加数据流示意图:添加箭头示意图,直观展示 props 向下传数据、emit 向上回传事件的流向,文章可读性更强。

7 拓展:不同场景通信选型总结

通信方式适用场景
props + emit直接父子组件通信
v-model自定义组件双向绑定,是 props+emit 语法糖
slot 插槽父向子传递自定义模板 UI 内容
provide / inject多层嵌套跨代传参,适合配置类数据
Pinia全局多组件共享业务状态,中大型项目首选

8 总结

1. props 实现父向子传递数据,遵循单向数据流,子组件不能直接修改 props; 2. emit 实现子组件向父组件发送事件、回传数据; 3. slot 插槽实现组件 UI 内容灵活定制,分为默认插槽与具名插槽; 4. 简单父子组件使用 props+emit;多层嵌套可以用 provide/inject;全局状态推荐 Pinia; 5. 组件化开发核心:模块拆分、代码复用、低耦合,数据流向清晰便于维护调试。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询