Vue2之组件通信(爆肝)

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

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

一、props

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

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

代码与介绍如下:

// 父组件
<template><div><!-- 我为Student添加属性 --><!-- 传递数据 --><Student name="张三" :age="18" sex="" /></div>
</template>
<script>
// 导入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>
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>
// 导入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>
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>
// 导入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>
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>
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>
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>
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>
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

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

组件

// 父组件
<template><div><Student></Student></div>
</template>
<script>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>
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>
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>
export default {name: 'MyHome',// 我们使用inject去做接收inject:['color','info'],
}
</script><style lang='scss' scoped></style>

请添加图片描述

八、消息订阅与发布

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

通俗易懂的例子

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

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

npm i pubsub-js

父组件:

<template><div><Student></Student></div>
</template><script>
// 引入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>
// 引入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>
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>
export default {name:'MyStudent',props:["msg"],data() {return {name:'张三'}},methods:{updateParent(){this.$parent.msg = '疯狂码字中'}}
}
</script><style lang='scss' scoped></style>

请添加图片描述

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

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/637287.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Docker - 简介

原文地址&#xff0c;使用效果更佳&#xff01; Docker - 简介 | CoderMast编程桅杆https://www.codermast.com/dev-tools/docker/docker-introduce.html Docker是什么&#xff1f; Docker 是一个开源的应用容器引擎&#xff0c;基于 Go 语言 并遵从 Apache2.0 协议开源。 D…

vulfocus靶场thinkphp命令执行cve-2018-1002015

thinkPHP 5.0.x版本和5.1.x版本中存在远程代码执行漏洞&#xff0c;该漏洞源于ThinkPHP在获取控制器名时未对用户提交的参数进行严格的过滤。远程攻击者可通过输入‘&#xff3c;’字符的方式调用任意方法利用该漏洞执行代码 开启靶场&#xff1a; 使用工具&#xff1a; think…

适配器模式【结构型模式C++】

1.概述 适配器模式是一种结构型设计模式&#xff0c; 又称为变压器模式、包装模式&#xff08;Wrapper&#xff09; 将一个类的接口变换成客户端所期待的另一种接口&#xff0c;从而使原本因接口不匹配而无法在一起工作的两个类能够在一起工作。 2.结构 Target&#xff1a;适配…

python3如何提取汉字

采用正则表达式的方法对字符串进行处理。 str1 "&#xff5b;我%$是&#xff0c;《速$.度\发》中 /国、人"&#xff08;1&#xff09;提取汉字 汉字的范围为”\u4e00-\u9fa5“&#xff0c;这个是用Unicode表示的。 import re res1 .join(re.findall([\u4e00-\u9fa…

排序 “叁” 之交换排序

目录 1. 基本思想 2.冒泡排序 2.1 基本思想 2.2 代码示例 2.3 冒泡排序的特性总结 3.快速排序 3.1 基本思想 &#x1f335;hoare版本 &#x1f335;挖坑法 ​编辑 &#x1f335;前后指针版本 ​编辑 3.2 快速排序优化 &#x1f33b;三数取中法选key 3.4 快速排序…

命理八字之电子木鱼的代码实现

#uniapp# #电子木鱼# 不讲废话&#xff0c;上截图 目录结构如下图 功能描述&#xff1a; 点击一下&#xff0c;敲一下&#xff0c;伴随敲击声&#xff0c;可自动点击。自动点击需看视频广告&#xff0c;或者升级VIP会员。 疑点解答&#xff1a; 即animation动画的时候&…

git 基础配置

一、下载git sudo apt install git -y二、用户信息配置 $ git config --global user.name "John Doe" $ git config --global user.email johndoeexample.com检查配置信息 git config --list三、ssh密钥生成 1、进入~/.ssh mkdir ~/.ssh cd ~/.ssh2、生成密钥 …

计算机网络基础1--基础概念

1. IP地址 1.1 IPv4地址 分为网络号和主机号 地址块的第一个地址和最后一个地址通常不使用。 广播地址为主机号全取1的情况。 2. 常用报文格式 2.0 ethernet协议 2.1 arp协议 2.2 ip协议 2.3 tcp协议 2.4 udp协议 2.5 icmp协议

电磁兼容(EMC):静电放电(ESD)抗扰度试验深度解读(三)

目录 1. 静电抗扰度试验标准试验程序定制的目的 2. 环境条件对充电量的影响 3. 环境级别与空气和接触放电的关系 4. 试验等级的选择 1. 静电抗扰度试验标准试验程序定制的目的 保护设备免受静电放电影响的问题对制造厂和用户来说都是相当重要的。 随着微电子元件的广泛应用…

安装多个MySQL版本时如何连接到不同的数据库

当安装多个版本的数据库时&#xff0c;不同版本的端口名不一样&#xff0c;可以使用以下命令进行连接 mysql -uroot -p数据库密码 -h主机名 -P端口号 数据库主机名默认是localhost&#xff0c;端口号默认是3306&#xff0c;当安装多个版本数据库时&#xff0c;需要记住数据库的…

ssm069端游账号销售管理系统+jsp

端游账号销售管理系统的设计与实现 摘 要 互联网发展至今&#xff0c;无论是其理论还是技术都已经成熟&#xff0c;而且它广泛参与在社会中的方方面面。它让信息都可以通过网络传播&#xff0c;搭配信息管理工具可以很好地为人们提供服务。针对端游账号销售信息管理混乱&…

Android Studio实现页面跳转

建立文件 temp.xml <?xml version"1.0" encoding"utf-8"?> <LinearLayout xmlns:android"http://schemas.android.com/apk/res/android"android:layout_width"match_parent"android:layout_height"match_parent"…