首页 > 其他分享 >Vue 3组件间通信全解:选项式API vs 组合式API

Vue 3组件间通信全解:选项式API vs 组合式API

时间:2024-11-24 15:32:48浏览次数:13  
标签:count Vue const 间通信 theme API 组件 import

在Vue 3中,组件间通信的方式可以分为两大类:选项式API(Options API)和组合式API(Composition API)。每种API风格都有其特点和适用场景,下面将分别介绍这两种API风格下的组件间通信方法。

选项式API(Options API)

1. propsemit

props用于父组件向子组件传递数据,而emit用于子组件向父组件传递数据。

父组件:

<template>
  <ChildComponent :message="parentMessage" @childEvent="handleChildEvent" />
</template>

<script>
export default {
  data() {
    return {
      parentMessage: 'Hello from Parent'
    };
  },
  methods: {
    handleChildEvent(message) {
      console.log(message); // 输出: Hello from Child
    }
  }
};
</script>

子组件:

<template>
  <div>
    <p>{{ message }}</p>
    <button @click="sendToParent">Send to Parent</button>
  </div>
</template>

<script>
export default {
  props: ['message'],
  methods: {
    sendToParent() {
      this.$emit('childEvent', 'Hello from Child');
    }
  }
};
</script>
2. provideinject

provideinject用于祖先组件向其所有后代组件提供数据。

祖先组件:

<template>
  <ChildComponent />
</template>

<script>
export default {
  provide() {
    return {
      theme: 'dark'
    };
  }
};
</script>

后代组件:

<template>
  <p>The current theme is {{ theme }}</p>
</template>

<script>
export default {
  inject: ['theme']
};
</script>
3. ref

父组件可以通过ref属性来访问子组件的实例,从而直接调用子组件的方法或访问其属性。

父组件:

<template>
  <ChildComponent ref="childRef" />
</template>

<script>
export default {
  mounted() {
    this.$refs.childRef.someMethod(); // 假设子组件有一个someMethod方法
  }
};
</script>

子组件:

<template>
  <p>Hello from Child</p>
</template>

<script>
export default {
  methods: {
    someMethod() {
      console.log('Called from Parent');
    }
  }
};
</script>

组合式API(Composition API)

1. propsemit

父组件:

<template>
  <ChildComponent :message="parentMessage" @childEvent="handleChildEvent" />
</template>

<script setup>
import { ref } from 'vue';
import ChildComponent from './ChildComponent.vue';

const parentMessage = ref('Hello from Parent');

function handleChildEvent(message) {
  console.log(message); // 输出: Hello from Child
}
</script>

子组件:

<template>
  <div>
    <p>{{ message }}</p>
    <button @click="sendToParent">Send to Parent</button>
  </div>
</template>

<script setup>
import { defineProps, defineEmits } from 'vue';

const props = defineProps({
  message: String
});

const emit = defineEmits(['childEvent']);

function sendToParent() {
  emit('childEvent', 'Hello from Child');
}
</script>
2. provideinject

祖先组件:

<template>
  <ChildComponent />
</template>

<script setup>
import { provide, ref } from 'vue';
import ChildComponent from './ChildComponent.vue';

const theme = ref('dark');

provide('theme', theme);
</script>

后代组件:

<template>
  <p>The current theme is {{ theme }}</p>
</template>

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

const theme = inject('theme');
</script>
3. ref

父组件可以通过ref属性来访问子组件的实例,从而直接调用子组件的方法或访问其属性。

父组件:

<template>
  <ChildComponent ref="childRef" />
</template>

<script setup>
import { ref, onMounted } from 'vue';
import ChildComponent from './ChildComponent.vue';

const childRef = ref(null);

onMounted(() => {
  if (childRef.value) {
    childRef.value.someMethod(); // 假设子组件有一个someMethod方法
  }
});
</script>

子组件:

<template>
  <p>Hello from Child</p>
</template>

<script setup>
function someMethod() {
  console.log('Called from Parent');
}
</script>
4. VuexPinia

对于大型应用,当组件间通信变得非常复杂时,可以考虑使用状态管理库如VuexPinia

Vuex:

// store/index.js
import { createStore } from 'vuex';

export default createStore({
  state: {
    count: 0
  },
  mutations: {
    increment(state) {
      state.count++;
    }
  },
  actions: {
    increment({ commit }) {
      commit('increment');
    }
  },
  getters: {
    doubleCount: state => state.count * 2
  }
});

使用Vuex:

<template>
  <div>
    <p>Count: {{ count }}</p>
    <p>Double Count: {{ doubleCount }}</p>
    <button @click="increment">Increment</button>
  </div>
</template>

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

const store = useStore();

const count = computed(() => store.state.count);
const doubleCount = computed(() => store.getters.doubleCount);

function increment() {
  store.dispatch('increment');
}
</script>

Pinia:

// store/index.js
import { defineStore } from 'pinia';

export const useMainStore = defineStore('main', {
  state: () => ({
    count: 0
  }),
  actions: {
    increment() {
      this.count++;
    }
  },
  getters: {
    doubleCount: (state) => state.count * 2
  }
});

使用Pinia:

<template>
  <div>
    <p>Count: {{ count }}</p>
    <p>Double Count: {{ doubleCount }}</p>
    <button @click="increment">Increment</button>
  </div>
</template>

<script setup>
import { computed } from 'vue';
import { useMainStore } from '@/store';

const store = useMainStore();

const count = computed(() => store.count);
const doubleCount = computed(() => store.doubleCount);

function increment() {
  store.increment();
}
</script>

总结

选项式API:适用于熟悉Vue 2的开发者,代码结构清晰,适合中小型项目。
组合式API:提供了更灵活的代码组织方式,适合大型项目和复杂的业务逻辑。

无论是哪种API风格,Vue 3都提供了丰富的工具和方法来实现组件间的高效通信。选择合适的API风格和通信方式,可以显著提升开发效率和代码的可维护性。

标签:count,Vue,const,间通信,theme,API,组件,import
From: https://blog.csdn.net/misstianyun/article/details/143994549

相关文章