vue的父子孙之间组件通信和兄弟之间的组件通信
父子孙组件之间的组件通信
- 面试题:vue组件之间有哪些通信方式呢?
第一种:props+this.$emit:
props:
父组件A通过v-bind绑定数据,传递数据给子组件,子组件用props接收
父组件A:
<template><div class="parent-root"><child class="child" :message="message"> </child></div>
</template><script>
import child from "@/components/child";
export default {name: "parent",components: { child },data() {return {message:"霸霸的数据"};},</script>
子组件B:
<template><div class="child-root">父组件传来的消息:{{message}} </div>
</template><script>export default {name: 'child',props: ['message'],</script>
this.$emit:
父组件可以在使用子组件的地方直接用 v-on来监听子组件触发的事件,使用 v-on绑定自定义事件eventName,然后在子组件中使用 $emit(eventName,data)触发事件
父组件A:
子组件B:
第二种:style、class和自定义属性
父组件可以在子组件标签上添加style、class和自定义属性,子组件会合并到自己的根标签身上
父组件A:
<template><div class="parent-root"><child class="child" style="color:#ccc" datd-a="5" :message="message"> </child></div>
</template><script>
import child from "@/components/child";
export default {name: "parent",components: { child },data() {return {message:"霸霸的数据"};},</script>
子组件B:
<template><div class="child-root">父组件传来的消息:{{message}} </div>
</template><script>export default {name: 'child',props: ['message'],</script>
第三种:this.$attrs、this.$listeners和inheritAttrs
- 父子组件间的
this.$attrs
存放了父组件传过来的除style、class、自定义属性和props接收的属性之外的其他属性,通常配合 interitAttrs 选项一起使用 - 需要注意的是:子组件里使用props接收父组件传来的属性数据之后,该属性就不在
this.$attrs
里面存放了 - 父孙之间可以使用
this.$attrs
传递数据,就不需要在每一层的子组件里都使用v-bind和props层层传递了 this.$listeners
存放了父组件用v-on(不含 .native 修饰器)的绑定的所有事件,子组件可通过v-bind:$listeners
将所有事件传递给后面的孙组件inheritAttrs
:默认为true, 会自动在挂载组件元素上属性值,如props声明了属性,则挂载未被声明的属性;false时会关闭自动挂载到组件根元素上属性。注意:这个选项不影响 class 和 style 绑定。
父组件:
<template><div class="parent-root"><child class="child" :name="name" :age="age" :data="data" @change="change" @childEvent="childEvent"> </child><p>孙组件传出来的值:{{text}}</p></div>
</template><script>import child from "@/components/child";export default {name: 'parent',components: {child},data() {return {name:"小明",age:18,text:'',data:"me"};},methods: {//孙组件传出来的事件change(text) {this.text = text;},childEvent(name){console.log("name:",name);}},};
</script>
子组件:
孙组件:
inheritAttrs:
inheritAttrs
为true时:
inheritAttrs
为false时:
第四种: this.$parent和 this.$children
在组件内部,可以通过$parent
和$children
属性,分别得到当前组件的父组件和子组件实例
结果:
第五种:Provide
和Inject
父组件实例可以使用Provide
向后代组件传递数据,后代组件使用inject
来接收数据,
但是需要注意的是,使用这个方法传递的数据不是响应式的,然而,如果你传入了一个可监听的对象,那么其对象的 property 还是可响应的。
详细看:https://cn.vuejs.org/v2/api/?#provide-inject
父组件:
子组件:
第六种:v-model
v-model 专门用来做表单元素的当绑定在表单元素上时
- 当表单为输入表单,v-model最后会生成一个value属性和input事件
- 当绑定的是一个多选或者单选框,v-model最后生成一个checked属性和change事件
v-model
指令实质是一个语法糖,它是value
属性和input
事件的结合体
<input :value="data" @input="data=$event.target.value" />
<!-- 等同于 -->
<input v-model="data" />
详见:表单输入绑定
$event.target.value
获取触发事件的target,就是触发事件的DOM元素的value
**当v-model绑定在组件上时 ( 等同于prop+this.$emit ) **
- 父组件通过v-model传递值给子组件时,会自动传递一个value的prop属性,在子组件中通过this.$emit(‘input’,val)自动修改v-model绑定的值
<!-- 父组件 -->
<template> <Child v-model="value" />
</template>
等同于:
<template> <Child :value="value" @ />
</template>
<!-- 子组件 -->
<template><input v-model="input" />
</template>
<script>
export default {props: {value: String,},model: {prop: 'value', // 指定 v-model 要绑定的参数叫什么名字,来自于 props 中定义的参数event: 'change', // 指定要触发的事件名字,将被用于 $emit},computed: {input: {// 这里的计算属性使用了 getter、setter,可以简化代码// 可参见链接 https://cn.vuejs.org/v2/guide/computed.html#%E8%AE%A1%E7%AE%97%E5%B1%9E%E6%80%A7%E7%9A%84-setterget() {return this.value;},set(val) {this.$emit('change', val); // 触发}}}
}
</script>
第七种:.sync修饰符
和v-model
的作用类似,用于双向绑定,不同点在于v-model
只能针对一个数据进行双向绑定 ,只针对input事件的value值进行绑定,而sync
修饰符没有限制
示例
<!-- 父组件 -->
<template><div id="app"><Numbers :num1.sync="n1" :num2.sync="n2" /><!-- 等同于 --><Numbers:num1="n1"@update:num1="n1 = $event":num2="n2"@update:num2="n2 = $event"/></div>
</template><script>
import Numbers from "./components/Numbers.vue";export default {components: {Numbers,},data() {return {n1: 0,n2: 0,};},
};
</script>
第八种:$ref
父组件可以通过ref
获取到子组件的实例
- 不过这种做法一般是不得已的时候才会使用ref,因为ref,因为ref,因为ref会动用真实的DOM操作,与vue的减少对DOM元素的手动操作的理念有所违背
不局限于父子孙层级关系的跨组件通信:
(兄弟与兄弟)
第一种:vuex
适用于大型项目的数据仓库
第二种:store
模式
适用于中小型项目的数据仓库
// store.js
const store = {loginUser: ...,setting: ...
}// compA
const compA = {data(){return {loginUser: store.loginUser}}
}// compB
const compB = {data(){return {setting: store.setting,loginUser: store.loginUser}}
}
第三种:eventbus
组件通知事件总线发生了某件事,事件总线通知其他监听该事件的所有组件运行某个函数 (发布订阅模式)【vue3.0好像不支持事件总线的方式了?】
// 发送消息
EventBus.$emit(channel: string, callback(payload1,…))// 监听接收消息
EventBus.$on(channel: string, callback(payload1,…))
它的工作原理是发布/订阅方法,通常称为 Pub/Sub
。
var EventBus = new Vue();
Object.defineProperties(Vue.prototype, {$bus: {get: function () {return EventBus}}
})
在这个特定的总线中使用两个方法 $on
和 $emit
。一个用于创建发出的事件,它就是 $emit
;另一个用于订阅 $on
:
var EventBus = new Vue();
this.$bus.$emit('nameOfEvent', { ... pass some event data ...});
this.$bus.$on('nameOfEvent',($event) => {// ...
})
然后我们可以在某个Vue页面使用 this.$bus.$emit("sendMsg", '我是web秀');
,另一个Vue页面使用
this.$bus.$on('updateMessage', function(value) {console.log(value); // 我是web秀
})
同时也可以使用this.$bus.$off('sendMsg')
来移除事件监听。
第四种:router
如果一个组件改变了地址栏,所有监听地址栏的组件都会做出相应反应
最常见的场景就是通过点击router-link
组件改变了地址,router-view
组件就渲染其他内容
笔记相关的代码:
父组件:
<template><div class="parent-root"><childclass="child":name="name":age="age":data="data"@change="change"@childEvent="childEvent"></child><p>孙组件传出来的值:{{ text }}</p></div>
</template>
<script>
import child from "@/components/child";
export default {name: "parent",components: { child},provide: {foo: "bar",},data() {return {name: "小明",age: 18,text: "",data: "me",};},computed: {},created() {},methods: {//孙组件传出来的事件change(text) {this.text = text;},childEvent(name) {console.log("name:", name);},},
};
</script><style scoped lang="less">
.parent-root {padding: 20px;font-size: 16px;position: absolute;p {margin-bottom: 10px;}
}
</style>
子组件:
<template><div class="child-root"><grandchild v-bind="$attrs" v-on="$listeners"> </grandchild><br /><button @click="childEvent">子组件的childEvent</button><br />子组件用props接收了data的数据: {{ data }}</div>
</template><script>
import grandchild from "@/components/grandchild";
export default {name: "child",components: { grandchild },inject: ["foo"], props: ["data"],//inheritAttrs://默认为true, 会自动在挂载组件元素上属性值,如props声明了属性,则挂载未被声明的属性//为false时会关闭自动挂载到组件根元素上属性inheritAttrs: false,data() {return {};},computed: {},created() {console.log(this.foo);console.log("$attrs:", this.$attrs, "$listeners:", this.$listeners); //$attrs: { "name": "小明", "age": 18 },这里不会输出"class":"child"},mounted() {console.log("parent:", this.$parent, "children:", this.$children);},methods: {childEvent() {console.log("child的data:", this.data);},},
};
</script><style scoped lang="less">
.child-root {border: 1px solid #ccc;
}
</style>
孙组件:
<template><div class="grandchild-root"><p>name:{{name}}</p><p>age:{{age}}</p><p>data:{{data}}</p><button @click="bindChange">孙子点击传给爷爷</button></div>
</template>
<script>export default {name: 'grandchild',components: {},props: {name: {type: String,default: ''},age:{type: Number,default: null},data:{type: String,default: null}},methods: {bindChange() {let text = '爷爷,您好'this.$emit('change',text);}},};
</script>
整理笔记看的相关文章:
vue的通信:
https://blog.csdn.net/zhoulu001/article/details/79548350
https://blog.csdn.net/Dobility/article/details/110147985
https://blog.csdn.net/weixin_42211816/article/details/116529864
v-model原理:
https://blog.csdn.net/yun_hou/article/details/86313212
https://blog.csdn.net/weixin_42380658/article/details/86568666
修饰符:
https://blog.csdn.net/qq_29468573/article/details/80771625
事件总线:
https://blog.csdn.net/i168wintop/article/details/95107935
vue的父子孙之间组件通信和兄弟之间的组件通信相关推荐
- Vue第二天学习总结—— Vue全家桶之组件化开发(组件化开发思想、组件注册、Vue调试工具用法、组件间数据交互传递、组件插槽、基于组件的案例——购物车)
(一) 组件化开发思想 1. 现实中的组件化思想体现 组件化即是对某些可以进行复用的功能进行封装的标准化工作 标准:要想组件能够成功组合在一起,每个组件必须要有标准 分治:将不同的功能封装到不同的组件 ...
- Vue非父子组件之间的通信
文章目录 非父子组件的通信 1.Provide和Inject 1.1基本使用 1.2处理响应式数据(了解) 2.全局事件总线 非父子组件的通信 此篇讲解的是, 在学习状态管理之前, 非父子间通信的方案 ...
- Vue中父子及非父子组件之间的通信方法
Vue中父子及非父子组件之间的通信方法 父子组件之间的通信方法 父级->子级通信 (依赖单向数据绑定+props实现) Vue.component('Father', { //注册了含有data ...
- vue的父子组件之间的通信详解
vue的父子组件之间的通信详解 一.父组件给子组件传值 父组件引入子组件,并对子组件进行监听 <!-- 父组件 --><template><div><h1&g ...
- 【Vue】父子组件之间的通信
情景 父组件有一个 btnList 数组,里面存放着按钮的名称和按钮的id,现在要把这个数组传入到子组件中进行渲染. 子组件渲染出按钮后,点击按钮,父组件的 h1 标签中会显示出当前点击的按钮是哪一个 ...
- VUE非父子组件之间通信的几种方式
一.使用广播的方式$emit(), $on() 1.创建js文件 import Vue from 'vue'export default new Vue() 组件A import bus from ' ...
- vue中非父子组件通信
在上一篇博客中,我们总结了父子组件通信方式有:props + emit.这里我们将总结一下,非父子组件通信方式,这里还不涉及到Vuex. 如果存在祖孙组件,我们可以通过Provide和Inject进行 ...
- 实现非父子之间通信,兄弟组件之间的数据传递--eventBus
vue中,组件传值的方法常见的也就那几种, 1.父组件向子组件传值,用props 属性, 2.子组件主要通过事件传递数据给父组件子向父传数据可以用$emit触发传,但是这种方法无法实现兄弟组件直接传数 ...
- Vue中父子之间的通信
在学习vue中,往往会碰到父子组件之间的通信问题,用一张图来简单解释下父子之间如何通信 由图可以知道 父组件传递参数给子组件 子组件通过props接收参数 父子通信 代码演示: <!DOCTYP ...
最新文章
- Linux内核编译过程分析
- 【Spring】12、Spring Security 四种使用方式
- 结束oracle import,Oracle 结束 imp/exp 和 expdp/impdp 进程的正确方法
- Windows 运行... 可执行的命令
- php后台如何避免用户直接进入方法
- 深度系统安装移动硬盘启动_深度系统如何安装_电脑知识
- 【JZOJ3824】【NOIP2014模拟9.9】渴
- 黄俊:电商系统的一些心得分享
- 设置windows自动登录
- android随机抽奖代码_手机随机数字抽奖器APP下载-手机随机数字抽奖器最新版下载 v2.0.3安卓版-都去下载...
- FTPSFTP的基本命令
- PLSQL 教程 简单上手教程
- 中继器制作联动下拉列表
- Python 蓝凌OA任意文件读取批量扫描 poc编写
- 使用阿里云对象存储oos遇到跨域访问的问题
- 未来小七:AI缩小教育差距,让孩子快乐成长
- 苹果电脑可以装windows系统吗_iPhone 可以装 windows 了,想不想试试?
- 基于51单片机的宠物自动猫粮狗粮喂养机proteus仿真原理图PCB
- 如何判断是不是个maven项目
- 新冠疫情中的区块链应用
热门文章
- 《现代命令行工具指南》15.表情符号:在命令行中查找表情符号 - emoj
- 电子烟软件测试项目清单,电子烟分析测试报告-COSH.PDF
- windows强制复制不计算机,Win10复制粘贴功能用不了的修复方法
- Git快捷删除本地已经合并到master的分支
- springboot + Mybatis +前端layui 项目总结(一)
- 机器学习入门(九):非监督学习:5种聚类算法+2种评估模型
- 利用Gitee搭建私人仓库-https篇
- php 海关对接 进口商品_海关总署公布跨境进口统一版系统对接事项
- 阿里云emas远程真机使用指南
- CorelDRAW使用图文教程电子书