Vue2 组件通信、组件间传值的几种方式(分享)

本文详细介绍了Vue中组件间通信的多种方法,包括props(父传子)、自定义事件(子传父)、provide/inject(祖孙通信)、事件总线、Vuex状态管理以及发布订阅模式。通过实例代码展示了每种通信方式的实现过程,帮助读者深入理解Vue组件间的交互机制。

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

1. 文件间的关系

App 为根组件
Father 与 Brother 为兄弟组件,也同为 App 的子组件
Child 是 Father 的子组件,也是 App 的孙组件

2. 父子之间传值

2.1 props,父传子
// Father.vue 文件
<template>
  <div id="father">
    <Child :cMsg="msg" />
  </div>
</template>

<script>
import Child from "./Child.vue";

export default {
  name: "Father",
  components: {
    Child,
  },
  data() {
    return {
      msg: "我是 Father 组件中的数据",
    };
  },
};
</script>
// Child.vue 文件
<template>
  <div id="child">
    <span> 我是 Child 组件,接收到的数据为:{{ cMsg }} </span>
  </div>
</template>

<script>
export default {
  name: "Child",
  props: {
    cMsg: String,
  },
};
</script>

在这里插入图片描述

2.2 props,子传父
// Father.vue 文件
<template>
  <div id="father">
    <Child :cHander="fHander" />
  </div>
</template>

<script>
import Child from "./Child.vue";

export default {
  name: "Father",
  components: {
    Child,
  },
  methods: {
    fHander(msg) {
      console.log(msg);
    },
  },
};
</script>
// Child.vue 文件
<template>
  <div id="child">
    <button @click="btn">点击我向 Father 组件传入数据</button>
  </div>
</template>

<script>
export default {
  name: "Child",
  props: {
    cHander: Function,
  },
  methods: {
    btn() {
      this.cHander("666666");
    },
  },
};
</script>

在这里插入图片描述

2.3 自定义事件,子传父
// Father.vue 文件
<template>
  <div id="father">
    <Child ref="child" />
  </div>
</template>

<script>
import Child from "./Child.vue";

export default {
  name: "Father",
  components: {
    Child,
  },
  mounted() {
    this.$refs.child.$on("change", (msg) => {
      console.log(msg);
    });
  },
};
</script>
// Child.vue 文件
<template>
  <div id="child">
    <button @click="btn">点击我向 Father 组件传入数据</button>
  </div>
</template>

<script>
export default {
  name: "Child",
  methods: {
    btn() {
      this.$emit("change", 666666);
    },
  },
};
</script>

在这里插入图片描述

3. 兄弟之间传值

3.1 事件总线
// main.js 文件
import Vue from 'vue'
import App from './App.vue'

Vue.config.productionTip = false

new Vue({
  render: h => h(App),
  beforeCreate() {
  	// 需要在全局添加一个属性
    Vue.prototype.$bus = this
  }
}).$mount('#app')
// Father.vue 文件
<template>
  <div id="father">
    <button @click="btn">我要给 Brother 组件传数据</button>
  </div>
</template>

<script>
export default {
  name: "Father",
  methods: {
    btn() {
      this.$bus.$emit("change", 66666);
    },
  },
};
</script>
// Brother.vue 文件
<template>
  <div id="brother"></div>
</template>

<script>
export default {
  name: "Brother",
  mounted() {
    this.$bus.$on("change", (msg) => {
      console.log(msg);
    });
  },
};
</script>
3.2 Vuex
// store/index.js 文件
import Vue from "vue"
import Vuex from "vuex"
Vue.use(Vuex)

export default new Vuex.Store({
  state: {
    count: 1
  },
  mutations: {
    change(state, value) {
      state.count += value
    }
  }
})
// main.js 文件
import Vue from 'vue'
import App from './App.vue'
import store from "./store/index"

Vue.config.productionTip = false

new Vue({
  render: h => h(App),
  // 需要挂载 store
  store
}).$mount('#app')
// Father.vue 文件
<template>
  <div id="father">
    <button @click="btn">我要给 VueX 中的数据加一</button>
  </div>
</template>

<script>
export default {
  name: "Father",
  methods: {
    btn() {
      this.$store.commit("change", 1);
    },
  },
};
</script>
// Brother.vue 文件
<template>
  <div id="brother">
    {{ $store.state.count }}
  </div>
</template>

<script>
export default {
  name: "Brother",
};
</script>

在这里插入图片描述

3.3 发布订阅

需要安装 pubsub:npm i pubsub-js

// Father.vue 文件
<template>
  <div id="father">
    <button @click="btn">我要向 Brother 组件传递数据</button>
  </div>
</template>

<script>
import pubsub from "pubsub-js";

export default {
  name: "Father",
  methods: {
    btn() {
      pubsub.publish("change", 666);
    },
  },
};
</script>
// Brother.vue 文件
<template>
  <div id="brother"></div>
</template>

<script>
import pubsub from "pubsub-js";

export default {
  name: "Brother",
  mounted() {
    pubsub.subscribe("change", (msgName, msg) => {
      console.log(msgName, msg);
    });
  },
};
</script>

在这里插入图片描述

4. 祖孙之间传值

4.1 provide与inject
// App.vue 文件
<template>
  <div id="app">
    <Father />
  </div>
</template>

<script>
import Father from "./components/Father.vue";

export default {
  name: "App",
  components: {
    Father,
  },
  provide: {
    msg: "要给 Child 传数据",
  },
};
</script>

// Father.vue 文件
<template>
  <div id="father">
    <Child />
  </div>
</template>

<script>
import Child from "./Child.vue";

export default {
  name: "Father",
  components: {
    Child,
  },
};
</script>
// Child.vue 文件
<template>
  <div id="child">
    {{ msg }}
  </div>
</template>

<script>
export default {
  name: "Child",
  inject: ["msg"],
};
</script>

在这里插入图片描述

评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值