vue2中 组件之间的通信

本文详细介绍了Vue2中组件间的通信方式,包括props和this.$emit实现父子传参,$attrs和$listeners用于祖孙组件通信,通过this.parent和this.children直接引用,provide和inject进行祖先到后代的数据注入,以及利用bus实现兄弟组件间通信。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1、prors 和 this.$emit ( 父子之间的传参 )

// 组件A
<template>
  <div id="app">
    <HelloWorld :data1="data1" @addData="addData" />
  </div>
</template>

// 组件B
<template>
  <div class="hello">
    <h1>{{data1}}</h1>
    <button @click="add">点击加1</button>
  </div>
</template>
// 组件A
<script>
import HelloWorld from "./components/HelloWorld.vue"
export default {
  name: "App",
  components: {
    HelloWorld,
  },
  data() {
    return {
      data1:1,
    }
  },
  methods:{
    addData (val) {
      this. data1++
      console.log(val) // 这里打印的是B组件发送过来的信息
    },
  }
};
</script>
// 组件B
<script>
export default {
  name: 'HelloWorld',
  props: {
    data1:Number
  },
  methods:{
    add () {
      this.$emit("addData","1111") // 发送事件给A组件
    }
  }
}
</script>

2、$attrs 和 $listeners ( 用于祖孙之间传参 )

// 组件A
<template>
  <div id="app">
  <!-- A 向 B组件 传递了两个变量data1、data2-->
    <HelloWorld :data2="data2" :data1="data1" v-on:getCData="getCData"/>
    <!-- v-on:getCData="getCData" 用来接受组件c里发送的事件,从而实现通信 -->
    <Test :myName="myName"></Test>
  </div>
</template>
// 组件B
<template>
  <div class="hello">
    <h1>{{data1}}</h1>
	<!-- C组件中能直接触发getCData(A组件中的方法)的原因在于 B组件调用C组件时 使用 v-on 绑定了$listeners 属性 -->
	<!-- 通过v-bind 绑定$attrs属性,C组件可以直接获取到A组件中传递下来的props(除了B组件中props声明的) -->
    <child v-bind="$attrs" v-on="$listeners"></child>
  </div>
</template>
// 组件C
<template>
  <div>
   <h2> 这是h组件下的child组件 </h2>
   <button @click="send">点击和app组件通信</button>
   <h5>这是app里的数据,{{$attrs.data2}}</h5>
  </div>
</template>
// 组件A
import HelloWorld from "./components/HelloWorld.vue"
export default {
  name: "App",
  components: {
    HelloWorld,
  },
  data() {
    return {
      data1:1,
      myName:'green',
      data2:10
    }
  },
  methods:{
    getCData (val) {
      this.data2+=2
      console.log("这是来自child组件的数据",val)
    }
  }
};
</script>

// 组件B
<script>
import child from './child.vue'
export default {
  components: { child },
  name: 'HelloWorld',
  props: {
    data1:Number, // 这里只接受了一个A传递过来的参数
  },
  data() {
    return {
      HMsg:'这是helloworld里面的信息'
    }
  }
}
</script>

// 组件C
<script>
export default {
    name:"child",
    data() {
        return {
            msg:"啦啦啦",
            data2:this.data2, // 接受到从A组件传递过来的数据 
        }
    },
    methods:{
        send () {
            this.$emit("getCData",this.msg)
        }
    } 
}

3、this. p a r e n t 和 t h i s . parent 和 this. parentthis.children

// 组件A
<template>
  <div id="app">
    <Test></Test>
    <div>
      这是app:{{myName}}
    </div>
    <button @click="getChild"> 用于获取子组件里的内容</button>
  </div>
</template>
// 组件B
<template>
  <div>
      <h3>{{testMsg}}</h3>
       <button @click="getP">使用parent获取值</button>
       名字:{{$parent.myName}}
  </div>
</template>
// 组件A
export default {
  name: "App",
  components: {
    Test,
  },
  data() {
    return {
      data1:1,
      myName:'green',
      data2:10
    }
  },
  beforeCreate() {
    console.log(this.$children) // 此时打印不出来
  },
  created() {
    console.log(this.$children) // 此时打印不出来
  },
  mounted() {
    console.log(this.$children) // 此时能打印 , 返回的是一个数组
  },
  methods:{
    getChild () {
      console.log(this.$children)
      console.log(this.$children[1].testMsg)
      this.$children[1].testMsg="我要改名了" // 可以之间改子组件里的变量
    }
  }
};
</script>

// 组件B
<script>
export default {
    name:"test",
    data() {
        return {
            testMsg:"这是test里面的信息"
        }
    },
    beforeCreate () {
         console.log(this.$parent.myName) // 可以打印出来
    },
    methods:{
        getP () {
            this.$parent.myName = "黑恶hi" // 可以直接对父组件里的数据进行修改
            console.log(this.$parent.myName)
        }
    }
}
</script>

4、provide 和 inject

// 组件A
<template>
  <div id="app">
    <Test></Test>
    <div>
      这是app:{{myName}}
    </div>
    <button @click="change">change</button>
  </div>
</template>

// 组件B
<template>
  <div>
      <h1>注入:{{myApp.myName}}</h1>
     这是Test组件:{{date}},这是app里的data:{{mydata}}
     <button @click="show">按钮</button>
  </div>
</template>
// 组件A
<script>
import Test from './components/test';

export default {
  name: "App",
  components: {
    Test
  },
  data() {
    return {
      data1:1,
      myName:'green',
      data2:10
    }
  },
  provide() {
    return {
      appMsg:"hellom,I'm app", // 提供方式1,无法进行修改
      myApp:this, // 提供方式2
      date:"2022/3/18",
      mydata:this.data1 // 提供方式3
    }
  },
  methods: {
    change () {
      this.data1++ // 视图不发生变化
      this.myName = 'blue' // 这样修改后在组件B中视图会发生变化
    }
   },
};
</script>

// 组件B
<script>
export default {
    inject:['date','myApp','mydata'],
    name:"test",
    data() {
        return {
            testMsg:"这是test里面的信息"
        }
    },
    methods:{
        show () {
            console.log(this.date)
        }
    }
}
</script>

5、bus传递 (兄弟组件之间的传参 )
新建一个 utils/bus.js 的文件

import Vue from "vue"
export default new Vue();

组件A和组件B为兄弟组件

// 组件A
<template>
  <div class="hello">
    <button @click="send"> 向test组件发射事件</button>
  </div>
</template>

// 组件B
<template>
  <div>
     <div>{{data}}</div>
  </div>
</template>
// 组件A
<script>
import bus from "../util/bus"

export default {
  name: 'HelloWorld'
  methods: {
    send () {
      bus.$emit("send","我是Hello组件") // 向组件B发送事件
    }
  },

}
</script>
// 组件B
<script>
import bus from "../util/bus"
export default {
    name:"test",
    data() {
        return {
            data:""
        }
    },
    created () {
        bus.$on("send",(val)=>{
            console.log(val)
            this.data = val
        }) // 接受组件A发射过来的事件
    }
}
</script>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值