Vue中父子及非父子组件之间的通信方法

父子组件之间的通信方法

父级->子级通信 (依赖单向数据绑定+props实现)
    Vue.component('Father', { //注册了含有data属性的父组件template: '#father',data () {return {val : 100,sav : 555}},});Vue.component('Son', { //注册了没有data的子组件template: '#son',});

可见,父级中有val、sav两条数据,如果其子组件可以使用自身的数据,首先需要的就是在子组件内部添加props属性

 Vue.component('Son', {template: '#son',//props:[数组内可有一个或多个参数]       props: ['val','sav']//props声明即表示该组件会使用父组件的数据});

为了语义化提升代码的可读性,推荐将参数名与父组件的属性名相同。

在渲染模板上将相应的参数名绑定在子组件上即可:

    <template id="father"><div><h4>我是父组件</h4><hr><!-- 将父组件数据分别绑定在props中声明的参数上 --><!-- :props参数名 = '父组件数据' --><Son :val = 'val' :sav = 'sav'></Son></div></template><template id="son"><h4>我是子组件,我拿到了父组件的val:{{val}},以及:{{sav}}</h4></template>

浏览器中结果如下:

子级 -> 父级通信 (依赖自定义事件)

和父子通信依靠props属性不同,在子父通信中我们需要使用自定义事件的方法。

Vue中的自定义事件

不同于点击事件、监听事件等等依托一个特定媒介去触发事件内部函数方法,

自定义事件依靠this.$emit()触发事件,例如:

<!-- 通过v-on事件绑定,我们在该标签上绑定了一个自定义方法test -->
<my-component v-on:test="any"></my-component>
//使用this.$emit()触发事件
this.$emit('test')

需要注意的是,Vue文档中提示自定义事件的事件名会在DOM模板中被自动转换为小写。

不同于组件和 prop,事件名不会被用作一个 JavaScript 变量名或属性名,所以就没有理由使用 camelCase 或 PascalCase 了。并且 v-on 事件监听器在 DOM 模板中会被自动转换为全小写 (因为 HTML 是大小写不敏感的),所以 v-on:myEvent 将会变成 v-on:myevent——导致 myEvent 不可能被监听到。

使用自定义事件实现子父通信

​ 在父组件中设置自定义事件(父组件内部定义了一个byson方法)

    Vue.component('Father', {template: '#father',data () {return {val : 100,sav : 555}},methods: {byson ( val ) { //定义方法this.val = val;}}});

​ DOM模板中设定自定义事件,为了更好区分关系自定义事件名设置为’bysons’

    <template id="father"><div><input type="text" v-model = 'val'><h4>我是父组件</h4><hr>
<!-- 在父组件中的子组件上绑定自定义事件byson1,这样就可以在点击事件触发时通过                                         this.$emit()调用方法 --><Son @bysons = 'byson'></Son></div></template>

​ 子组件中设定事件触发这个自定义事件(这里使用的是点击事件)

    Vue.component('Son', {template: '#son',data() {return {son: 669}},methods: {press() {//this.$emit('时间名',可选参数) 此处将子组件私有的son作为参数传递给父组件this.$emit('byson1', this.son);}},props: ['getFather', 'getSav']});

​ 将点击事件绑定在子组件后,即可实现子->父通信功能,逻辑如下:

父组件中设定自定义事件 -> 子组件设置点击事件,执行触发父组件中的自定义事件。

非父子组件之间的通信

通过ref链实现

​ ref是什么

在Vue实例对象下有一个refs属性,其内容包含了所以作用域内组件的具体信息,利用ref实现非父子组件通信的核心逻辑就是通过操作$refs作为一个中间件来进行数据交换。

简单例子:通过点击事件改变一个非父子关系组件的样式

<body><div id="app"><button @click = "getP">get</button><p ref = "box"> 123 </p>  //在标签中添加ref = 'name'来添加标识<p ref > 123 </p><Hello ref = "hello"></Hello></div>
</body>
<script>Vue.component('Hello',{template: '<div></div>',data () {return {money: 1000}}})new Vue({el: '#app',methods: {getP () {//通过refs操作box的样式this.$refs.box.style.background = 'red'}}})
</script>

refs的特点:除了对组件有效,$refs对DOM元素也有效,但是它的性能较差,不推荐使用。

更方便高效的思路 — 事件总线

因为$refs性能低下的问题,所以产生了另外一条思路:将数据托管在一个公共(全局属性)的中间件上,这样无论是不是存在父子关系都可以访问的到其内部的数据。

如何实现?

  1. 全局定义一个公共的Vue实例对象bus,用于存储数据

  2. 利用自定义事件发布和触发,实现通信

下面例子中,通过中间件bus,实现了非父子组件之间数据的交换:

<body><div id="app"><key-in></key-in><print-out></print-out></div><template id="in"><!-- 和add属性双向绑定 --><input type="text" v-model="add" @keyup.enter="addNew" /></template><template id="out"><ul><li v-for="item in lists">{{ item.text }}</li></ul></template>
</body>
<script src="../../lib/vue.js"></script>
<script>// bus事件总线思维: 将new Vue() 的实例作为全局变量,用来联通非父子组件var bus = new Vue();//注册组件Vue.component("keyIn", {template: "#in",data() {return {add: ""};},methods: {addNew() {//触发bus上的自定义事件pushInbus.$emit("pushIn", this.add);this.add = "";}}});//输出组件上绑定有一个数据数组用于渲染列表Vue.component("printOut", {template: "#out",data() {return {lists: [{id: 1,text: "测试"}]};},mounted() {//保存指向该组件的this指针var _this = this;// $on关键词设定bus上的自定义事件,将新数据push进数组中bus.$on("pushIn", function (val) {var list = {id: _this.lists.length + 1,text: val};_this.lists.push(list);});}});new Vue({el: "#app"});
</script>

Vue中父子及非父子组件之间的通信方法相关推荐

  1. 「后端小伙伴来学前端了」Vue中Props配合自定义方法实现组件间的通信

    校园的云 前言 废话: 上篇文章写了关于Vue 中的 props

  2. Vue中基于Vuex使用echarts组件动态数据绑定的方法

    效果如下: 1.导入echarts组件,建议使用4.9.0版本,5.0.1可能会报错 npm uninstall echarts //卸载npm install echarts@4.9.0//引入特定 ...

  3. Vue组件通信:任意组件之间进行通信

    之前一篇博客,我们介绍了子组件向父组件通信的方法,可以参考博客: 深度理解Vue组件的子组件向父组件传递数据的通信方式,全面详细,看这一篇就够了,推荐收藏_czjl6886的博客-CSDN博客 今天, ...

  4. Vue非父子组件之间的通信

    文章目录 非父子组件的通信 1.Provide和Inject 1.1基本使用 1.2处理响应式数据(了解) 2.全局事件总线 非父子组件的通信 此篇讲解的是, 在学习状态管理之前, 非父子间通信的方案 ...

  5. Vue中关于父子组件之间的通信

    父子组件之间的通信是vue中的基础知识,在此做一个简单的梳理. 总的来说父传子是通过props,子传父是通过$emit. 简单的一个demo来说说,先上代码 父组件: 如图,HelloWorld是一个 ...

  6. vue/父子组件之间的通信

    父子组件之间的通信 父组件绑定数据在组件上子组件props属性接收 父组件内的data属性中待传的数据data1 => <cpn :data2="data1">& ...

  7. vue父子组件之间传值的方法

    vue父子组件之间传值的方法 一.基本父子传值 父传子 方式: props 效果: 把父组件的fatherName属性传入子组件,在子组件中使用 父组件代码: <template>< ...

  8. vue的父子组件之间的通信详解

    vue的父子组件之间的通信详解 一.父组件给子组件传值 父组件引入子组件,并对子组件进行监听 <!-- 父组件 --><template><div><h1&g ...

  9. VUE 2.0 父子组件之间的通信

    父组件是通过props属性给子组件通信的来看下代码: 父组件: <parent><child :child-com="content"></child ...

最新文章

  1. Hibernate5.x Idea搭建
  2. Linux中look命令,如何在Linux上使用look命令 | MOS86
  3. 为什么python不出结果_Python 的 Checksum 为什么结果是一长串数字而不是如下效果...
  4. JZOJ 5305. 【NOIP2017提高A组模拟8.18】C
  5. 天天象棋 残局闯关 第15关
  6. .Net Core中使用ref和Spanamp;lt;Tamp;gt;提高程序性能
  7. 绘制几何图形——使用android.graphics类 onDraw
  8. 通过两个小栗子来说说Java的sleep、wait、notify、notifyAll的用法
  9. 玩转Android Camera开发(一):Surfaceview预览Camera,基础拍照功能完整demo
  10. Caffe学习:Blobs, Layers, and Nets
  11. 计算机打字键盘亮怎么设置,键盘指示灯亮着却不能打字的解决方法
  12. ubuntu20.04 NVIDIA显卡驱动安装教程(Y9000p)
  13. MBP清除NVRAM和PRAM
  14. 7-3 寻找大富翁 (50分)
  15. PDF文件怎么拆分页面
  16. 启动vidalia 时不用打开firefox
  17. 使用Unity3D制作Flappy Bird
  18. duet太香啦啦啦啦啦啦啦啦啦啦
  19. 对抗网络之PG-GAN,无条件下生成更真实的人脸图像
  20. 从打车到专车,滴滴们除了烧钱还有什么?

热门文章

  1. Freeswitch配置之sofia
  2. SpringFabMenu
  3. java时钟日历_java日历时钟小程序
  4. 红米Note4X 刷机LineageOs 14.1全过程讲解
  5. 求两个集合的交集,并集,差集
  6. devexpress皮肤设置
  7. 苹果充电器怎么辨别真假_三星或考虑取消附赠耳机充电器 降低产品售价或成本...
  8. 唐代白居易《燕诗示刘叟 》
  9. 基于百度地图开发网易班车地图导航展示
  10. 一天300个快递,康小康团队都撸些什么商品回来?