1.Vue2.x组件通信有哪些方式?
1-1 父子组件通信
- 父->子props;子(emit)->父(on)
- 获取父子组件实例 parent/parent / parent/children 如:直接在子组件的methods方法里面写:this.$parent.show()//show为父组件中定义的方法
- Ref (如果在普通的 DOM 元素上使用,引用指向的就是 DOM 元素;如果用在子组件上,引用就指向组件实例),如在引入的子组件的标签上挂载一个: ref="comA",然后在方法中或者子组件的数据,this.$refs.comA.titles
- Provide、inject 官方不推荐使用,但是写组件库时很常用,祖先组件中通过provider来提供变量,然后在子孙组件中通过inject来注入变量
1-2 兄弟组件通信
- Event Bus 实现跨组件通信: Vue.prototype.$bus = new Vue
- Vuex
1-3 跨级组件通信
- Vuex
- attrs,listeners
- Provide、inject
1-4 使用
1. 父子props,on
// 子组件
<template>
<header>
<h1 @click="changeTitle">{
{title}}</h1>//绑定一个点击事件
</header>
</template>
<script>
export default {
data() {
return {
title:"Vue.js Demo"
}
},
methods:{
changeTitle() {
this.$emit("titleChanged","子向父组件传值");//自定义事件 传递值“子向父组件传值”
}
}
}
</script>
// 父组件
<template>
<div id="app">
<Header @titleChanged="updateTitle" ></Header>//与子组件titleChanged自定义事件保持一致
<h2>{
{title}}</h2>
</div>
</template>
<script>
import Header from "./Header"
export default {
data(){
return{
title:"传递的是一个值"
}
},
methods:{
updateTitle(e){ //声明这个函数
this.title = e;
}
},
components:{
Header
}
}
</script>
2. parent / $children与 ref
// A 子组件
export default {
data () {
return {
title: 'a组件'
}
},
methods: {
sayHello () {
alert('Hello');
}
}
}
// 父组件
<template>
<A ref="comA"></A>
</template>
<script>
export default {
mounted () {
const comA = this.$refs.comA;
console.log(comA.title); // a组件
comA.sayHello(); // 弹窗
}
}
</script>
3.attrs,listeners
attrs: 包含了父作用域
中不被 prop
所识别
(且获取) 的特性绑定 ( class 和 style 除外 )。当一个组件没有声明任何 prop 时,这里会包含所有父作用域的绑定 ( class 和 style 除外 ),并且可以通过 v-bind="$attrs" 传入内部组件。通常配合 inheritAttrs 选项一起使用。
listeners: :包含了父作用域中的 (不含 .native 修饰器的) v-on 事件监听器。它可以通过 v-on="$listeners" 传入内部组件
// index.vue
<template>
<div>
<h2>宇六岁呀</h2>
<child-com1 :foo="foo" :boo="boo" :coo="coo" :doo="doo" title="前端"></child-com1>
</div>
</template>
<script>
const childCom1 = () => import("./childCom1.vue");
export default {
components: { childCom1 },
data() {
return {
foo: "Javascript",
boo: "Html",
coo: "CSS",
doo: "Vue"
};
}
};
</script>
// childCom1.vue
<template class="border">
<div>
<p>foo: {
{ foo }}</p>
<p>childCom1的$attrs: {
{ $attrs }}</p>
<child-com2 v-bind="$attrs"></child-com2>
</div>
</template>
<script>
const childCom2 = () => import("./childCom2.vue");
export default {
components: {
childCom2
},
inheritAttrs: false, // 可以关闭自动挂载到组件根元素上的没有在props声明的属性
props: {
foo: String // foo作为props属性绑定
},
created() {
console.log(this.$attrs); // 父组件中的属性,且不在当前组件props中的属性。{ "boo": "Html", "coo": "CSS", "doo": "Vue", "title": "前端工匠" }
}
};
</script>
// childCom2.vue
<template>
<div class="border">
<p>boo: {
{ boo }}</p>
<p>childCom2: {
{ $attrs }}</p>
<child-com3 v-bind="$attrs"></child-com3>
</div>
</template>
<script>
const childCom3 = () => import("./childCom3.vue");
export default {
components: {
childCom3
},
inheritAttrs: false,
props: {
boo: String
},
created() {
console.log(this.$attrs); // / 父组件中的属性,且不在当前组件props中的属性。{"coo": "CSS", "doo": "Vue", "title": "前端工匠" }
}
};
</script>
// childCom3.vue
<template>
<div class="border">
<p>childCom3: {
{ $attrs }}</p>
</div>
</template>
<script>
export default {
props: {
coo: String,
title: String
}
};
</script>
4. Provide、inject的使用:
父组件
<template>
<div id="app">
</div>
</template>
<script>
export default {
data () {
return {
datas: [
{
id: 1,
label: '产品一'
}
]
}
},
provide {
return {
datas: this.datas
}
}
}
</script>
子组件
<template>
<div>
<ul>
<li v-for="(item, index) in datas" :key="index">
{
{ item.label }}
</li>
</ul>
</div>
</template>
<script>
export default {
inject: ['datas']
}
</script>