Vue2之组件通信(爆肝)

devtools/2024/10/11 9:28:11/

大家有什么想看的可以在评论区留言,我尽量满足,感谢大家!

组件通信是vue中一个非常重要的内容,我们需要掌握好组件通信,那么让我为大家介绍几种组件通信的方式吧!

一、props

这是父传子的方式,它有三种方式去定义,让我为大家介绍一下

注意:
props是只读的,不要去修改 vue底层监视了props 如果被修改它会发出警告

代码与介绍如下:

// 父组件
<template><div><!-- 我为Student添加属性 --><!-- 传递数据 --><Student name="张三" :age="18" sex="" /></div>
</template>
<script>javascript">
// 导入Student组件
import Student from './components/Student.vue'
export default {name:'App',components:{Student}
}
</script>// 子组件
<template><div><div>姓名:{{ name }}</div><div>年龄:{{ age }}</div><div>性别:{{ sex }}</div></div>
</template>
<script>javascript">
export default {name: 'MyStudent',// 我这里可以使用到props去接收数据// 这个数据会在哪呢? // 它会在VC 也就是这个组件实例身上// 第一种方法 只接受// props: ["name", "age", "sex"],//......................// 第二种方法 限制类型 // 限制了类型 假设我们传入了一个跟这类型不一样的值// 它会在控制台报错 但不影响数据传递 为什么呢// 它可以给操作人员做到提示的用处// props:{//     // 记得大写//     name:String,//     age:Number,//     sex:String,// },//......................// 第三种 限制类型 限制必要性 指定默认值props:{name:{type:String,required:true},age:{type:Number,default:18},sex:{type:String,required:true}}
}
</script>

在这里插入图片描述

二、自定义事件

配合$emit
顾名思义 自定义事件 我们自己定义的事件
可以实现子传父

// 父组件
<template><div><!-- 自定义事件 你想定义什么都行 --><Student @getStudentName="getStudentName" /><!-- 注意事项 如果我想使用原生的DOM事件 我们需要添加上native修饰符 --><Student @click.native="test" /></div>
</template><script>javascript">
// 导入Student组件
import Student from './components/Student.vue'
export default {name: 'App',components: {Student},methods: {getStudentName(value) {console.log(value) // 打印 张三},test() {console.log(1);}}
}
</script>// 子组件
<template><div><div>我是Student组件</div><button @click="sendStudentName">点击名字传给父组件</button><button @click="offStudentName">解绑</button></div>
</template><script>javascript">
export default {name: 'MyStudent',data(){return {name:'张三'}},methods:{sendStudentName(){// this.$emit(触发的事件,传入的数据)this.$emit('getStudentName',this.name)},// 解绑 offStudentName(){// off有三种写法// 解绑单个 this.$off(绑定的事件)this.$off('getStudentName')// 解绑多个 使用数组 this.$off(["事件","事件"])// 解绑全部// this.$off()}}
}
</script>

请添加图片描述

三、ref

ref也可以实现子传父
使用到$on 既然有 $on 那就有 $off

// 父组件
<template><div><!-- ref绑定一个名字 --><Student ref="student" /></div>
</template>
<script>javascript">
// 导入Student组件
import Student from './components/Student.vue'
export default {name: 'App',components: {Student},methods: {getStudentName(value) {console.log(value) // 打印 张三}},// 最好写在 mounted中mounted(){// $on 绑定事件 最好写成箭头函数 不然this指向student这个组件,不指向App组件// this.$refs.student.$on('getStudentName',(value)=>{//   console.log(value) // 张三// })// 通常是如下写法this.$refs.student.$on('getStudentName',this.getStudentName)}
}
</script>// 子组件
<template><div><div>我是Student组件</div><button @click="sendStudentName">点击名字传给父组件</button></div>
</template>
<script>javascript">
export default {name: 'MyStudent',data(){return {name:'张三'}},methods:{sendStudentName(){// this.$emit(触发的事件,传入的数据)this.$emit('getStudentName',this.name)}}
}
</script>

请添加图片描述

四、v-model

咦,这不是双向数据绑定吗?它怎么会出现在咋们的组件通信里?
好,接下来大家要知道v-model的原理
其实他还是借助了自定义事件,与props,当一个扩展知识吧!
原理: v-model本质上是一个语法糖例如应用在输入框上,就是 value属性 和 input事件 的合写
就是下面这段代码,假设我在data中有数据,我使用双向数据绑定

<Student :value="age" @input="age = $event.target.value"></Student>

父组件代码:

<template><div><!-- 我们使用v-model v-model的原理采用了:value + @input="?=$event.target.value" --><BaseSelect v-model="selectId"></BaseSelect></div>
</template>
<script>javascript">
import BaseSelect from "./components/BaseSelect.vue"
export default {name: 'VueApp',data() {return {selectId: '2',};},components: {BaseSelect}
};
</script>
<style scoped></style>

子组件代码:

<template><div><!-- 我们不能直接使用v-model去绑定 --><!-- 我们使用change事件监听 --><select :value="value" @change="handleChange"><option value="1">北京</option><option value="2">上海</option><option value="3">广州</option><option value="4">深圳</option></select></div>
</template>
<script>javascript">
export default {name: 'VueBaseSelect',props: {// 我们直接使用value去接收父组件中的selectIdvalue: String},methods: {handleChange(e) {// 子传父 用到this.$emit() input事件 因为我们父组件的事件是inputthis.$emit("input", e.target.value)}}
};
</script>
<style scoped></style>

请添加图片描述

五、sync

其实这跟上面的v-model有异曲同工之处

作用:可以实现 子组件 与 组件数据的 双向绑定,简化代码

特点: prop属性名,可以自定义,非固定为 value

场景:封装弹框类的基础组件,visible属性 true显示false隐藏

本质:就是 :属性名 和 @update:属性名 合写

<BaseDialog :visible.sync="isShow" />
-----------------------------------
<BaseDialog :visible="isShow" @update:visible="isShow=$event" />

上代码

父组件:

<template><div><button @click="isShow=true">点击退出登录</button><BaseDialog :visible.sync="isShow" /><!-- <BaseDialog :visible="isShow" @update:visible="isShow=$event" /> --></div>
</template><script>javascript">
import BaseDialog from './components/BaseDialog.vue';
export default {name:'App',data() {return {isShow:false}},components:{BaseDialog}}
</script><style lang='scss' scoped></style>

子组件:

<template><div v-show="visible" class="box"><div class="contentBox"><h1 class="outText">你确定确定退出吗?</h1><div class="button"><button @click="confirm">确定</button><button @click="close">取消</button></div></div></div>
</template><script>javascript">
export default {name: 'MyBaseDialog',props:{visible:Boolean},data() {return {}},methods:{confirm(){this.$emit('update:visible',false)},close(){this.$emit('update:visible',false)}}
}
</script><style scoped>
.box {position: absolute;top: 0;left: 0;width: 100vw;height: 100vh;background-color: rgba(0, 0, 0, 0.1);
}.contentBox {position: absolute;top: 50%;left: 50%;transform: translate(-50%, -50%);width: 500px;height: 400px;background-color: #fff;
}.outText {text-align: center;
}
.button {display: flex;justify-content: space-around;
}
.button button{font-size: 40px;
}
</style>

请添加图片描述

六、全局事件总线

一看这个名字就觉得,全局,那我是不是在哪个组件都可以使用呀,没错,是的

首先要有一个概念,既然是全局下的,我如何在别的组件中看见这个方法,并且我们需要用到$on 与 $emit,它们只有在vm上才会存在,所有我们可以在vue的原型对象上声明一个方法,好,废话不多说,上操作

我们找到main.js

javascript">new Vue({render: h => h(App),beforeCreate() {// 使用全局事件总线 最好在beforeCreate中写Vue.prototype.$bus = this},
}).$mount('#app')

组件

// 父组件
<template><div><Student></Student></div>
</template>
<script>javascript">import Student from './components/Student.vue'
export default {name:'MyApp',data() {return {name:''}},components:{Student},mounted() {this.$bus.$on("getStudentName",(data)=>{console.log(data);})}
}
</script><style lang='scss' scoped></style>// 子组件
<template><div><div>我是Student组件</div><button @click="sendStudentName">点击名字传给父组件</button></div>
</template><script>javascript">
export default {name: 'MyStudent',data(){return {name:'张三'}},methods:{sendStudentName(){// this..$bus.$emit(触发的事件,传入的数据)this.$bus.$emit('getStudentName',this.name)}}
}
</script>

请添加图片描述

七、provide & inject

跨组件共享数据

子孙后代都可以收到

我认为这种方法挺方便的

来,为大家展示一下

父组件

<template><div><button @click="updateColor">点击修改颜色</button><button @click="updateName">点击修改姓名</button><Home></Home></div>
</template><script>javascript">
import Home from './components/Home.vue';
export default {name: 'App',// 来我们使用一下provideprovide() {return {color: this.color,info: this.info}},components: {Home},data() {return {// 普通数据类型 非响应式color: 'pink',// 复杂数据类型 响应式info: {name: '张三',age: 18}}},methods: {updateColor() {this.color = 'red'},updateName() {this.info.name = '李四'}}
}
</script><style lang='scss' scoped></style>

子组件

<template><div><div>{{ color }}</div><div>{{ info.name }}---{{ info.age }}</div></div>
</template><script>javascript">
export default {name: 'MyHome',// 我们使用inject去做接收inject:['color','info'],
}
</script><style lang='scss' scoped></style>

请添加图片描述

八、消息订阅与发布

定阅消息:消息名
发布消息:消息内容

通俗易懂的例子

订阅报纸:地址
邮递员送报纸:报纸

我们需要使用到第三方组件库

javascript">npm i pubsub-js

父组件:

<template><div><Student></Student></div>
</template><script>javascript">
// 引入pubsub
import pubsub from 'pubsub-js'
import Student from './components/Student.vue'
export default {name:'App',components:{Student},mounted(){// 订阅消息 第一个参数订阅的消息名 第二个回调函数// 最好写成箭头函数 要不然this指向会有问题// 回调函数有两个参数 第一个消息名 第二个订阅的数据this.pubId = pubsub.subscribe("name",(msgName,data)=>{console.log(msgName,data);})}
}
</script><style lang='scss' scoped></style>

子组件

<template><div><button @click="sendData">点击发布</button></div>
</template><script>javascript">
// 引入pubsub
import pubsub from 'pubsub-js'
export default {name:'MyStudent',data() {return {name:'张三'}},methods:{sendData(){pubsub.publish('name',this.name)}}
}
</script><style lang='scss' scoped></style>

请添加图片描述

九、$parent 与 $children

大家一看,这不就是父子吗?没错确实是父子,哈哈

$children 可以有多个,所以是数组,如果父组件中没有子组件,children就是空数组
$parent是个对象,如在#app上拿parent得到的是new Vue()的实例,在这实例上再拿 parent得到的是undefined

父组件

<template><div><div>{{ name }}</div><div>{{ msg }}</div><Student :msg="msg"></Student><button @click="getChildren">点击获取子组件的name</button></div>
</template><script>javascript">
import Student from './components/Student.vue';
export default {name: 'App',components: {Student},data() {return {name:'',msg: '码字中.....'}},methods: {getChildren() {this.name = this.$children[0].name}}
}
</script><style lang='scss' scoped></style>

子组件

<template><div><button @click="updateParent">点击修改父组件的msg</button></div>
</template><script>javascript">
export default {name:'MyStudent',props:["msg"],data() {return {name:'张三'}},methods:{updateParent(){this.$parent.msg = '疯狂码字中'}}
}
</script><style lang='scss' scoped></style>

请添加图片描述

还有几种方式,日后补全,感谢大家的阅读

最值得欣的景,是自己奋斗的足迹,加油!


http://www.ppmy.cn/devtools/9550.html

相关文章

在React中的函数组件和类组件——附带示例的对比

在React中&#xff0c;创建组件有两种主要方式&#xff1a;函数组件和类组件。每种方式都有自己的语法和用例&#xff0c;尽管随着React Hooks的引入&#xff0c;它们之间的差距已经显著缩小。但选择适当的组件类型对于构建高效和可维护的React应用程序仍然非常关键。 在本文中…

《王者荣耀》游戏攻略:角色排行榜——墨子

作为天蝎座黄金圣斗士&#xff0c;墨子以他的正义感和荣誉感闻名&#xff0c;一直站在正义的一方&#xff0c;忠于女神雅典娜。他的猩红毒针象征着审判和死亡&#xff0c;而他所施加的十五针“安达里士”更是生命终结的预兆。在冥王再次发动战争之际&#xff0c;墨子追随雅典娜…

Java入门四步走

1. 简单的入门语法&#xff1a; 1.1 数据类型&#xff1a; 基本数据类型&#xff1a; 整数类型 —— byte、short、int、long, 浮点类型 —— float、double 字符类型 —— char 布尔类型 —— boolean 引用数据类型&#xff1a; 接口&#xff08;interface&#xff09;、数…

ORACLE错误提示概述

OceanBase分布式数据库-海量数据 笔笔算数 保存起来方便自己查看错误代码。 ORA-00001: 违反唯一约束条件 (.) ORA-00017: 请求会话以设置跟踪事件 ORA-00018: 超出最大会话数 ORA-00019: 超出最大会话许可数 ORA-00020: 超出最大进程数 () ORA-00021: 会话附属于其它某些进程…

37-4 用Python编写SQL注入的基于错误报告的POC

环境准备:构建完善的安全渗透测试环境:推荐工具、资源和下载链接_渗透测试靶机下载-CSDN博客 一、SQL 注入基础 SQL注入是一种常见的应用程序安全漏洞,发生在应用程序与数据库层之间。简而言之,它是通过在输入的字符串中注入SQL指令来实现的,如果程序设计不良未进行充分…

SSM整合后的一个及其简单的商城

shopping-cart SSM整合后的一个及其简单的商城&#xff0c;首页数据是模拟的&#xff0c;主要测试购物车模块 启动 git clone https://github.com/0saber0/shopping-cart创建数据库&#xff1a;shopping导入建表脚本&#xff1a;shopping.sql修改db.properties部署和启动项目&…

Python的pytest框架(3)--fixtrue固件

fixture是pytest的一项核心特性&#xff0c;它提供了一种组织和管理测试依赖项&#xff08;如初始化环境、创建资源、清理操作等&#xff09;的有效机制。下面将对fixture进行深入讲解&#xff0c;包括其基本概念、作用、使用方式、特性以及高级应用&#xff1a; 目录 一、基…

《中学科技》是什么级别的刊物?如何投稿?

《中学科技》是什么级别的刊物&#xff1f;如何投稿&#xff1f; 《中学科技》创刊于1976年&#xff0c;由上海世纪出版&#xff08;集团&#xff09;有限公司主管&#xff0c;上海科技教育出版社有限公司主办的省级学术期刊&#xff0c;《中学科技》以传播科技知识、启迪智慧…