Vue组件通信

1、父组件=>子组件,属性传递

父组件:传值

<HelloWorld msg="Welcome to your vue app" />

子组件:接收

props{

  msg: String

}

2、父组件=>子组件,使用ref传值

此处使用mounted而不是使用created,因为挂载时子组件才加载完成,才能访问到子组件

父组件先于子组件创建

父组件

<HelloWorld msg="Welcome to Your Vue.js App"
    ref="hw"/>

export default {
  components: {
    HelloWorld
  },
  mounted () {
    this.$refs.hw.foo = 'abcabc'
  }
}

子组件

<div class="hello">
    <h1>{{ msg }}</h1>
    {{foo}}
</div>


data(){
    return{
      foo: 'foo'
    }
}

页面的{{ foo }}  部分,会显示abcabc

3、父组件=>子组件,使用$children

mounted(){

  this.$children[0].foo = 'dong'    // 在此处可以访问到这个子组件

}

页面的{{ foo }}  部分,会显示 dong

这种方式,子元素(this.$children)不保证顺序,也不响应式(只读)---不推荐使用

this.$children中的foo值是响应式的

4、子组件=>父组件,自定义事件

原理:子组件派发事件,父组件监听事件(观察者模式)

// child
// foo为派发的事件名,bar为传参
<h1 @click="$emit('foo', 'bar')">test</h1>

// parent
<HelloWorld @foo="onFoo" />
methods:{
  onFoo(){
    console.log('onFoo')
  }
}

// 有传参的情况(传一个参数)
// child
<h1 @click="$emit('foo', 'bar')">test</h1>
// parent
<HelloWorld @foo="onFoo($event)" />
methods:{
  onFoo(e){
    console.log(e)
  }
}

// 有传参的情况(传多个参数)
// child
<h1 @click="$emit('foo', 'bar', 'dong')">test</h1>
// parent
<HelloWorld @foo="onFoo(arguments)" />
methods:{
  onFoo(arg){ // 此处agr会以数组的形式传入
    console.log(arg)
  }
}

事件的派发者是谁,事件的监听者就是谁

5、兄弟组件

通过共同的祖辈搭桥,$parent   或者  $root,(parent找父节点,root找根节点)

// HelloWorld组件中,通过父组件搭桥
<div class="hello" @click="$parent.$emit('mua')">
 HelloWorld
</div>

// Log组件中,监听父组件中的mua事件
created () {
    this.$parent.$on('mua', () => {
        console.log('muamua');
    })
}

此时点击HelloWorld,会输出  muamua

6、祖先和后代之间(隔代传值)

由于嵌套过多,使用props不切实际,vue提供了provide和inject  API来完成该任务(常用于组件库开发)

// 父组件
provide: {dong: 'dong'},
mounted () {  }

// 子组件
inject: ['dong'],
props: {
    msg: String
}

甚至可以将祖先作为this传入

// 父组件
data(){
  return{
    dong: 'dong'
  }
},
provide(){
  return{ dong: this }
}

// 子组件
<div>
    {{foo}} - {{dong.dong}}
</div>
inject: ['dong'],
data(){
  return{
    foo: 'foo'
  }
}

这种方式,只能祖先代给子辈代传值,反过来不行

平常开发时少用,主要用于组件库的开发

如果想改provide中的值,在provide时传入一个set的函数

provide(){

  dong: 'dong',

  setDong: this.xx

}

子组件通过调用setDong来更改dong的值

7、任意两个组件之间传参(事件总线  or  vuex)

(1)事件总线:创建一个Bus类进行事件派发、监听和回调管理

// Bus:事件派发,监听和回调管理
class Bus{
  constructor(){
    this.callbacks = {}
  }
  $on(name, fn){
    this.callbacks[name] = this.callbacks[name] || []
    this.callbacks[name].push(fn)
  }
  $emit(name, args){
    if(this.callbacks[name]){
      this.callbacks[name].forEach(cb => cb(args))
    }
  }
}

// main.js
Vue.prototype.$bus = new Bus()
// 也可以直接 Vue.prototype.$bus = new Vue()
// 因为Vue中已经实现了这些

// child1
this.$bus.$on('foo', handle)
// child2
this.$bus.$emit('foo')

(2)vuex

创建一个唯一的全局数据管理者store,通过它管理数据并通知组件状态变更

原文地址:https://www.cnblogs.com/haishen/p/11276377.html