文章目录

  • 前言
  • 零、如何使用封装组件
  • 一、为什么需要下面的通信方式
  • 二、父组件给子组件通信
  • 三、子组件给父组件通信
  • 四、兄弟组件通信
  • 五、多层组件之间的通信
  • 总结

前言

组件可以说是 vue 中最为核心的一部分了,通过组件化,可以使得整个项目的创建更加的高效和便捷。下面我主要是介绍学习的关于组件的通信方式。


零、如何使用封装组件

一般我们在一个 vue 项目中,项目的结构就如官网给出的下图这般:

我们的项目分为由很多个组件来构成一个整体,这有什么好处呢?我个人觉得,有下面几点:

  • 可复用:往往某些部分我们会多次用到,通过抽离成组件,我们只需要引用,不仅减少工作量,还减少了
  • 结构化,我们对整个项目更加的条理和清晰,当出现问题也能便捷的定位和处理更换。

简单介绍在项目中使用吧!我们用脚手架创建了一个项目,那么里面会有一个 components文件夹就是用来存放组件的。我们可以在这里创建我们使用到的组件。组件的格式以下面:

<template></template><script>
export default {name: 'TemplateExplainDialog',}
</script><style scoped></style>

组件的几个注意点就是:

  • 命名一般以大写字母开头
  • date里面是函数
  • 每一个组件相当于一个vue的实例,所以有独立的生命周期等等

在使用上,我们创建好组件后,我们在需要使用到该组件的地方中

  • 引入该组件文件
  • components声明
  • 然后使用就好了
  1. 建立组件的模板,根据需求实现结果和样式
  2. 分析数据的接收和输出,比如使用到的 props 和 emit
  3. 父组件中调用和实例化

完整的使用方式,可以参考下方的代码案例。

一、为什么需要下面的通信方式

首先我们需要知道,在 vue 中组件间的信息是遵循数据的单向流通的,因为要是子组件的实例化很可能是多个的,要是组件间双向的,那会导致数据乱成一团了,一个子组件改变了父组件的数据,会导致与该组件有关的所有子组件的数据发生变化,所以是应该避免的。

二、父组件给子组件通信

  • 首先在子组件中使用 props,来接收对应的属性
  • 在父组件中使用子组件的地方,添加上面定义的属性
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title>
</head>
<body><div id="app"><Parents></Parents></div><script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script><script>const ABorder = {//用props来接收父组件传来的值,同时父组件要绑定属性props: {name:{//设置类型,符合才接收type: String,//不传默认为这个default: '我也不知道呀'}},template: `<div>我是儿子A<div>我的名字叫:{{name}}</div></div>`};const BBorder = {template: `<div>我是儿子B</div>`}const Parents = {data() {return {msg: '孩儿们好呀!',aName: '大花猫',bName: '大黄狗'}},//可以有下面两种形式来调用组件template: `<div>我是父组件:{{msg}}<hr/><a-border :name= 'this.aName'></a-border><hr/><BBorder></BBorder></div>`,components: {ABorder,BBorder }}//实例化一个vue,并且绑定到app这个元素const vm = new Vue({el: '#app',components: {Parents,}})</script>
</body>
</html>

输出的效果图如下:

这里子组件A接收到了,来自父组件的值(大花猫)

那么我们在这里又另外个需求了,儿子A, 他不想叫大花猫,他想给自己命名为小黄鸭,他进行了,下面的操作:

<script>const ABorder = {template: `<div>我是儿子A<div>我的名字叫:{{name}}</div><button @click="newName">给自己命名</button></div>`,//用props来接收父组件传来的值,同时父组件要绑定属性props: {name:{//设置类型,符合才接收type: String,//不传默认为这个default: '我也不知道呀'}},methods: {newName() {this.name = '小黄鸭'}}};

这时候就报错了!

想知道具体为啥吗?看我的另外一篇文章,里面详细的讲解了这个问题,以及给出了,解决的办法哦。点击链接

当然,我们也可以通过下面即将讲到的方法来解决。

三、子组件给父组件通信

我们父组件可以通过 props 来向子组件传递值,那么要是我们子组件需要向父组件传递值呢?如果我们可以实现向父组件传递值,那么两个组件间,不就形成一个闭环啦,数据就可以根据我们的需要来进行传递了!!方法如下:

  • 子组件中声明对应饿事件,通过 this.$emit(‘事件’ , ‘数据’)
  • 在父组件中使用子组件的地方,添加上面定义的事件
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title>
</head>
<body>
<div id="app"><Parents></Parents>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
<script>const ABorder = {template: `<div>我是儿子A<div>我的名字叫:{{name}}</div><button @click="newName">给自己命名</button></div>`,//用props来接收父组件传来的值,同时父组件要绑定属性props: {name:{//设置类型,符合才接收type: String,//不传默认为这个default: '我也不知道呀'}},methods: {newName() {this.$emit('newName','大黄狗')}}};const BBorder = {template: `<div>我是儿子B</div>`}const Parents = {data() {return {msg: '孩儿们好呀!',aName: '大花猫',bName: '大黄狗'}},methods: {chang(value) {this.aName = value}},//可以有下面两种形式来调用组件template: `<div>我是父组件:{{msg}}<hr/><a-border :name= 'this.aName'  @newName = 'chang'></a-border><hr/><BBorder></BBorder></div>`,components: {ABorder,BBorder}}//实例化一个vue,并且绑定到app这个元素const vm = new Vue({el: '#app',components: {Parents,}})
</script>
</body>
</html>

实现的效果如下:

点击按键后:

这时成功把子组件中的值(大黄狗)传递给了父组件,同时父组件传递给子组件,实现了数据的更新。

四、兄弟组件通信

上面我们说的是爸爸和儿子A他们为名字的争论过程,可是我们是不是忘了个人,那就是儿子B呢?儿子B他觉得大黄狗这个名字真好听,也想给自己命名为大黄狗呀!这么一来,父亲就不高兴了,老子起给你们的名字,你们都不要,自己搞去吧!

现在就面临一个问题了,儿子A 需要和 儿子B 大家讨论,谁叫大黄狗这个名字?那么他们如何决定呢?他老爸不肯来参与了,那么我们就需要第三方来沟通协商两者了。

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title>
</head>
<body>
<div id="app"><Parents></Parents>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
<script>//创建一个媒介来连通两个是组件const medium = new  Vue()const ABorder = {template: `<div>我是儿子A<div>我的名字叫:{{name}}</div><button @click="newName">给自己命名</button></div>`,created () {medium.$on('letDiscussionName',(val)=>{alert(val)})},//用props来接收父组件传来的值,同时父组件要绑定属性props: {name:{//设置类型,符合才接收type: String,//不传默认为这个default: '我也不知道呀'}},methods: {newName() {this.$emit('newName','大黄狗')}}};const BBorder = {template: `<div>我是儿子B<button @click="discussionName">讨论</button></div>`,methods: {discussionName() {medium.$emit('letDiscussionName','儿子A来讨论')}}}const Parents = {data() {return {msg: '孩儿们好呀!',aName: '大花猫',bName: '大黄狗'}},methods: {chang(value) {this.aName = value}},//可以有下面两种形式来调用组件template: `<div>我是父组件:{{msg}}<hr/><a-border :name= 'this.aName'  @newName = 'chang'></a-border><hr/><BBorder></BBorder></div>`,components: {ABorder,BBorder}}//实例化一个vue,并且绑定到app这个元素const vm = new Vue({el: '#app',components: {Parents,}})
</script>
</body>
</html>

我们点击儿子B里的 discussionName 那么就会去触发 儿子A里的letDiscussionName,正常来说,我们是用 this.xxxxx 的,但是我们这里是创建了一个Vue的实例对象 medium来连接两者,因为使用 this 的话,只是分别指向他们组件本身们这里我们通过 medium 就相当于给两者之间搭了条桥(第三者)。这是中间事件总线的思想。

同样的我们也可以用父组件来做中转的,也是可以的!

五、多层组件之间的通信

当我们构建一个大点的项目时,往往会有很多个组件构成的,A组件下可能还有 B组件 ,B组件下有C组件…E组件.,那么我们如果要是需要在E组件中拿到A组件的值该如何做呢?

那么其实这里很简单,我们在父组件中使用 provide ,在子组件中使用 inject

// 父级组件提供 name
var Parent= {provide: {name: '大花猫'},// ...
}// 子组件引入 name
var Son = {inject: ['name'],created () {console.log(this.name) // 大花猫}}

总结

到这里,组件间传递值的基本方法就介绍完了,后面在来补充一些遇到的技巧和知识点要注意的地方。

如何在vue 中使用组件,以及组件通信的方式(父传子/子传父/兄弟传)相关推荐

  1. class根据状态 vue_搞懂并学会运用 Vue 中的无状态组件

    啥是应用程序状态,为什么咱们需要它? 状态管理通常在较小的项目并不需要,但是当涉及到更大的范围时,如企业级的应用大部分需要它了.简单的说,状态是一个包含应用程序使用的最新值的对象.但是,如果咱们从结构 ...

  2. [vue] vue中什么是递归组件?举个例子说明下?

    [vue] vue中什么是递归组件?举个例子说明下? 组件自己调用自己,场景有用于生成树形结构菜单 个人简介 我是歌谣,欢迎和大家一起交流前后端知识.放弃很容易, 但坚持一定很酷.欢迎大家一起讨论 主 ...

  3. vue中集成的ui组件库_Vue组件可使用Vault Flow通过Braintree集成PayPal付款

    vue中集成的ui组件库 Vue Braintree PayPal按钮 (Vue Braintree PayPal button) Vue component to integrate PayPal ...

  4. Revit建模软件:如何在Revit中准确放置族组件?

    Revit建模软件:如何在Revit中准确放置族组件? 如何在Revit中准确放置族组件?今天,我们以螺丝为例来解释这个问题. 设置工作面: 你需要的工作平面是一个垂直或有角度的平面. 如图所示,蓝色 ...

  5. 有关QJ_Filecenter在vue中的使用和组件封装

    有关QJ_Filecenter在vue中的使用和组件封装 QJ_FileCenter在vue中的使用和组件封装 安装 第一步:在官网下载QJ_FileCenter安装包 第二部:访问FileCente ...

  6. vue中,右键菜单组件v-contextmenu的使用

    vue中,右键菜单组件v-contextmenu的使用 1.效果 右键菜单之禁用和子菜单 2.流程 第一步:安包 npm install v-contextmenu --save-dev npm in ...

  7. Vue中如何扩展⼀个组件

    Vue中如何扩展⼀个组件 按照逻辑扩展和内容扩展来列举: 逻辑扩展有:mixins.extends.composition api: 内容扩展有: slots: 一.Mixin 组件和组件之间有时候会 ...

  8. vue 递归创建菜单_如何在Vue中创建类似中等的突出显示菜单

    vue 递归创建菜单 by Taha Shashtari 由Taha Shashtari 如何在Vue中创建类似中等的突出显示菜单 (How to Create a Medium-Like Highl ...

  9. 如何在 Vue 中使用 Chart.js - 手把手教你搭可视化数据图表

    本文首发:<如何在 Vue 中使用 Chart.js - 手把手教你搭可视化数据图表> 使用 Chart.js 在 Vue 搭建的后台管理工具里添加炫酷的图表,是所有数据展示类后台必备的功 ...

  10. 如何在 Vue 中导出数据至 Excel 表格 - 卡拉云

    本文首发:<如何在 Vue 中导出数据至 Excel 表格 - 卡拉云> 我们经常需要在 Vue 搭建的后台管理系统里导出数据到 Excel / CSV ,方便我们将数据共享给其他同学或在 ...

最新文章

  1. SSH暴力破解IP大曝光
  2. 网页全文搜索字符和全局搜索文件名【Edge和谷歌浏览器均适用】
  3. 开源绘画应用 Pinta 已移植到GTK 3和.NET 6
  4. 如何形容自己的计算机水平,信息在计算机中的表示
  5. 一个值得收藏的小工具
  6. Dijkstra(狄克斯特拉)求加权重的邻接矩阵最短路径(初级版)
  7. jQuery Mobile中弹窗popup的data-*选项
  8. Android 控件 -------- AutoCompleteTextView 动态匹配内容,例如 百度搜索提示下拉列表功能...
  9. Android简单实现高德地图显示及定位
  10. xlsxwriter设置列宽_Python3之excel操作xlsxwriter模块
  11. 怎样彻底删除微信聊天记录?学会这招,从此不用再砸手机也不用泡水里
  12. ​​商朝是广西骆越人北上建立的政权,是骆越文化的延续
  13. 机器学习中的方差与偏差
  14. 安装jdk,没有jre
  15. 服务器虚拟化种类,服务器虚拟化的种类
  16. 计算机网络--自顶向下方法学习笔记
  17. android vitamio集成教程,集成Vitamio实现万能播放器(示例代码)
  18. 国内20家优秀的低代码平台/厂商汇总
  19. 《Docker系列》Docker安装Hadoop
  20. element——弹窗

热门文章

  1. Python实现将一张图片放到另一张图片指定的位置上并合成一张图
  2. UVa10019:Funny Encryption Method
  3. 常用的web服务器有哪些
  4. 液晶显示器不宜使用屏幕保护程序
  5. java pdfbox2 中文乱码_使用PdfBox实现pdf转图片,解决中文方块乱码等问题
  6. 【软件工具】之下载微软官方正版 windows 系统
  7. 日本与美国服务器比较
  8. NDK撩妹三部曲(四)—NDK 开发如何优雅的定位 Native 异常,看这篇就够了
  9. 架构师速成4.4-我该学什么语言
  10. Python numpy.testing.assert_warns函数方法的使用