نموذج Form
يوفر LhForm وLhFormItem ربط النموذج والتحقق الإلزامي وعرض أخطاء الحقول.
الاستخدام الأساسي
الاستخدام الأساسي
vue
<script setup lang="ts">
import { reactive, ref } from 'vue'
import { LhForm, LhFormItem, LhInput, LhButton, LhMessage } from '@lh-ui/vue3'
const formRef = ref()
const formModel = reactive({
name: '',
email: '',
})
const formRules = {
name: [{ required: true, message: 'يرجى إدخال الاسم' }],
email: [{ required: true, message: 'يرجى إدخال البريد الإلكتروني' }],
}
async function submitForm() {
const valid = await formRef.value.validate()
if (valid) {
LhMessage.success('تم الإرسال بنجاح')
console.log('تم الإرسال بنجاح', formModel)
}
}
function resetForm() {
formRef.value?.resetFields()
}
</script>
<template>
<LhForm ref="formRef" :model="formModel" :rules="formRules" label-width="80px">
<LhFormItem prop="name" label="الاسم" required>
<LhInput v-model="formModel.name" placeholder="يرجى إدخال الاسم" />
</LhFormItem>
<LhFormItem prop="email" label="البريد الإلكتروني" required>
<LhInput v-model="formModel.email" placeholder="يرجى إدخال البريد الإلكتروني" />
</LhFormItem>
<LhFormItem>
<LhButton type="primary" @click="submitForm">إرسال</LhButton>
<LhButton plain @click="resetForm" style="margin-left: 8px">إعادة تعيين</LhButton>
</LhFormItem>
</LhForm>
</template>vue
<script>
import { LhForm, LhFormItem, LhInput, LhButton, LhMessage } from '@lh-ui/vue3'
export default {
components: { LhForm, LhFormItem, LhInput, LhButton },
data() {
return {
formModel: { name: '', email: '' },
formRules: {
name: [{ required: true, message: 'يرجى إدخال الاسم' }],
email: [{ required: true, message: 'يرجى إدخال البريد الإلكتروني' }],
},
}
},
methods: {
async submitForm() {
const valid = await this.$refs.formRef.validate()
if (valid) {
LhMessage.success('تم الإرسال بنجاح')
console.log('تم الإرسال بنجاح', this.formModel)
}
},
resetForm() { this.$refs.formRef?.resetFields() },
},
}
</script>
<template>
<LhForm ref="formRef" :model="formModel" :rules="formRules" label-width="80px">
<LhFormItem prop="name" label="الاسم" required>
<LhInput v-model="formModel.name" placeholder="يرجى إدخال الاسم" />
</LhFormItem>
<LhFormItem prop="email" label="البريد الإلكتروني" required>
<LhInput v-model="formModel.email" placeholder="يرجى إدخال البريد الإلكتروني" />
</LhFormItem>
<LhFormItem>
<LhButton type="primary" @click="submitForm">إرسال</LhButton>
<LhButton plain @click="resetForm">إعادة تعيين</LhButton>
</LhFormItem>
</LhForm>
</template>سمة مخصصة
يمكن تطبيق لون سمة مخصص على النموذج.
نموذج بسمة 青花瓷 (الخزف الأزرق)
vue
<script setup lang="ts">
import { reactive } from 'vue'
import { LhConfigProvider, LhForm, LhFormItem, LhInput, LhButton } from '@lh-ui/vue3'
const themeForm = reactive({ name: '' })
const cerblueTheme = {
'primary-color': '#2B4C7C',
'primary-color-hover': '#3D649E',
'primary-color-bg': '#E8EDF3',
}
</script>
<template>
<!-- سمة الخزف الأزرق -->
<LhConfigProvider :theme-vars="cerblueTheme">
<LhForm :model="themeForm" label-width="80px">
<LhFormItem label="الاسم">
<LhInput v-model="themeForm.name" />
</LhFormItem>
<LhFormItem>
<LhButton type="primary">إرسال</LhButton>
</LhFormItem>
</LhForm>
</LhConfigProvider>
</template>vue
<script>
import { LhConfigProvider, LhForm, LhFormItem, LhInput, LhButton } from '@lh-ui/vue3'
export default {
data() {
return {
themeForm: { name: '' },
cerblueTheme: {
'primary-color': '#2B4C7C',
'primary-color-hover': '#3D649E',
'primary-color-bg': '#E8EDF3',
},
}
},
}
</script>
<template>
<!-- سمة الخزف الأزرق -->
<LhConfigProvider :theme-vars="cerblueTheme">
<LhForm :model="themeForm" label-width="80px">
<LhFormItem label="الاسم">
<LhInput v-model="themeForm.name" />
</LhFormItem>
<LhFormItem>
<LhButton type="primary">إرسال</LhButton>
</LhFormItem>
</LhForm>
</LhConfigProvider>
</template>التدويل
نموذج مُدوَل
vue
<script setup lang="ts">
import { reactive, ref } from 'vue'
import { LhConfigProvider, LhForm, LhFormItem, LhInput, LhButton } from '@lh-ui/vue3'
import { zhCN } from '@lh-ui/vue3'
import { enUS } from '@lh-ui/vue3'
const locale = ref('zh-CN')
const formModel = reactive({ name: '' })
</script>
<template>
<!-- تكوين التدويل -->
<LhConfigProvider :locale="locale === 'zh-CN' ? zhCN : enUS">
<LhForm :model="formModel" label-width="80px">
<LhFormItem :label="locale === 'zh-CN' ? '姓名' : 'Name'">
<LhInput v-model="formModel.name" :placeholder="locale === 'zh-CN' ? '请输入姓名' : 'Enter name'" />
</LhFormItem>
<LhFormItem>
<LhButton type="primzhCNy">{{ locale === 'zh-CN' ? '提交' : 'Submit' }}</LhButton>
</LhFormItem>
</LhForm>
</LhConfigProvider>
</template>vue
<script>
import { LhConfigProvider, LhForm, LhFormItem, LhInput, LhButton } from '@lh-ui/vue3'
import { zhCN } from '@lh-ui/vue3'
import { enUS } from '@lh-ui/vue3'
export default {
data() {
return {
locale: 'zh-CN',
formModel: { name: '' },
zhCN: zhCN,
enUS: enUS,
}
},
}
</script>
<template>
<!-- تكوين التدويل -->
<LhConfigProvider :locale="locale === 'zh-CN' ? zhCN : enUS">
<LhForm :model="formModel" label-width="80px">
<LhFormItem :label="locale === 'zh-CN' ? '姓名' : 'Name'">
<LhInput v-model="formModel.name" :placeholder="locale === 'zh-CN' ? '请输入姓名' : 'Enter name'" />
</LhFormItem>
<LhFormItem>
<LhButton type="primzhCNy">{{ locale === 'zh-CN' ? '提交' : 'Submit' }}</LhButton>
</LhFormItem>
</LhForm>
</LhConfigProvider>
</template>موضع التسمية والتخطيط الصَّفِّي
يبدّل label-position محاذاة التسمية (left / right / top)؛ ويجعل inline عناصر النموذج تُرتَّب أفقيًا.
label-position / inline
vue
<script setup lang="ts">
import { reactive } from 'vue'
const fpModel = reactive({ name: '', city: '' })
</script>
<template>
<LhForm :model="fpModel" label-position="top" inline>
<LhFormItem prop="name" label="الاسم" required>
<LhInput v-model="fpModel.name" />
</LhFormItem>
<LhFormItem prop="city" label="المدينة">
<LhInput v-model="fpModel.city" />
</LhFormItem>
</LhForm>
</template>vue
<script>
export default {
data() {
return {
fpModel: { name: '', city: '' },
}
},
}
</script>
<template>
<LhForm :model="fpModel" label-position="top" inline>
<LhFormItem prop="name" label="الاسم" required>
<LhInput v-model="fpModel.name" />
</LhFormItem>
<LhFormItem prop="city" label="المدينة">
<LhInput v-model="fpModel.city" />
</LhFormItem>
</LhForm>
</template>خصائص LhForm
| الخاصية | الوصف | النوع | الافتراضي |
|---|---|---|---|
| model | كائن بيانات النموذج | { [x: string]: unknown; } | — |
| rules | قواعد التحقق من الحقول | { [x: string]: LhFormRule[]; } | — |
| labelPosition | موضع التسمية | "left" | "right" | "top" | 'right' |
| labelWidth | عرض التسمية | string | number | — |
| inline | ما إذا كان التخطيط صَفِّيًا | boolean | false |
| sx | خصائص التخطيط السريع sx | LhSxProps | — |
خصائص LhFormItem
| الخاصية | الوصف | النوع | الافتراضي |
|---|---|---|---|
| prop | مسار الحقل في model، يدعم user.name | string | — |
| label | نص التسمية | string | — |
| required | ما إذا كان إلزاميًا | boolean | false |
| rules | قواعد التحقق لهذا الحقل، أولويتها أعلى من rules الخاصة بـ Form | LhFormRule[] | — |
قواعد التحقق
ts
type LhFormRule = {
required?: boolean
message?: string
validator?: (value: unknown, model: Record<string, unknown>) => string | undefined
}يُعرّض LhForm التابعين validate() وresetFields().
إمكانية الوصول
- نص خطأ
LhFormItemيحملrole="alert"، فيُبثّه قارئ الشاشة فورًا عند فشل التحقق - تُربط منطقة المحتوى بنص الخطأ عبر
aria-describedby، فتستطيع التقنيات المساعدة قراءة علاقة «الحقل ← الخطأ»؛ وعند انعدام الخطأ يُزال الربط تلقائيًا - تقرأ عناصر التحكم في النموذج (Input / Select / Checkbox / Radio / Switch / Slider / InputNumber / DatePicker / TimePicker / Cascader) حالة التحقق الخاصة بـ
LhFormItemالذي يضمّها، فتُوسَم بـaria-invalidعند فشل التحقق، ويُزال الوسم بعد زوال الخطأ؛ ولا تتأثر العناصر الموضوعة خارجLhFormItem - يُؤخذ نص الاحتياط للحقول الإلزامية من مفتاح اللغة
form.required(في الصينية 此项为必填)، ويتبدّل مع لغة ConfigProvider؛ وmessageداخلrulesله أولوية أعلى
تعريفات الأنواع
بنى TypeScript التي يصدّرها هذا المكوّن خارجيًا (مستخرَجة تلقائيًا من packages/components/form/src/types.ts و@lh-ui/share/core/*؛ انقر كل عنصر لعرض التعريف كاملًا؛ وصف الخصائص في جدول الخصائص أعلاه):
LhFormLabelPosition
ts
export type LhFormLabelPosition = 'left' | 'right' | 'top'LhFormProps
ts
export interface LhFormProps {
model: Record<string, unknown>
rules?: Record<string, LhFormRule[]>
labelPosition?: LhFormLabelPosition
labelWidth?: string | number
inline?: boolean
/** خصائص التخطيط السريع sx */
sx?: LhSxProps
}LhFormItemProps
ts
export interface LhFormItemProps {
prop?: string
label?: string
required?: boolean
rules?: LhFormRule[]
}LhFormRule (مأخوذ من @lh-ui/share/core/form)
ts
export interface LhFormRule {
required?: boolean
message?: string
validator?: (value: unknown, model: Record<string, unknown>) => string | undefined
}