如何在vue 中使用组件,以及组件通信的方式(父传子/子传父/兄弟传)
文章目录
- 前言
- 零、如何使用封装组件
- 一、为什么需要下面的通信方式
- 二、父组件给子组件通信
- 三、子组件给父组件通信
- 四、兄弟组件通信
- 五、多层组件之间的通信
- 总结
前言
组件可以说是 vue 中最为核心的一部分了,通过组件化,可以使得整个项目的创建更加的高效和便捷。下面我主要是介绍学习的关于组件的通信方式。
零、如何使用封装组件
一般我们在一个 vue 项目中,项目的结构就如官网给出的下图这般:
我们的项目分为由很多个组件来构成一个整体,这有什么好处呢?我个人觉得,有下面几点:
- 可复用:往往某些部分我们会多次用到,通过抽离成组件,我们只需要引用,不仅减少工作量,还减少了
- 结构化,我们对整个项目更加的条理和清晰,当出现问题也能便捷的定位和处理更换。
简单介绍在项目中使用吧!我们用脚手架创建了一个项目,那么里面会有一个 components文件夹就是用来存放组件的。我们可以在这里创建我们使用到的组件。组件的格式以下面:
<template></template><script>
export default {name: 'TemplateExplainDialog',}
</script><style scoped></style>
组件的几个注意点就是:
- 命名一般以大写字母开头
- date里面是函数
- 每一个组件相当于一个vue的实例,所以有独立的生命周期等等
在使用上,我们创建好组件后,我们在需要使用到该组件的地方中
- 引入该组件文件
- 在components声明
- 然后使用就好了
- 建立组件的模板,根据需求实现结果和样式
- 分析数据的接收和输出,比如使用到的 props 和 emit等
- 父组件中调用和实例化
完整的使用方式,可以参考下方的代码案例。
一、为什么需要下面的通信方式
首先我们需要知道,在 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 中使用组件,以及组件通信的方式(父传子/子传父/兄弟传)相关推荐
- class根据状态 vue_搞懂并学会运用 Vue 中的无状态组件
啥是应用程序状态,为什么咱们需要它? 状态管理通常在较小的项目并不需要,但是当涉及到更大的范围时,如企业级的应用大部分需要它了.简单的说,状态是一个包含应用程序使用的最新值的对象.但是,如果咱们从结构 ...
- [vue] vue中什么是递归组件?举个例子说明下?
[vue] vue中什么是递归组件?举个例子说明下? 组件自己调用自己,场景有用于生成树形结构菜单 个人简介 我是歌谣,欢迎和大家一起交流前后端知识.放弃很容易, 但坚持一定很酷.欢迎大家一起讨论 主 ...
- vue中集成的ui组件库_Vue组件可使用Vault Flow通过Braintree集成PayPal付款
vue中集成的ui组件库 Vue Braintree PayPal按钮 (Vue Braintree PayPal button) Vue component to integrate PayPal ...
- Revit建模软件:如何在Revit中准确放置族组件?
Revit建模软件:如何在Revit中准确放置族组件? 如何在Revit中准确放置族组件?今天,我们以螺丝为例来解释这个问题. 设置工作面: 你需要的工作平面是一个垂直或有角度的平面. 如图所示,蓝色 ...
- 有关QJ_Filecenter在vue中的使用和组件封装
有关QJ_Filecenter在vue中的使用和组件封装 QJ_FileCenter在vue中的使用和组件封装 安装 第一步:在官网下载QJ_FileCenter安装包 第二部:访问FileCente ...
- vue中,右键菜单组件v-contextmenu的使用
vue中,右键菜单组件v-contextmenu的使用 1.效果 右键菜单之禁用和子菜单 2.流程 第一步:安包 npm install v-contextmenu --save-dev npm in ...
- Vue中如何扩展⼀个组件
Vue中如何扩展⼀个组件 按照逻辑扩展和内容扩展来列举: 逻辑扩展有:mixins.extends.composition api: 内容扩展有: slots: 一.Mixin 组件和组件之间有时候会 ...
- vue 递归创建菜单_如何在Vue中创建类似中等的突出显示菜单
vue 递归创建菜单 by Taha Shashtari 由Taha Shashtari 如何在Vue中创建类似中等的突出显示菜单 (How to Create a Medium-Like Highl ...
- 如何在 Vue 中使用 Chart.js - 手把手教你搭可视化数据图表
本文首发:<如何在 Vue 中使用 Chart.js - 手把手教你搭可视化数据图表> 使用 Chart.js 在 Vue 搭建的后台管理工具里添加炫酷的图表,是所有数据展示类后台必备的功 ...
- 如何在 Vue 中导出数据至 Excel 表格 - 卡拉云
本文首发:<如何在 Vue 中导出数据至 Excel 表格 - 卡拉云> 我们经常需要在 Vue 搭建的后台管理系统里导出数据到 Excel / CSV ,方便我们将数据共享给其他同学或在 ...
最新文章
- SSH暴力破解IP大曝光
- 网页全文搜索字符和全局搜索文件名【Edge和谷歌浏览器均适用】
- 开源绘画应用 Pinta 已移植到GTK 3和.NET 6
- 如何形容自己的计算机水平,信息在计算机中的表示
- 一个值得收藏的小工具
- Dijkstra(狄克斯特拉)求加权重的邻接矩阵最短路径(初级版)
- jQuery Mobile中弹窗popup的data-*选项
- Android 控件 -------- AutoCompleteTextView 动态匹配内容,例如 百度搜索提示下拉列表功能...
- Android简单实现高德地图显示及定位
- xlsxwriter设置列宽_Python3之excel操作xlsxwriter模块
- 怎样彻底删除微信聊天记录?学会这招,从此不用再砸手机也不用泡水里
- ​​商朝是广西骆越人北上建立的政权,是骆越文化的延续
- 机器学习中的方差与偏差
- 安装jdk,没有jre
- 服务器虚拟化种类,服务器虚拟化的种类
- 计算机网络--自顶向下方法学习笔记
- android vitamio集成教程,集成Vitamio实现万能播放器(示例代码)
- 国内20家优秀的低代码平台/厂商汇总
- 《Docker系列》Docker安装Hadoop
- element——弹窗
热门文章
- Python实现将一张图片放到另一张图片指定的位置上并合成一张图
- UVa10019:Funny Encryption Method
- 常用的web服务器有哪些
- 液晶显示器不宜使用屏幕保护程序
- java pdfbox2 中文乱码_使用PdfBox实现pdf转图片,解决中文方块乱码等问题
- 【软件工具】之下载微软官方正版 windows 系统
- 日本与美国服务器比较
- NDK撩妹三部曲(四)—NDK 开发如何优雅的定位 Native 异常,看这篇就够了
- 架构师速成4.4-我该学什么语言
- Python numpy.testing.assert_warns函数方法的使用