项目中经常遇到的数据传递方式进行了一个小结:

1. Props 和 Events(父子组件间)
  • Props:父组件通过 props 向子组件传递数据。
// 父组件
<template>
  <ChildComponent :message="parentMessage" />
</template>

<script>
export default {
  data() {
    return {
      parentMessage: 'Hello from Parent'
    };
  }
};
</script>
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • Events:子组件通过 $emit 触发事件,父组件监听并获取数据。
// 子组件
<template>
  <button @click="sendData">Send Data</button>
</template>

<script>
export default {
  methods: {
    sendData() {
      this.$emit('dataSent', 'Hello from Child');
    }
  }
};
</script>

// 父组件
<template>
  <ChildComponent @dataSent="handleData" />
</template>

<script>
export default {
  methods: {
    handleData(data) {
      console.log(data);
    }
  }
};
</script>
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
2. Provide 和 Inject(祖孙组件间)
  • Provide:在祖先组件中提供数据。
  • Inject:在后代组件中注入数据。
// 祖先组件
<template>
  <ChildComponent />
</template>

<script>
export default {
  provide() {
    return {
      sharedData: 'Hello from Ancestor'
    };
  }
};
</script>

// 后代组件
<template>
  <div>{{ injectedData }}</div>
</template>

<script>
export default {
  inject: ['sharedData'],
  computed: {
    injectedData() {
      return this.sharedData;
    }
  }
};
</script>
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
3. Composition API(组合式 API)

使用 Composition API,可以通过 refreactive 来管理状态,并通过函数返回这些状态。

import { ref } from 'vue';

export function useSharedState() {
  const count = ref(0);
  
  function increment() {
    count.value++;
  }

  return { count, increment };
}

// 组件中使用
<template>
  <button @click="increment">{{ count }}</button>
</template>

<script>
import { useSharedState } from './useSharedState';

export default {
  setup() {
    const { count, increment } = useSharedState();
    return { count, increment };
  }
};
</script>
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
4. Event Bus(事件总线)

在某些情况下,可以使用事件总线来实现组件之间的通信,但在 Vue 3 中,推荐使用更现代的状态管理方案(如 Vuex 或 Pinia)。

// eventBus.js
import { reactive } from 'vue';

const eventBus = reactive({});

export default eventBus;

// 发送事件
eventBus.someEvent = 'data';

// 监听事件
const data = eventBus.someEvent;
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
5. Vuex 或 Pinia(状态管理)

对于大型应用,使用 Vuex 或 Pinia 进行全局状态管理是最佳选择。

// Vuex store
import { createStore } from 'vuex';

const store = createStore({
  state: {
    count: 0
  },
  mutations: {
    increment(state) {
      state.count++;
    }
  }
});

// 组件中使用
<template>
  <button @click="increment">{{ count }}</button>
</template>

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

export default {
  setup() {
    const store = useStore();
    
    return {
      count: store.state.count,
      increment: () => store.commit('increment')
    };
  }
};
</script>
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.
  • 33.
总结

在 Vue  中,数据传递的方式多样且灵活。可以根据具体的需求选择合适的方式。对于简单的父子组件通信,使用 props 和 events 就足够了;而对于复杂的状态管理,推荐使用 Vuex 或 Pinia。