【前端学习 -Vue (7) Vue2.x组件通信有哪些方式?】

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>

猜你喜欢

转载自blog.csdn.net/weixin_60364883/article/details/126715413