vue间的组件通讯

文章目录

    • 父子组件通讯(通过props和$emit)
    • 兄弟组件通讯(使用事件总线):
    • 跨级组件通讯(使用provide/inject):
    • 使用Vuex状态管理:
    • 使用$refs引用组件:

父子组件通讯(通过props和$emit)

父组件可以通过props将数据传递给子组件,子组件可以通过$emit触发事件将数据传递回父组件。

javascript 复制代码
<!-- ParentComponent.vue -->
<template>
  <div>
    <ChildComponent :message="parentMessage" @childEvent="handleChildEvent" />
  </div>
</template>

<script>
import ChildComponent from './ChildComponent.vue';

export default {
  data() {
    return {
      parentMessage: 'Hello from parent',
    };
  },
  components: {
    ChildComponent,
  },
  methods: {
    handleChildEvent(data) {
      console.log('Data received from child:', data);
    },
  },
};
</script>
<!-- ChildComponent.vue -->
<template>
  <div>
    <p>{{ message }}</p>
    <button @click="emitEvent">Send Event</button>
  </div>
</template>

<script>
export default {
  props: ['message'],
  methods: {
    emitEvent() {
      this.$emit('childEvent', 'Data from child');
    },
  },
};
</script>

兄弟组件通讯(使用事件总线):

可以通过共享一个父组件中的数据或使用事件总线(Event Bus)来实现兄弟组件之间的通讯

javascript 复制代码
// EventBus.js
import Vue from 'vue';
export default new Vue();
<!-- ComponentA.vue -->
<template>
  <div>
    <input type="text" v-model="message" />
    <button @click="sendMessage">Send Message</button>
  </div>
</template>

<script>
import EventBus from './EventBus.js';

export default {
  data() {
    return {
      message: '',
    };
  },
  methods: {
    sendMessage() {
      EventBus.$emit('messageEvent', this.message);
    },
  },
};
</script>
<!-- ComponentB.vue -->
<template>
  <div>
    <p>{{ receivedMessage }}</p>
  </div>
</template>

<script>
import EventBus from './EventBus.js';

export default {
  data() {
    return {
      receivedMessage: '',
    };
  },
  mounted() {
    EventBus.$on('messageEvent', (message) => {
      this.receivedMessage = message;
    });
  },
};
</script>

跨级组件通讯(使用provide/inject)

可以使用provide/inject来在祖先组件中提供数据,并在后代组件中注入数据。

javascript 复制代码
<!-- GrandparentComponent.vue -->
<template>
  <div>
    <ParentComponent>
      <ChildComponent />
    </ParentComponent>
  </div>
</template>

<script>
import { provide } from 'vue';

export default {
  setup() {
    const sharedData = 'Shared Data';

    provide('sharedData', sharedData);

    return {};
  },
};
</script>
<!-- ParentComponent.vue -->
<template>
  <div>
    <slot></slot>
  </div>
</template>

<script>
export default {
  setup() {
    return {};
  },
};
</script>
<!-- ChildComponent.vue -->
<template>
  <div>
    <p>{{ injectedData }}</p>
  </div>
</template>

<script>
import { inject } from 'vue';

export default {
  setup() {
    const injectedData = inject('sharedData');

    return {
      injectedData,
    };
  },
};
</script>

使用Vuex状态管理

Vuex是Vue官方提供的状态管理库,可以用于在不同组件之间共享状态。

首先,需要安装和配置Vuex。然后,可以使用store中的state、mutations、actions等来修改和获取共享状态。

javascript 复制代码
// store.js
import { createStore } from 'vuex';

const store = createStore({
  state() {
    return {
      message: '',
    };
  },
  mutations: {
    setMessage(state, message) {
      state.message = message;
    },
  },
});

export default store;
<!-- ComponentA.vue -->
<template>
  <div>
    <input type="text" v-model="message" />
    <button @click="updateMessage">Update Message</button>
  </div>
</template>

<script>
import { useStore } from 'vuex';

export default {
  data() {
    return {
      message: '',
    };
  },
  methods: {
    updateMessage() {
      const store = useStore();
      store.commit('setMessage', this.message);
    },
  },
};
</script>
<!-- ComponentB.vue -->
<template>
  <div>
    <p>{{ receivedMessage }}</p>
  </div>
</template>

<script>
import { computed } from 'vue';
import { useStore } from 'vuex';

export default {
  setup() {
    const store = useStore();

    const receivedMessage = computed(() => {
      return store.state.message;
    });

    return {
      receivedMessage,
    };
  },
};
</script>

使用$refs引用组件

每个Vue组件都有一个唯一的ref属性,可以用于在父组件中引用子组件的实例,然后通过实例直接调用子组件的方法或访问数据。

javascript 复制代码
<!-- ParentComponent.vue -->
<template>
  <div>
    <ChildComponent ref="child" />
    <button @click="callChildMethod">Call Child Method</button>
  </div>
</template>

<script>
import ChildComponent from './ChildComponent.vue';

export default {
  components: {
    ChildComponent,
  },
  methods: {
    callChildMethod() {
      this.$refs.child.childMethod();
    },
  },
};
</script>
<!-- ChildComponent.vue -->
<template>
  <div>
    <p>{{ childData }}</p>
  </div>
</template>

<script>
export default {
  data() {
    return {
      childData: 'Data from child',
    };
  },
  methods: {
    childMethod() {
      console.log('Child method called');
    },
  },
};
</script>
相关推荐
coderYYY3 分钟前
多个el-form-item两列布局排齐且el-select/el-input组件宽度撑满
前端·javascript·vue.js·elementui·前端框架
荔枝吖27 分钟前
项目中会出现的css样式
前端·css·html
Dontla31 分钟前
何时需要import css文件?怎么知道需要导入哪些css文件?为什么webpack不提示CSS导入?(导入css导入规则、css导入规范)
前端·css·webpack
小堃学编程1 小时前
前端学习(2)—— CSS详解与使用
前端·css·学习
蓝婷儿1 小时前
第一章:HTML基石·现实的骨架
前端·html
Watermelo6171 小时前
前端如何应对精确数字运算?用BigNumber.js解决JavaScript原生Number类型在处理大数或高精度计算时的局限性
开发语言·前端·javascript·vue.js·前端框架·vue·es6
HebyH_1 小时前
2025前端面试遇到的问题(vue+uniapp+js+css)
前端·javascript·vue.js·面试·uni-app
Clockwiseee1 小时前
CSRF记录
前端·csrf
深圳卢先生1 小时前
XSS 和 CSRF 有什么区别?Java Web 如何防御?
前端·xss·csrf
EndingCoder3 小时前
2025年JavaScript性能优化全攻略
开发语言·javascript·性能优化