Skip to content

自定义组件使用

自定义组件使用示例展示了 ProForm 中如何使用自定义组件。

两种使用方式

方式1:使用 Field 中的 component 属性,传入 markRaw 包裹的组件引用

方式2:使用 ProForm 插槽,以字段 path 为插槽名,接收字段 props 并自定义渲染

当同一字段同时使用两种方式时,方式2(插槽)优先级更高

表单展示


自定义组件使用示例

表单数据对象:{}

代码实现

vue
<script lang="ts" setup>
import { markRaw } from 'vue';
import { Card, Space, Button } from 'antdv-next';
import { ProForm, useForm } from '@qin-ui/antdv-next-pro';
import CustomInput from './CustomInput.vue';

type FormData = {
  firstName: string;
  lastName: string;
};

const form = useForm<FormData>({}, [
  {
    label: '姓氏',
    path: 'firstName',
    // 方式1:使用Field中 component 属性
    component: markRaw(CustomInput),
    componentStyle: {
      width: `clamp(200px, 80vw, 400px)`,
      borderColor: 'green',
    },
    placeholder: '请输入姓氏',
  },
  {
    label: '名字',
    path: 'lastName',
    componentStyle: { width: `clamp(200px, 80vw, 400px)`, borderColor: 'blue' },
    placeholder: '请输入名字',
  },
]);

const { formRef, formData } = form;

const reset = () => {
  formRef.value?.resetFields();
};

const submit = async () => {
  await formRef.value?.validate();
  console.log('表单提交数据:', { ...formData });
};
</script>

<template>
  <Card title="自定义组件使用示例">
    <ProForm :form="form">
      <!-- 方式2 使用ProForm插槽 -->
      <template #lastName="scoped">
        <CustomInput v-bind="scoped" />
      </template>
      <Space>
        <Button @click="reset">重置表单</Button>
        <Button type="primary" html-type="submit" @click="submit">提交</Button>
      </Space>
    </ProForm>
    <br />
    <div style="white-space: pre">表单数据对象:{{ formData }}</div>
  </Card>
</template>

CustomInput 代码实现

vue
<script lang="ts" setup>
const value = defineModel<string>('value', { default: '' });
</script>

<template>
  <!-- From Uiverse.io by ErzenXz -->
  <input
    type="text"
    class="input"
    v-bind="$attrs"
    :value="value"
    @input="e => (value = (e.target as any)?.value)"
  />
</template>

<style scoped lang="css">
/* From Uiverse.io by ErzenXz */
.input {
  width: 100%;
  height: 45px;
  padding: 12px;
  border: 1.5px solid lightgrey;
  border-radius: 12px;
  outline: none;
  box-shadow: 0px 0px 20px -18px;
  transition: all 0.3s cubic-bezier(0.19, 1, 0.22, 1);
}

.input:hover {
  border: 2px solid lightgrey;
  box-shadow: 0px 0px 20px -17px;
}

.input:active {
  transform: scale(0.95);
}

.input:focus {
  border: 2px solid grey;
}
</style>