Vue组件之间的通信

一、通信方式

  • Props 和 Events :通过父组件传递 props 给子组件,子组件使用**$emit** 发送事件到父组件。
  • Event Bus:使用一个中央事件总线来跨组件通信。
  • Vuex:使用 Vuex 进行全局状态管理,以便在任何组件间共享状态。
  • Provide / Inject :祖先组件使用 provide 传递数据,后代组件通过 **inject**接收数据。
  • $refs :父组件通过 **ref**获取子组件实例,直接调用其方法或访问属性。
  • Scoped Slots:使用插槽在父组件中传递数据到子组件,允许子组件根据传递的数据进行渲染。

二、应用举例

1、Props 和 Events:

父组件 (Parent.vue)

javascript 复制代码
<template>
  <Child :message="parentMessage" @update="handleUpdate" />
</template>
<script>
export default {
  data() {
    return { parentMessage: 'Hello from parent' };
  },
  methods: {
    handleUpdate(newMessage) {
      this.parentMessage = newMessage;
    }
  }
}
</script>

子组件 (Child.vue)

javascript 复制代码
<template>
  <button @click="updateParent">Update Parent</button>
</template>
<script>
export default {
  props: ['message'],
  methods: {
    updateParent() {
      this.$emit('update', 'Hello from child');
    }
  }
}
</script>

2、Event Bus:

事件总线 (eventBus.js)

javascript 复制代码
import Vue from 'vue';
export const EventBus = new Vue();

发送消息 (ComponentA.vue)

javascript 复制代码
<template>
  <button @click="sendMessage">Send Message</button>
</template>
<script>
import { EventBus } from './eventBus';
export default {
  methods: {
    sendMessage() {
      EventBus.$emit('message', 'Hello from Component A');
    }
  }
}
</script>

接收消息 (ComponentB.vue)

javascript 复制代码
<template>
  <p>{{ receivedMessage }}</p>
</template>
<script>
import { EventBus } from './eventBus';
export default {
  data() {
    return { receivedMessage: '' };
  },
  created() {
    EventBus.$on('message', (message) => {
      this.receivedMessage = message;
    });
  }
}
</script>

3、Vuex:

Vuex Store (store.js)

javascript 复制代码
import Vue from 'vue';
import Vuex from 'vuex';

Vue.use(Vuex);

export default new Vuex.Store({
  state: {
    message: 'Hello from Vuex'
  },
  mutations: {
    setMessage(state, newMessage) {
      state.message = newMessage;
    }
  }
});

更新消息 (ComponentA.vue)

javascript 复制代码
<template>
  <button @click="updateMessage">Update Message</button>
</template>
<script>
import { mapMutations } from 'vuex';
export default {
  methods: {
    ...mapMutations(['setMessage']),
    updateMessage() {
      this.setMessage('Hello from Component A');
    }
  }
}
</script>

显示消息 (ComponentB.vue)

javascript 复制代码
<template>
  <p>{{ message }}</p>
</template>
<script>
import { mapState } from 'vuex';
export default {
  computed: {
    ...mapState(['message'])
  }
}
</script>

4、Provide / Inject:

提供数据 (Ancestor.vue)

javascript 复制代码
<template>
  <Descendant />
</template>
<script>
export default {
  provide() {
    return {
      message: 'Hello from ancestor'
    };
  }
}
</script>

注入数据 (Descendant.vue)

javascript 复制代码
<template>
  <p>{{ message }}</p>
</template>
<script>
export default {
  inject: ['message']
}
</script>

5、$refs:

父组件 (Parent.vue)

javascript 复制代码
<template>
  <Child ref="childComponent" />
  <button @click="callChildMethod">Call Child Method</button>
</template>
<script>
import Child from './Child.vue';
export default {
  components: { Child },
  methods: {
    callChildMethod() {
      this.$refs.childComponent.someMethod();
    }
  }
}
</script>

子组件 (Child.vue)

javascript 复制代码
<template>
  <p>Child Component</p>
</template>
<script>
export default {
  methods: {
    someMethod() {
      console.log('Method in child called!');
    }
  }
}
</script>

6、Scoped Slots:

父组件 (Parent.vue)

javascript 复制代码
<template>
  <Child>
    <template v-slot:default="slotProps">
      <p>{{ slotProps.message }}</p>
    </template>
  </Child>
</template>
<script>
import Child from './Child.vue';
export default {
  components: { Child }
}
</script>

子组件 (Child.vue)

javascript 复制代码
<template>
  <slot :message="'Hello from child'"></slot>
</template>
<script>
export default {}
</script>
相关推荐
এ慕ོ冬℘゜12 小时前
ES Promise.all/ Promise.race
前端·javascript·elasticsearch
喜欢打篮球的普通人13 小时前
LLVM 前端与优化层:Clang 如何把 C 代码变成 IR
c语言·前端·状态模式
只睡四小时13 小时前
端侧推理:face-api.js 首屏 92% 是白下载的
开发语言·javascript·人脸识别·ecmascript·tensorflow.js·face-api.js·端侧推理
大文说跨境13 小时前
亚马逊多店铺用过多款指纹浏览器,说点长期用的实际感受
前端·网络
中屹指纹浏览器svip14 小时前
中屹指纹浏览器和普通 Chrome 有什么区别?
前端·chrome·中屹指纹浏览器
feixing_fx14 小时前
CSS Grid 入门:二维布局时代的降维打击
前端·css·前端框架·css3
Lank_M14 小时前
JPG的8×8块里只要有条边,白底就保不住255
前端
coding漫漫长路14 小时前
主图纯白检测,阈值放宽到250会放过252的底
前端
计算机魔术师14 小时前
藏了八个月没被当漏洞的洞,AI红队一晚上翻出来了
前端
用户831348593069814 小时前
Vue3 v-for:常用用法与开发高频坑点
前端·javascript·vue.js