Vue3-父子组件通信

在 Vue 3 中,尤其是在使用 `` 并结合 TypeScript 时,父子组件之间的通信变得非常清晰和类型安全。

核心思想是:

  1. 父组件向子组件 (Prop down): 通过 Props 传递数据。
  2. 子组件向父组件 (Event up): 通过 Events (自定义事件) 发送消息。

1.父传子

  • 定义一些本地数据 (响应式引用 ref)。

  • 将这些数据通过 props 传递给子组件。

  • 监听子组件发出的 emits 事件,并定义一个处理函数来更新本地数据。

ts 复制代码
  <div class="parent-container">
    <h2>👋 我是父组件</h2>
    
    更新给子组件的消息: 
    

    <p>
      从子组件收到的消息: <strong>{{ messageFromChild }}</strong>
    </p>

    <hr/>

    
  </div>



// 1. 导入 ref 用于创建响应式数据
import { ref } from 'vue';
// 2. 导入子组件
import ChildComponent from './ChildComponent.vue';

// 3. 定义父组件的本地状态
const messageForChild = ref('你好,子组件!这是来自父组件的消息。');
const messageFromChild = ref('...等待子组件的消息...'); // 存放从子组件收到的消息

// 4. 定义一个函数,用于处理子组件触发的 'updateMessage' 事件
// TypeScript 在这里可以根据子组件的 emit 定义自动推断 'newMessage' 的类型为 string
const handleChildMessage = (newMessage: string) => {
  messageFromChild.value = newMessage;
}



.parent-container {
  border: 2px solid #34495e;
  background-color: #f0f8ff;
  padding: 20px;
  border-radius: 8px;
}
input {
  margin-left: 10px;
}

2.子接收数据,传递数据给父组件

ts 复制代码
  <div class="child-container">
    <h3>👶 我是子组件</h3>
    
    <p>父组件传来的消息 (mainMessage):</p>
    <blockquote>{{ props.mainMessage }}</blockquote>
    
    <p>父组件传来的可选数字 (optionalCount):</p>
    <blockquote>{{ props.optionalCount || '未提供' }}</blockquote>

    
      向父组件发送消息
    
  </div>



// 1. 接收 Props (父 -> 子)
// 使用泛型参数为 props 定义类型。
// 这是最推荐的 TS 语法。
const props = defineProps<{
  mainMessage: string;      // 必需的 prop
  optionalCount?: number;   // 可选的 prop (注意 '?' 符号)
}>()

// 2. 定义 Emits (子 -> 父)
// 使用泛型参数为 emit 定义事件和载荷类型。
const emit = defineEmits<{
  // (e: '事件名', 载荷1: 类型, 载荷2: 类型, ...): void
  (e: 'updateMessage', message: string): void;
}>()

// 3. 定义一个函数来触发 emit
const sendMessageToParent = () => {
  const dataToSend = `你好父组件,我更新了!(时间戳: ${Date.now()})`;
  
  // 4. 触发事件,将数据 (dataToSend) 发送回父组件
  // Vue 会查找父组件上绑定的 @updateMessage 监听器
  emit('updateMessage', dataToSend);
}



.child-container {
  border: 2px dashed #42b983;
  background-color: #f0fff4;
  padding: 15px;
  margin-top: 15px;
  border-radius: 8px;
}
blockquote {
  margin: 0;
  padding: 10px;
  background: #fff;
  border-left: 5px solid #ccc;
}

3.关键点总结

  • defineProps (子组件用于接收)

    • 在 `` 中,它是一个宏,无需导入。
    • 使用泛型 defineProps<{...}>() 来提供最严格的类型检查。
    • props 是单向数据流。子组件不应该 直接修改 props 对象中的值。
  • defineEmits (子组件用于发送)

    • 同样是一个宏,无需导入。
    • 使用泛型 defineEmits<{...}>() 来定义事件签名。
    • 语法 (e: 'eventName', payload: Type): void 确保了当你调用 emit('eventName', ...) 时,payload 必须匹配定义的 Type
  • 模板中的绑定

    • 父组件使用冒号 : (即 v-bind) 来传递 props
    • 父组件使用艾特 @ (即 v-on) 来监听 emits 事件。
相关推荐
小满zs16 分钟前
关于HBuilderX+ 微信小程序开发工具启动的问题
前端·uni-app
林深见鹿_海蓝见鲸23 分钟前
微信小程序反编译完整教程(Windows 新手版)
前端
夏雪coding30 分钟前
JeecgBoot 动态路由踩坑(Vue2):刷新白屏、permissionList[0] 报 undefined,以及我最后为什么全删了
javascript·vue.js
默_笙39 分钟前
😋 我让爬虫终于看到了我的网站,后端同事说"这也行?"(上):SEO 与渲染模式
前端·javascript
feixing_fx1 小时前
告别枯燥字体:Web 字体加载策略与 font-display 最佳实践
前端·css·前端框架·交互·css3
Liora_Yvonne1 小时前
不懂后端,只会 TypeScript,想独立做完整项目?这套全栈底座就是给前端准备的
前端·后端·全栈
前端Hardy1 小时前
GitHub 爆火!236K+ Star!一套 Skills 让 AI 按工程师方式写代码
前端·后端
烬羽2 小时前
AI Coding 全流程实战:从需求到上线,我用 AI 开发了一个 NPM 包
前端·react.js·ai编程
前进的程序员2 小时前
Codex破局:前端组件秒级生成|提速React/Vue开发,可复用提示词+实战调试经验
前端·vue.js·react.js·codex
前端snow2 小时前
ai agent ---output汇总
前端