ant-design-vue@4.2.6 自定义表单控件

自 3.0 版本以后,Form.Item 不再劫持子元素,而是通过 provider / inject 依赖注入的方式进行自动校验,这种方式可以提高组件性能,子元素也不会限制个数,同样子元素也可以是进一步封装的高级组件。

自定义或第三方的表单控件,也可以与 Form 组件一起使用。只要该组件注入 useInjectFormItemContext 并调用相应方法。

price-input.vue

ts 复制代码
<template>
  <span>
    <a-input type="text" :value="value.number" style="width: 100px" @change="onNumberChange" />
    <a-select
      :value="value.currency"
      style="width: 80px; margin: 0 8px"
      :options="[
        { value: 'rmb', label: 'RMB' },
        { value: 'dollar', label: 'Dollar' },
      ]"
      @change="onCurrencyChange"
    ></a-select>
  </span>
</template>

<script lang="ts">
import { defineComponent } from 'vue';
import type { PropType } from 'vue';
import { Form } from 'ant-design-vue';

export type Currency = 'rmb' | 'dollar';

interface PriceValue {
  number: number;
  currency: Currency;
}
export default defineComponent({
  props: {
    value: { type: Object as PropType<PriceValue>, isRequired: true },
  },
  emits: ['update:value'],
  setup(props, { emit }) {
    const formItemContext = Form.useInjectFormItemContext();
    const triggerChange = (changedValue: { number?: number; currency?: Currency }) => {
      emit('update:value', { ...props.value, ...changedValue });
      formItemContext.onFieldChange();
    };
    const onNumberChange = (e: InputEvent) => {
      const newNumber = parseInt((e.target as any).value || '0', 10);
      triggerChange({ number: newNumber });
    };
    const onCurrencyChange = (newCurrency: Currency) => {
      triggerChange({ currency: newCurrency });
    };

    return {
      onNumberChange,
      onCurrencyChange,
    };
  },
});
</script>

父组件

ts 复制代码
<template>
  <a-form name="customized_form_controls" layout="inline" :model="formState" @finish="onFinish">
    <a-form-item name="price" label="Price" :rules="[{ validator: checkPrice }]">
      <price-input v-model:value="formState.price" />
    </a-form-item>
    <a-form-item>
      <a-button type="primary" html-type="submit">Submit</a-button>
    </a-form-item>
  </a-form>
</template>
<script lang="ts" setup>
import { reactive } from 'vue';
import PriceInput from './price-input.vue';
import type { Currency } from './price-input.vue';

const formState = reactive({
  price: {
    number: 0,
    currency: 'rmb' as Currency,
  },
});
const onFinish = (values: any) => {
  console.log('Received values from form: ', values);
};
const checkPrice = (_: any, value: { number: number }) => {
  if (value.number > 0) {
    return Promise.resolve();
  }
  return Promise.reject(new Error('Price must be greater than zero!'));
};
</script>
相关推荐
恋猫de小郭9 分钟前
八年开源,GSY 用五种技术开发了同一个 Github 客户端,这次轮到 AI + Compose
android·前端·flutter
少年姜太公6 小时前
什么?还不知道git cherry pick?
前端·javascript·git
白兰地空瓶8 小时前
🏒 前端 AI 应用实战:用 Vue3 + Coze,把宠物一键变成冰球运动员!
前端·vue.js·coze
Liu.7749 小时前
vue3使用vue3-print-nb打印
前端·javascript·vue.js
松涛和鸣9 小时前
Linux Makefile : From Basic Syntax to Multi-File Project Compilation
linux·运维·服务器·前端·windows·哈希算法
dly_blog10 小时前
Vue 逻辑复用的多种方案对比!
前端·javascript·vue.js
万少10 小时前
HarmonyOS6 接入分享,原来也是三分钟的事情
前端·harmonyos
烛阴10 小时前
C# 正则表达式:量词与锚点——从“.*”到精确匹配
前端·正则表达式·c#
wyzqhhhh10 小时前
京东啊啊啊啊啊
开发语言·前端·javascript
JIngJaneIL10 小时前
基于java+ vue助农电商系统(源码+数据库+文档)
java·开发语言·前端·数据库·vue.js·spring boot·后端