Skip to content

覆盖内置组件

FormCreate 允许您通过 formCreate.component() 方法挂载同名组件来覆盖内置组件。这种方式可以让您完全自定义内置组件的行为和外观,满足特定的业务需求。

获取 formCreate 对象

在使用 formCreate.component() 之前,您需要先获取 formCreate 对象。可以通过以下方式获取:

  • 从设计器包中导入:import { formCreate } from 'path/to/fcDesignerPro'
  • 从设计器实例获取:FcDesigner.formCreate

基本用法

覆盖单个组件

js
import formCreate from '@form-create/element-ui';
import CustomInput from './CustomInput.vue';

// 覆盖内置的 input 组件
formCreate.component('input', CustomInput);

覆盖多个组件

js
import formCreate from '@form-create/element-ui';
import CustomInput from './CustomInput.vue';
import CustomSelect from './CustomSelect.vue';

// 覆盖多个内置组件
formCreate.component('input', CustomInput);
formCreate.component('select', CustomSelect);

使用示例

示例 1:覆盖输入框组件

创建一个自定义的输入框组件,添加自动格式化功能:

vue
<!-- CustomInput.vue -->
<template>
  <el-input
    :modelValue="formattedValue"
    @update:modelValue="handleChange"
    v-bind="$attrs"
  />
</template>

<script>
import { defineComponent, computed } from 'vue';

export default defineComponent({
  name: 'CustomInput',
  props: {
    modelValue: [String, Number],
    disabled: Boolean,
    // 添加自定义属性:自动格式化
    autoFormat: {
      type: Boolean,
      default: false
    }
  },
  emits: ['update:modelValue', 'change'],
  setup(props, { emit }) {
    // 格式化值(例如:自动添加千分位)
    const formattedValue = computed(() => {
      if (!props.autoFormat || !props.modelValue) {
        return props.modelValue;
      }
      // 格式化逻辑
      return String(props.modelValue).replace(/\B(?=(\d{3})+(?!\d))/g, ',');
    });

    const handleChange = (val) => {
      // 移除格式化字符
      const rawValue = props.autoFormat 
        ? val.replace(/,/g, '') 
        : val;

        emit('update:modelValue', rawValue);
      emit('change', rawValue);
    };

    return {
      formattedValue,
      handleChange
    };
  }
});
</script>

在应用启动时覆盖内置组件:

js
// main.js
import formCreate from '@form-create/element-ui';
import CustomInput from './components/CustomInput.vue';

// 覆盖内置的 input 组件
formCreate.component('input', CustomInput);

示例 2:覆盖选择器组件

创建一个自定义的选择器组件,添加搜索和远程加载功能:

vue
<!-- CustomSelect.vue -->
<template>
  <el-select
    :modelValue="modelValue"
    @update:modelValue="handleChange"
    filterable
    remote
    :remote-method="remoteMethod"
    :loading="loading"
    v-bind="$attrs"
  >
    <el-option
      v-for="item in options"
      :key="item.value"
      :label="item.label"
      :value="item.value"
    />
  </el-select>
</template>

<script>
import { defineComponent, ref } from 'vue';
import axios from 'axios';

export default defineComponent({
  name: 'CustomSelect',
  props: {
    modelValue: [String, Number, Array],
    disabled: Boolean,
    // 自定义属性:远程搜索接口
    remoteUrl: String
  },
  emits: ['update:modelValue', 'change'],
  setup(props, { emit }) {
    const options = ref([]);
    const loading = ref(false);

    const remoteMethod = async (query) => {
      if (!props.remoteUrl) {
        return;
      }

      loading.value = true;
      try {
        const response = await axios.get(props.remoteUrl, {
          params: { keyword: query }
        });
        options.value = response.data;
      } catch (error) {
        console.error('加载选项失败:', error);
      } finally {
        loading.value = false;
      }
    };

    const handleChange = (val) => {
      emit('update:modelValue', val);
      emit('change', val);
    };

    return {
      options,
      loading,
      remoteMethod,
      handleChange
    };
  }
});
</script>

覆盖内置组件:

js
// main.js
import formCreate from '@form-create/element-ui';
import CustomSelect from './components/CustomSelect.vue';

// 覆盖内置的 select 组件
formCreate.component('select', CustomSelect);

在设计器中使用

覆盖内置组件后,设计器中所有使用该组件的地方都会自动使用您的自定义组件:

js
// 表单规则中使用覆盖后的组件
const rule = [
  {
    type: 'input',  // 使用覆盖后的自定义 input 组件
    field: 'username',
    title: '用户名',
    props: {
      autoFormat: true  // 使用自定义属性
    }
  },
  {
    type: 'select',  // 使用覆盖后的自定义 select 组件
    field: 'category',
    title: '分类',
    props: {
      remoteUrl: '/api/categories'  // 使用自定义属性
    }
  }
];

注意事项

重要提示

  1. 组件名称必须完全匹配:覆盖内置组件时,组件名称必须与内置组件的标识符完全一致。常见的内置组件标识符包括:inputselectelButtontextarearadiocheckbox 等。完整列表请查看内置组件列表

  2. 覆盖时机formCreate.component() 应该在应用启动时调用,确保在所有表单实例创建之前完成覆盖

  3. 组件规范:自定义组件必须遵循 FormCreate 的组件规范,包括:

    • 必须支持 modelValueupdate:modelValue(v-model 双向绑定)
    • 必须支持 disabled 属性
    • 必须触发 change 事件
    • 使用 v-bind="$attrs" 透传其他属性
  4. 向后兼容:覆盖组件时,建议保持与内置组件相同的 API 接口,确保现有表单规则可以正常工作

  5. 全局影响:覆盖内置组件会影响整个应用中所有使用该组件的地方,请谨慎使用

通过这种方式,您可以完全自定义内置组件的行为,同时保持与 FormCreate 的兼容性。