vue项目setup开发过程中的一些问题--动态组件如何排除不需要的prop和emit

136 阅读1分钟

在 Vue 3 中,动态组件通过 标签实现,可以动态地根据 is 属性渲染不同的组件。但如果一些组件需要 props,而另一些不需要,传递不必要的 props 时可能会触发 Vue 的警告。

以下是解决方案:

  1. 条件传递 props
<template>
  <component 
    :is="currentComponent"
    v-bind="getPropsForComponent(currentComponent)"
  />
</template>

<script>
export default {
  data() {
    return {
      currentComponent: 'ComponentA',
    };
  },
  methods: {
    getPropsForComponent(component) {
      const propsMap = {
        ComponentA: { propA: 'valueA' },
        ComponentB: { propB: 'valueB' },
      };
      return propsMap[component] || {};
    },
  },
};
</script>

  • 这里的 getPropsForComponent 方法根据组件名动态返回需要的 props。

在 Vue 3 中,不同的动态组件可能会需要不同的事件监听 (emits),而有些组件则不需要这些事件。如果你将所有的 emits 都传递给动态组件,可能会导致无效的事件绑定和控制台警告。因此,可以采取以下方式进行处理:

  1. 通过条件判断,根据组件类型动态绑定所需的事件监听。
<template>
  <component 
    :is="currentComponent" 
    v-bind="props"
    v-on="getEmitsForComponent(currentComponent)"
  />
</template>

<script>
export default {
  data() {
    return {
      currentComponent: 'ComponentA',
      props: {
        propA: 'valueA',
      },
    };
  },
  methods: {
    getEmitsForComponent(component) {
      const emitHandlers = {
        ComponentA: {
          onEventA: this.handleEventA,
        },
        ComponentB: {
          onEventB: this.handleEventB,
        },
      };
      return emitHandlers[component] || {};
    },
    handleEventA(payload) {
      console.log('Event A triggered:', payload);
    },
    handleEventB(payload) {
      console.log('Event B triggered:', payload);
    },
  },
};
</script>

解释:

  • 根据组件名称动态返回对应的事件绑定。
  • 如果当前组件不需要任何事件,返回一个空对象 {}

自动化加载组件


<template>

 <component :is="components[item.type + 'Component']"></component>

</template>

<script setup>
// 统一路径 

// src\components\control\cascader\index.vue
// src\components\control\input\index.vue
// src\components\control\date\index.vue
// src\components\control\radio\index.vue
// src\components\control\upload\index.vue

const files = require.context("@/components/control", true, /\index.vue$/);

const modules = {};

// 自动化加载组件
files.keys().forEach((key) => {
  const name = key.split("/");
  modules[name[1] + "Component"] = files(key).default || files(key);
});

const components = modules;
<script>