Skip to content

自定义组件参数透传问题

封装自定义 组件时,透传 props + 黑白名单限制 是一个很常见的需求,主要是为了:

  • 透传 → 让外部调用方仍能用底层 Table 的原生属性
  • 黑/白名单 → 限制可用 props,防止调用方传入不安全或不符合规范的参数

下面我用 Vue 3 举例

1.基本透传 props

假设你用的是 Element Plus 的 <el-table> 作为底层,

可以用 v-bind 直接透传:

vue
<script setup lang="ts">
import { ElTable } from 'element-plus';
import type { TableProps } from 'element-plus';

// 接收所有 props
const props = defineProps<TableProps>();
</script>

<template>
  <el-table v-bind="props">
    <slot />
  </el-table>
</template>

这样,父组件传的所有 props 都会原样传给 <el-table>

但这样没限制,容易被乱传。

2. 黑名单限制

黑名单 = 禁止某些 props 透传

vue
<script setup lang="ts">
import { ElTable } from 'element-plus';
import type { TableProps } from 'element-plus';

// 禁止外部传这些 props
const blacklist = ['data', 'border'];

const allProps = defineProps<TableProps>();

// 过滤掉黑名单里的 key
const filteredProps = computed(() => {
  const newProps = { ...allProps };
  blacklist.forEach((key) => delete newProps[key as keyof typeof newProps]);
  return newProps;
});
</script>

<template>
  <el-table v-bind="filteredProps">
    <slot />
  </el-table>
</template>

好处:你能完全控制调用方不能覆盖的数据,比如 data。

3. 白名单限制

白名单 = 只允许某些 props 透传,其它一律无效

vue
<script setup lang="ts">
import { ElTable } from 'element-plus';
import type { TableProps } from 'element-plus';

const whitelist = ['height', 'stripe', 'highlightCurrentRow'];

const allProps = defineProps<TableProps>();

const filteredProps = computed(() => {
  const newProps: Partial<TableProps> = {};
  whitelist.forEach((key) => {
    if (allProps[key as keyof TableProps] !== undefined) {
      newProps[key as keyof TableProps] = allProps[key as keyof TableProps];
    }
  });
  return newProps;
});
</script>

<template>
  <el-table v-bind="filteredProps">
    <slot />
  </el-table>
</template>

好处:外部可用的 props 是你明确列出的,避免出现奇怪参数。

4. 透传 + 自定义合并逻辑

有时候你不仅要透传,还要合并自己的默认值

比如固定 border=true,即使调用方传了 false 也无效:

vue
const defaultConfig = { border: true } const filteredProps = computed(() => { return { ...defaultConfig, ...allProps,
border: defaultConfig.border // 强制覆盖 } })

5. 最佳实践建议

  • 通用组件用白名单(避免调用方乱传)
  • 业务组件用黑名单(只屏蔽关键 props)
  • 如果 props 太多,可以结合 lodash.pick / lodash.omit 简化白名单和黑名单过滤逻辑

Released under the MIT License.