vue2中常见的组件通信方法

1,父传子:自定义事件配合props

父组件
<template>
  <div class="element">
    <h3>父组件</h3>
    <!-- 父组件向子组件传值通过自定事件 -->
    <son-com :abc="pimsg"></son-com>
  </div>
</template>

<script>
//导入子组件
import sonCom from '@/components/SonCom.vue'
export default {
  components: {
    sonCom
  },
  data () {
    return {
      pimsg: '我是父组件的值'
    }
  }
}
</script>
//子组件
<template>
  <div class="">
    <h4>子组件</h4>
    <p>父组件传过来的值:{{abc}}</p>
  </div>
</template>

<script>
export default {
  // 父组件传过来的值通过props接收,子组件便可以使用
  props: ['abc']
}
</script>

2,子传父 自定义事件配合 $emit

//子组件
<template>
  <div class="">
    <h4>子组件</h4>
    //子组件要向父组件传递值的按钮
    <input type="button" value="子组件传值" @click="sonbtn">
  </div>
</template>

<script>
export default {
  data () {
    return {
      sondata: '我是子组件的值'
    }
  },
  methods: {
    sonbtn () {
      // 子传父,需要通过自定义事件来实现
      // 1. 注册自定义事件 -- 注意 自定义事件名不要使用驼峰命名法!
      this.$emit('son-btn', { sondata: this.sondata })
    }
  },
}
</script>
//父组件
<template>
  <div class="element">
    <h3>父组件</h3>
    <!-- son-btn是子组件注册的自定事件,里面携带着要传递的参数 -->
    <son-com @son-btn="sonbtns($event)"></son-com>
  </div>
</template>

<script>
import sonCom from '@/components/SonCom.vue'
export default {
  components: {
    sonCom
  },
  data () {
    return {
      pimsg: '我是父组件的值'
    }
  },
  methods: {
    sonbtns (val) {
    // val===> { "sondata": "我是子组件的值" }
      this.pimsg = val.sondata
    }
  }
}
</script>

3,兄弟组件之间的传递 -eventBus事件总线

新建一个.js的文件作为中间件
作为事件中心管理组件之间的通信

import Vue from 'vue'
// 定义一个新的vue实例作为事件中心,利用它来监听本身的自定义事件
const tmpCom = new Vue()
export default tmpCom
//兄弟组件之====>大兄弟
<template>
  <div class="">
    <h4>第一个兄第组件</h4>
    <input type="button" value="我是大兄弟" @click="maxbrother">
  </div>
</template>

<script>
 //引入中间件
import tmpCom from '@/router/middleware'
export default {
  data () {
    return {
      brotherdata: '我是大兄弟'
    }
  },
  methods: {
    maxbrother () {
       // 触发事件中心的max-brother事件 
      tmpCom.$emit('max-brother', this.brotherdata)
      console.log(this.brotherdata)
    }
  },
  created () {}
}
</script>
//兄弟组件之====>小兄弟
<template>
  <div class="">
    <h4>第二个兄第组件</h4>
    <p>{{brother}}</p>
  </div>
</template>

<script>
//引入中间件
import tmpCom from '@/router/middleware'
export default {
  data () {
    return {
      brother: '我是小兄弟'
    }
  },
  mounted () {
      // 监听事件中心的max-brother事件
     // 这里的第二个参数必须使用箭头函数
    tmpCom.$on('max-brother', val => {
      this.brother = val
    })
  }
}
</script>

4,注入依赖provide/inject使用

这种方式就是vue中依赖注入,该方法用于 父子组件之间 的通信。当然这里所说的父子不一定是真正的父子,也可以是祖孙组件,在层数很深的情况下,可以使用这种方式来进行传值。就不用一层一层的传递数据了。

provide和inject是vue提供的两个钩子,和data、methods是同级的。并且provide的书写形式和data一样。

  • provide 钩子用来发送数据或方法。
  • inject钩子用来接收数据或方法
//父组件  
data () {
    return {
      pimsg: '我是父组件的值',
      num: 99999
    }
  },
  provide () {
    return {
      num: this.num
    }
  },

//子组件
 inject: ['num'],

5,ref / $refs

这种方式也是实现父子组件之间的通信

ref:这个属性用在子组件上,它的用法就指向了子组件的实例,可以通过实例来访问组件的数据和方法

//子组件
export default {
    data () {
    return {
      name: '我是张三'
    }
  },
  methods: {
    sayHello () {
      console.log('我是李四')
    }
  }
}
//父组件
<template>
  <child ref="child"></child>
</template>

<script>
  import child from './child.vue'
  export default {
    components: { child },
    mounted () {
      console.log(this.$refs.child.name);  // '我是张三'
      this.$refs.child.sayHello();  // 我是李四
    }
  }
</script>

6,parent /children

  • 使用$parent可以让组件访问父组件的实例(访问的是上一级父组件的属性和方法)。
    使用 $children 可以让组件访问子组件的实例,但是, $children 并不能保证顺序,并且访问的数据也不是响应式的。
    
    //子组件
    <template>
      <div>
        <span>{{message}}</span>
        <p>获取父组件的值为:  {{parentVal}}</p>
      </div>
    </template>
    
    <script>
    export default {
      data() {
        return {
          message: '张三'
        }
      },
      computed:{
        parentVal(){
          return this.$parent.msg;
        }
      }
    }
    </script>
    
    
//父组件
<template>
  <div class="hello_world">
    <div>{{msg}}</div>
    <child></child>
    <button @click="change">点击改变子组件值</button>
  </div>
</template>

<script>
import child from './child.vue'
export default {
  components: { child },
  data() {
    return {
      msg: 'abc'
    }
  },
  methods: {
    change() {
      // 获取到子组件
      this.$children[0].message = '李四'
    }
  }
}
</script>

通过 $parent 访问到的是上一级父组件的实例,可以使用 $root 来访问根组件的实例
在组件中使用$children拿到的是所有的子组件的实例,它是一个数组,并且是无序的
在根组件 #app 上拿 $parent 得到的是 new Vue()的实例,在这实例上再拿 $parent 得到的是undefined,而在最底层的子组件拿 $children 是个空数组
$children 的值是数组,而 $parent是个对象
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,524评论 5 460
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,869评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,813评论 0 320
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,210评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,085评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,117评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,533评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,219评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,487评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,582评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,362评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,218评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,589评论 3 299
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,899评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,176评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,503评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,707评论 2 335

推荐阅读更多精彩内容