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

组件通信(父传子,子传父,跨组件通信)

        组件(component)是vue.js最核心的功能,是可扩展的HTML元素。每个页面都是一个HTML。以.vue结尾的文件,都可以叫组件。

场景:将一个完整的项目,拆分成不同的功能模块。

注意:组件首字母要大写。

创建和使用组件 

A.组件放在src中的components

如图:

代码显示: 

// App.vue组件
<template><div class="div1"><h3>这是App.vue组件</h3></div></template><style scoped>
.div1{background-color: aqua;
}
</style>

B. 导入组件:import xxx from 'xxx'

// App.vue组件
<template><div class="div1"><h3>这是App.vue组件</h3></div></template><script setup>
// 组件已创建好,需在App.vue中导入 如下import HelloWorld from './components/HelloWorld.vue';import TheWelcome from './components/TheWelcome.vue';
</script><style scoped>
.div1{background-color: aqua;
}
</style>

C.使用组件 

  • HelloWorld.vue
<template><h3>子组件HelloWorld</h3>
</template>
  • TheWelcome.vue 
<template><div class="div2"><a href="">子组件TheWelcome</a></div>
</template><style scoped>
.div2{background-color: yellowgreen;height: 50px;width: 150px;
}
</style>
  •  App.vue
// App.vue组件
<template><div class="div1"><h3>这是App.vue组件</h3></div><!-- App.vue使用了HelloWorld、TheWelcome组件 --><HelloWorld/><TheWelcome/>
</template><script setup>
// 组件已创建好,需在App.vue中导入 如下import HelloWorld from './components/HelloWorld.vue';import TheWelcome from './components/TheWelcome.vue';
</script><style scoped>
.div1{background-color: aqua;
}
</style>


一、父传子

使用props实现父传子通信,从父组件传输,在子组件接收。父组件通过在子组件标签上绑定(v-on)自定义属性来传递数据。

  • App.vue
// App.vue组件
<template><div class="div1"><h3>这是App.vue组件</h3></div><!-- App.vue使用了HelloWorld、TheWelcome组件 --><!-- 实验1:在父组件中,通过v-bind的增强语法,向子组件传递普通对象数据 --><HelloWorld v-bind="propStudent"  /><!-- 实验2:在父组件中,通过v-bind的增强语法,向子组件传递响应式对象数据 --><Swiper v-bind="proTeacher"/><button @click="addTeacherAge">Swiper增加教师年龄</button><br><!-- 实验3:在父组件中,通过设置子组件的“字符串型”属性,用于向子组件传递字符串数据 --><TheWelcome propName="王五" propAge="90"/></template><script setup>
import {reactive } from 'vue';
import HelloWorld from './components/HelloWorld.vue';
import Swiper from './components/Swiper.vue';
import TheWelcome from './components/TheWelcome.vue';
// 实验1const propStudent = {     // 这里使用const声明了一个名为propStudent的常量propName:"张三",propAge:20,}
// 实验2const proTeacher = reactive({name:"韩梅梅",age:30,})
const addTeacherAge = () => {proTeacher.age++;console.log(`教师年龄为${proTeacher.age}`)
}
</script><style scoped>
.div1{background-color: aqua;
}
</style>
  • HelloWorld.vue

<template><h3>子组件HelloWorld</h3>
</template><script setup>// 定义对象类型的属性 (用于接收上级组件传递过来的对象类型数据) const props = defineProps({propName:{type:String   // 类型为字符串},propAge:{type:Number,  // 类型为数字// 是否必需传值(若必须传值却没有传,则控制台会给出警告)required:true,  default:18    // 默认值},        })console.log(props);
</script>
  •  Swiper.vue

<script setup>const props = defineProps(["name","age"])console.log(props)
</script><style scoped></style>
  •  TheWelcome.vue
<template><h1>子组件TheWelcome</h1>
</template><script setup>// props是properties的缩写,意思为属性,// defineProps定义的属性是提供给外部进行设置使用的// 定义字符串类型的属性(用于接收上级组件传递过来的字符串数据) const props = defineProps(["propName", "propAge"])console.log(props);
</script><style scoped>
.div2{background-color: yellowgreen;height: 50px;width: 150px;
}
</style>

二、子传父

子组件通$emit方法触发一个自定义事件,父组件在使用子组件标签时监听这个事件来获取数据。

例如:在子组件定义一个 emit(名称可自定义)对象,存储自定义事件。在这里定义了两个自定义事件,分别是“getPerson”和“addPerson”。再在父组件设置监听事件监听子组件。

  • App.vue
// 父组件
<script setup>import { ref } from 'vue';import Header from './components/Header.vue';const person_num = ref(1) //初始值为1// 定义emitPrintPerson函数接收一个参数dataconst emitPrintPerson = (data) => {console.log(`下级组件发射过来的数据为: ${data.name} , ${data.age}`);}const emitAddPersonNum = (data) => {person_num.value += data}
</script><template><div id="root_component"><h3>我是上级组件</h3><h5>计算机学院总人数:{{ person_num }}</h5><!-- 监听两个子组件的事件 --><Header v-on:getPerson="emitPrintPerson" @addPerson="emitAddPersonNum" />  </div> 
</template><style scoped>#root_component {width: 50%;background-color: antiquewhite;}
</style>
  • Header.vue
<script setup>/* defineEmits是Vue3的编译时宏函数,用于子组件向父组件发送自定义事件 *///1.用宏函数defineEmits定义一个名为 emits 的对象//(名字可以随便取), 用于存储自定义事件//这行代码完成了事件的定义声明,告知 Vue 框//架该组件有这两个可以触发并传递数据给父组件的事件。const emits = defineEmits(["getPerson", "addPerson"])//2.向上级组件发射名为“getPerson”的自定义事件,//并同时发射数据emits("getPerson", { name:"李雷", age: 18 })const addPerson = () => {//3.向父组件发射名为“addPerson”的自定义事件,//并同时发射数据emits("addPerson", 1)}  
</script><template><div><h3>我是下级组件</h3><!-- 这个按钮绑定了@click事件监听器,点击时会触发addPerson函数 --><button @click="addPerson">添加人数</button></div>
</template><style scoped>div {width: 50%;background-color: gray;}
</style>

三、跨组件通信(依赖注入方法)

  • provide+inject(提供和注入方法)

传统组件传值是逐级传递的,必须一级一级传递,而该方法不用一级一级注入,可以使用provide提供数据,由inject注入数据。无论层级多深,都可以注入由父组件提供给整条链路的依赖。

App.vue 

<template><div id="div1"><h2>跨组件传值(依赖注入)</h2>App.vue <br><input v-model="ver" /><div id="div2"><Base/></div></div>
</template><script setup>
// 从App.vue中提供数据
// provide定义提供可使用的数据,语法:provide(变量名称,值)
import { provide } from 'vue'
import Base from './views/Base.vue'
// 定义ver的值
const ver = 200;
//在后面的组件中可以通过version取到ver的值
provide('version',ver)
</script><style scoped>
#div1{width: 500px;height: 400px;background-color: aquamarine;
}
#div2{width: 200px;height: 100px;background-color: darkcyan;
}
</style>

Base.vue

<template><div>Base.vue<input v-model="ver" /></div>
</template><script setup>
// inject注入父组件provide的变量,
//语法如下:inject(变量名称,可选的默认值)
import { inject } from 'vue'const ver = inject('version')
console.log(ver);</script><style lang="scss" scoped></style>
  • 响应式传值

 同时,Base改变App也会改变。

直接将ver设置为响应式对象,其他不用改动。

http://www.lryc.cn/news/502780.html

相关文章:

  • JWT 令牌:原理、应用与安全考量
  • YOLOv5+pyqt5+摄像头在特定条件下进行目标检测并采集原始数据
  • 12.6深度学习_模型优化和迁移_整体流程梳理
  • TCP 和 UDP 可以使用同一个端口吗
  • 信而泰网络测试仪校准解决方案
  • Java 实现给pdf文件指定位置盖章功能
  • 机器学习支持向量机(SVM)算法
  • 解决 MySQL 启动失败与大小写问题,重置数据库
  • 计算生成报价单小程序系统开发方案
  • 若依集成Uflo2工作流引擎
  • STM32模拟I2C通讯的驱动程序
  • Unity简单操作及使用教程
  • 网络安全法-监测预警与应急处置
  • qt 设置系统缩放为150%,导致的文字和界面的问题
  • Scala的正则表达式二
  • 软考系分:今日成绩已出
  • DevExpress WPF中文教程:Grid - 如何移动和调整列大小?(一)
  • Docker 安装 sentinel
  • PyCharm 2024.1 解锁版 (Python集成开发IDE)详细安装步骤
  • SQL中的函数介绍
  • 【工业机器视觉】基于深度学习的水表盘读数识别(2-数据采集与增强)
  • 爬虫基础知识点
  • 高效利用资源:分布式有状态服务的高可靠性设计
  • aws(学习笔记第十六课) 使用负载均衡器(ELB)解耦webserver以及输出ELB的日志到S3
  • 关于php://filter过滤器
  • 数据安全法-政务数据安全与开放
  • MySQL数据库的数据类型
  • 前端H5移动端基础框架模板 :Vue3 + Vite5 + Pinia + Vant4 + Sass + 附源码
  • 什么是线程安全
  • ️️️ 避坑指南:如何修复国密gmssl 库填充问题并提炼优秀加密实践20241212