Vue组件间的通信

父组件向子组件传值

父组件通过 v-bind 绑定 message 值到子组件的 prop.

1
<template>
2
  <div id="app">
3
    <Children v-bind:message="message"></Children>
4
  </div>
5
</template>
6
<script>
7
import Children from "./components/Children"
8
export default {
9
  name: 'Parents',
10
  data(){
11
    return{
12
      message:"父组件传递数据到子组件"
13
    }
14
  },
15
  components:{
16
    "Children":Children
17
  }
18
}
19
</script>

子组件通过 props 获取到父组件的值,即可渲染

1
<template>
2
  <div id="app">
3
    {message}
4
  </div>
5
</template>
6
<script>
7
export default {
8
  name: 'Children',
9
   props: ['message'],
10
}
11
</script>

子组件向父组件传值

父组件通过 v-on:changeInput="updateInput", 绑定一个自定义事件 changeInput,当子组件触发时调用事件回调函数updateInput

1
<template>
2
  <div id="app">
3
    <Children v-on:changeInput="updateInput"></Children>
4
  </div>
5
</template>
6
<script>
7
import Children from "./components/Children"
8
export default {
9
  name: 'Parents',
10
  data(){
11
    return{
12
      input:"默认值"
13
    }
14
  },
15
  components:{
16
    "Children":Children
17
  },
18
  methods:{
19
    updateInput(e){
20
        this.input = e; 
21
    }
22
  }
23
}
24
</script>

子组件通过$emit,触发父组件的自定义事件changeInput,来传递值到父组件

1
<template>
2
  <div id="app">
3
    <input type="text" v-on:click="changeInput">
4
  </div>
5
</template>
6
<script>
7
export default {
8
  name: 'Children',
9
  methods:{
10
    changeInput(){
11
        this.$emit('changeInput','子向父组件传值')
12
    }
13
  }
14
}
15
</script>

兄弟间通信

同级传参或者隔级传参可以用eventBus.这种方法通过一个空的Vue实例作为中央事件总线,然后给每个子组件绑定一个方法(触发时候发布eventBus),在 每个子组件做一个订阅的监控,触发绑在created里的方法执行,靠传递参数的不同实现同步数据

首先创建一个空的Vue实例:

1
import Vue from 'vue';  
2
export default new Vue();

然后创建A组件,定义一个click点击事件,每次点击都会在bus中触发这个名为’click’的事件,并将点击事件的event.target顺着事件传递出去。:

1
<template>
2
  <div id="app">
3
  </div>
4
</template>
5
<script>
6
import Bus from './Bus'
7
export default {
8
  name: 'A',
9
  methods:{
10
    clickA(event){
11
        Bus.$emit('click', event.target);  
12
    }
13
  }
14
}
15
</script>

创建B组件,在created中调用Bus监听或者事件:

1
<template>
2
  <div id="app">
3
  </div>
4
</template>
5
<script>
6
import Bus from './Bus'
7
export default {
8
  name: 'B',
9
    created() {  
10
            Bus.$on('click', target => {  
11
                console.log(target);  
12
            });  
13
    }
14
}
15
</script>

$attrs/$listeners

  • $attrs: 包含了父作用域中不作为 prop 被识别 (且获取) 的特性绑定 (class 和 style 除外)。当一个组件没有声明任何 prop 时,这里会包含所有父作用域的绑定 (class 和 style 除外),并且可以通过 v-bind=”$attrs” 传入内部组件——在创建高级别的组件时非常有用。
  • $listeners: 包含了父作用域中的 (不含 .native 修饰器的) v-on 事件监听器。它可以通过 v-on=”$listeners” 传入内部组件——在创建更高层次的组件时非常有用
1
<template>
2
  <div>
3
    <child1
4
      :a="a"
5
      :b="b"
6
      :c="c"
7
      :d="d"
8
      title="title"
9
     v-on:click1="onclick1"
10
    ></child1>
11
  </div>
12
</template>
13
<script>
14
import child1 from './child1.vue'
15
export default {
16
  components: { child1 },
17
  data() {
18
    return {
19
      a: "Javascript",
20
      b: "Html",
21
      c: "CSS",
22
      d: "Vue"
23
    };
24
  },
25
  methods:{
26
    onclick1(){
27
        console.log("click1 running...");
28
    }
29
  }
30
};
31
</script>
1
<template>
2
  <div>
3
    <div>{{this.$attrs}}</div>
4
    <child2
5
    v-bind="$attrs"
6
    v-on="$listeners"
7
    />
8
  </div>
9
</template>
10
<script>
11
import child2 from './child2.vue'
12
export default {
13
  components: { child2 },
14
  inheritAttrs: false,
15
  created() {
16
// { "a": "Javascript","b": "Html", "c": "CSS", "d": "Vue", "title": "前端工匠" }
17
      console.log(this.$attrs); 
18
  }
19
};
20
</script>
1
<template>
2
  <div>
3
    <div>{{this.$attrs}}</div>
4
    <button v-on:click="$emit('click1','按钮点击')">触发事件</button>
5
  </div>
6
</template>
7
<script>
8
export default {
9
   created() {
10
      console.log(this.$attrs); 
11
    }
12
};
13
</script>

provide/inject

在A组件设置 provide 属性 name 值为 fireworks,它将这个name提供给了它所有的子组件。在它的子组件 B 中,通过 inject 注入了从 A 组件中提供的 name 变量,所以 this.name 就等于 fireworks.
但是它们并不是响应式的,所以 A 里面的name改变了,B还是 fireworks。然而,如果你传入了一个可监听的对象,那么其对象的属性还是可响应的。

1
// A.vue
2
export default {
3
  provide: {
4
    name: 'fireworks'
5
  }
6
}
1
// B.vue
2
export default {
3
  inject: ['name'],
4
  mounted () {
5
    console.log(this.name);  // fireworks
6
  }
7
}