Vue 2 通信方式

146 阅读2分钟

Vue 2 通信方式


1. Props 和 Events(父子组件通信)

这是 Vue 中最基础的通信方式,适用于父子组件之间的数据传递。

Props:父组件向子组件传递数据
  • 父组件通过 props 将数据传递给子组件。
  • 子组件通过声明 props 来接收数据。

示例代码:

<!-- 父组件 -->
<template>
  <ChildComponent :message="parentMessage" />
</template>

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

export default {
  data() {
    return {
      parentMessage: 'Hello from Parent'
    };
  },
  components: { ChildComponent }
};
</script>
<!-- 子组件 -->
<template>
  <div>{{ message }}</div>
</template>

<script>
export default {
  props: {
    message: {
      type: String,
      required: true
    }
  }
};
</script>
Events:子组件向父组件传递数据
  • 子组件通过 $emit 触发自定义事件,将数据传递给父组件。
  • 父组件通过监听事件来接收数据。

示例代码:

<!-- 子组件 -->
<template>
  <button @click="sendToParent">Send Message to Parent</button>
</template>

<script>
export default {
  methods: {
    sendToParent() {
      this.$emit('child-event', 'Hello from Child');
    }
  }
};
</script>
<!-- 父组件 -->
<template>
  <ChildComponent @child-event="handleChildEvent" />
</template>

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

export default {
  components: { ChildComponent },
  methods: {
    handleChildEvent(message) {
      console.log(message); // 输出:Hello from Child
    }
  }
};
</script>

2. Vuex(全局状态管理)

当项目规模较大时,使用 Vuex 可以集中管理全局状态,适用于跨层级组件通信或多个组件共享状态。

核心概念:
  • State:存储全局状态。
  • Getters:从 State 中派生出一些状态。
  • Mutations:同步修改 State。
  • Actions:异步操作,最终调用 Mutations 修改 State。

示例代码:

// store.js
import Vue from 'vue';
import Vuex from 'vuex';

Vue.use(Vuex);

export default new Vuex.Store({
  state: {
    count: 0
  },
  mutations: {
    increment(state) {
      state.count++;
    }
  },
  actions: {
    incrementAsync({ commit }) {
      setTimeout(() => {
        commit('increment');
      }, 1000);
    }
  }
});
<!-- 组件中使用 Vuex -->
<template>
  <div>
    <p>Count: {{ count }}</p>
    <button @click="increment">Increment</button>
  </div>
</template>

<script>
export default {
  computed: {
    count() {
      return this.$store.state.count;
    }
  },
  methods: {
    increment() {
      this.$store.commit('increment');
    }
  }
};
</script>

3. Event Bus(事件总线)

适用于非父子组件之间的通信,但不推荐在大型项目中使用,因为容易导致代码难以维护。

实现方式:
  • 创建一个空的 Vue 实例作为事件总线。
  • 使用 $emit 发送事件,使用 $on 监听事件。

示例代码:

// eventBus.js
import Vue from 'vue';
export const EventBus = new Vue();
<!-- 组件 A -->
<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>
<!-- 组件 B -->
<template>
  <div>{{ message }}</div>
</template>

<script>
import { EventBus } from './eventBus';

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

4. Provide / Inject(祖先与后代组件通信)

适用于祖先组件向深层嵌套的后代组件传递数据,而无需逐层传递 props

实现方式:
  • 祖先组件通过 provide 提供数据。
  • 后代组件通过 inject 注入数据。

示例代码:

<!-- 祖先组件 -->
<template>
  <ChildComponent />
</template>

<script>
export default {
  provide() {
    return {
      sharedData: 'Hello from Ancestor'
    };
  }
};
</script>
<!-- 后代组件 -->
<template>
  <div>{{ sharedData }}</div>
</template>

<script>
export default {
  inject: ['sharedData']
};
</script>

5. refsrefs 和 parent / $children

$refs:访问子组件实例
  • 通过 ref 属性为子组件设置引用名,父组件可以通过 this.$refs 访问子组件实例。
parentparent 和 children:直接访问父/子组件
  • $parent 用于访问父组件实例。
  • $children 用于访问子组件实例数组。

注意: 这种方式会破坏组件的封装性,应谨慎使用。



总结

通信方式适用场景
Props 和 Events父子组件通信
Vuex全局状态管理,跨层级组件通信
Event Bus非父子组件通信(小型项目)
Provide / Inject祖先与深层后代组件通信
refs/refs / parent直接访问组件实例(不推荐频繁使用)

选择合适的通信方式可以提高代码的可维护性和可读性。对于小型项目,PropsEvent Bus 是常用的选择;而对于大型项目,建议使用 VuexProvide/Inject 来管理复杂的状态和通信逻辑。