使用场景 ​
为输入控件提供模型、规则、校验状态和表单尺寸上下文。model 必须是调用方维护的响应式对象,FormItem.prop 绑定对应字段。
校验、原生提交与重置 ​
以真实 form 提交触发校验;FormActions 使用 submitNativeType=submit 时无需同时监听 save 再次提交。resetFields 将有 prop 的字段恢复初始值。
校验、原生提交与重置
<template>
<div class="example">
<AsamBaseForm
ref="form"
v-bind="{ ...{ 'label-position': 'top' }, ...{ model: model, rules: rules } }"
@submit.prevent="submit"
>
<AsamFormItem label="项目名称" prop="name" help="使用团队易于辨认的名称">
<AsamInput v-model="model.name" aria-label="项目名称" />
</AsamFormItem>
<AsamFormItem label="团队" prop="team">
<AsamSelect v-model="model.team" :options="options" />
</AsamFormItem>
<AsamFormActions submit-native-type="submit" @cancel="form?.resetFields()" />
</AsamBaseForm>
<output>{{ result }};{{ model }}</output>
</div>
</template>
<script lang="ts" setup>
defineOptions({ name: 'AsamBaseFormBasicExample' });
import { ref, reactive } from 'vue';
import { AsamBaseForm, AsamFormItem, AsamInput, AsamSelect, AsamFormActions } from '@asam-ui/ui';
import type { AsamBaseFormExpose, AsamBaseFormProps } from '@asam-ui/ui';
const form = ref<AsamBaseFormExpose>();
const model = reactive({ name: '', team: '' });
const rules: AsamBaseFormProps['rules'] = {
name: [{ required: true, message: '请输入名称', trigger: 'blur' }],
team: [{ required: true, message: '请选择团队', trigger: 'change' }]
};
const result = ref('尚未提交');
async function submit() {
try {
await form.value?.validate();
result.value = '校验通过';
} catch {
result.value = '请检查必填项';
}
}
const options = [
{ label: '设计', value: 'design', raw: { code: 'design' } },
{ label: '开发', value: 'dev', raw: { code: 'dev' } },
{ label: '停用', value: 'off', disabled: true, raw: { code: 'off' } }
];
</script>
<style scoped>
.example {
display: grid;
gap: var(--asam-space-md, 16px);
min-width: 0;
}
.row {
display: flex;
flex-wrap: wrap;
align-items: center;
gap: var(--asam-space-sm, 8px);
}
.density-grid {
display: grid;
gap: var(--asam-space-md, 16px);
grid-template-columns: repeat(auto-fit, minmax(min(100%, 260px), 1fr));
}
section {
display: grid;
gap: var(--asam-space-sm, 8px);
min-width: 0;
}
output {
overflow-wrap: anywhere;
color: var(--asam-color-text-secondary);
}
</style>
<template>
<div class="example">
<AsamBaseForm
ref="form"
v-bind="{ ...{ 'label-position': 'top' }, ...{ model: model, rules: rules } }"
@submit.prevent="submit"
>
<AsamFormItem label="项目名称" prop="name" help="使用团队易于辨认的名称">
<AsamInput v-model="model.name" aria-label="项目名称" />
</AsamFormItem>
<AsamFormItem label="团队" prop="team">
<AsamSelect v-model="model.team" :options="options" />
</AsamFormItem>
<AsamFormActions submit-native-type="submit" @cancel="form?.resetFields()" />
</AsamBaseForm>
<output>{{ result }};{{ model }}</output>
</div>
</template>
<script setup>
defineOptions({ name: 'AsamBaseFormBasicExample' });
import { ref, reactive } from 'vue';
import { AsamBaseForm, AsamFormItem, AsamInput, AsamSelect, AsamFormActions } from '@asam-ui/ui';
const form = ref();
const model = reactive({ name: '', team: '' });
const rules = {
name: [{ required: true, message: '请输入名称', trigger: 'blur' }],
team: [{ required: true, message: '请选择团队', trigger: 'change' }]
};
const result = ref('尚未提交');
async function submit() {
try {
await form.value?.validate();
result.value = '校验通过';
} catch {
result.value = '请检查必填项';
}
}
const options = [
{ label: '设计', value: 'design', raw: { code: 'design' } },
{ label: '开发', value: 'dev', raw: { code: 'dev' } },
{ label: '停用', value: 'off', disabled: true, raw: { code: 'off' } }
];
</script>
<style scoped>
.example {
display: grid;
gap: var(--asam-space-md, 16px);
min-width: 0;
}
.row {
display: flex;
flex-wrap: wrap;
align-items: center;
gap: var(--asam-space-sm, 8px);
}
.density-grid {
display: grid;
gap: var(--asam-space-md, 16px);
grid-template-columns: repeat(auto-fit, minmax(min(100%, 260px), 1fr));
}
section {
display: grid;
gap: var(--asam-space-sm, 8px);
min-width: 0;
}
output {
overflow-wrap: anywhere;
color: var(--asam-color-text-secondary);
}
</style>
字段校验与动态禁用 ​
validateField 校验指定字段,clearValidate 清除提示,scrollToField 定位字段。表单 disabled 传递到控件;显式设置 disabled=false 的子控件保持启用。不能用关闭校验代替禁用。
字段校验与动态禁用
<template>
<div class="example">
<AsamBaseForm
ref="form"
v-bind="{
...{ 'label-width': '100px' },
...{ model: model, rules: rules, disabled: disabled }
}"
>
<AsamFormItem label="项目名称" prop="name">
<AsamInput v-model="model.name" />
</AsamFormItem>
<AsamFormItem label="显式启用控件" prop="team">
<AsamInput v-model="model.team" :disabled="false" />
</AsamFormItem>
</AsamBaseForm>
<div class="row">
<AsamButton type="default" @click="validateName"> 校验名称 </AsamButton>
<AsamButton type="default" @click="form?.clearValidate('name')"> 清除提示 </AsamButton>
<AsamButton type="default" @click="form?.scrollToField('name')"> 定位字段 </AsamButton>
<AsamButton type="default" @click="disabled = !disabled"> 切换禁用 </AsamButton>
</div>
<output>{{ result }}</output>
</div>
</template>
<script lang="ts" setup>
defineOptions({ name: 'AsamBaseFormInstanceExample' });
import { ref, reactive } from 'vue';
import { AsamBaseForm, AsamFormItem, AsamInput, AsamButton } from '@asam-ui/ui';
import type { AsamBaseFormExpose, AsamBaseFormProps } from '@asam-ui/ui';
const form = ref<AsamBaseFormExpose>();
const model = reactive({ name: '', team: '' });
const rules: AsamBaseFormProps['rules'] = {
name: [{ required: true, message: '请输入名称', trigger: 'blur' }],
team: [{ required: true, message: '请选择团队', trigger: 'change' }]
};
const result = ref('尚未提交');
const disabled = ref(false);
async function validateName() {
try {
await form.value?.validateField('name');
result.value = '名称有效';
} catch {
result.value = '名称必填';
}
}
</script>
<style scoped>
.example {
display: grid;
gap: var(--asam-space-md, 16px);
min-width: 0;
}
.row {
display: flex;
flex-wrap: wrap;
align-items: center;
gap: var(--asam-space-sm, 8px);
}
.density-grid {
display: grid;
gap: var(--asam-space-md, 16px);
grid-template-columns: repeat(auto-fit, minmax(min(100%, 260px), 1fr));
}
section {
display: grid;
gap: var(--asam-space-sm, 8px);
min-width: 0;
}
output {
overflow-wrap: anywhere;
color: var(--asam-color-text-secondary);
}
</style>
<template>
<div class="example">
<AsamBaseForm
ref="form"
v-bind="{
...{ 'label-width': '100px' },
...{ model: model, rules: rules, disabled: disabled }
}"
>
<AsamFormItem label="项目名称" prop="name">
<AsamInput v-model="model.name" />
</AsamFormItem>
<AsamFormItem label="显式启用控件" prop="team">
<AsamInput v-model="model.team" :disabled="false" />
</AsamFormItem>
</AsamBaseForm>
<div class="row">
<AsamButton type="default" @click="validateName"> 校验名称 </AsamButton>
<AsamButton type="default" @click="form?.clearValidate('name')"> 清除提示 </AsamButton>
<AsamButton type="default" @click="form?.scrollToField('name')"> 定位字段 </AsamButton>
<AsamButton type="default" @click="disabled = !disabled"> 切换禁用 </AsamButton>
</div>
<output>{{ result }}</output>
</div>
</template>
<script setup>
defineOptions({ name: 'AsamBaseFormInstanceExample' });
import { ref, reactive } from 'vue';
import { AsamBaseForm, AsamFormItem, AsamInput, AsamButton } from '@asam-ui/ui';
const form = ref();
const model = reactive({ name: '', team: '' });
const rules = {
name: [{ required: true, message: '请输入名称', trigger: 'blur' }],
team: [{ required: true, message: '请选择团队', trigger: 'change' }]
};
const result = ref('尚未提交');
const disabled = ref(false);
async function validateName() {
try {
await form.value?.validateField('name');
result.value = '名称有效';
} catch {
result.value = '名称必填';
}
}
</script>
<style scoped>
.example {
display: grid;
gap: var(--asam-space-md, 16px);
min-width: 0;
}
.row {
display: flex;
flex-wrap: wrap;
align-items: center;
gap: var(--asam-space-sm, 8px);
}
.density-grid {
display: grid;
gap: var(--asam-space-md, 16px);
grid-template-columns: repeat(auto-fit, minmax(min(100%, 260px), 1fr));
}
section {
display: grid;
gap: var(--asam-space-sm, 8px);
min-width: 0;
}
output {
overflow-wrap: anywhere;
color: var(--asam-color-text-secondary);
}
</style>
四档尺寸与上下文继承 ​
四个实例分别显式使用 large、big、default、small。下面省略 size 的实例随 ConfigProvider 响应切换;显式 size 覆盖祖先。面板本身没有 size 契约的入口不附加虚构尺寸属性。
四档尺寸与上下文继承
<template>
<div class="example">
<div class="density-grid">
<section data-density="large">
<strong> large </strong>
<AsamBaseForm size="large" :model="model" label-position="top">
<AsamFormItem label="名称" prop="name">
<AsamInput v-model="model.name" />
</AsamFormItem>
<AsamFormActions />
</AsamBaseForm>
</section>
<section data-density="big">
<strong> big </strong>
<AsamBaseForm size="big" :model="model" label-position="top">
<AsamFormItem label="名称" prop="name">
<AsamInput v-model="model.name" />
</AsamFormItem>
<AsamFormActions />
</AsamBaseForm>
</section>
<section data-density="default">
<strong> default </strong>
<AsamBaseForm size="default" :model="model" label-position="top">
<AsamFormItem label="名称" prop="name">
<AsamInput v-model="model.name" />
</AsamFormItem>
<AsamFormActions />
</AsamBaseForm>
</section>
<section data-density="small">
<strong> small </strong>
<AsamBaseForm size="small" :model="model" label-position="top">
<AsamFormItem label="名称" prop="name">
<AsamInput v-model="model.name" />
</AsamFormItem>
<AsamFormActions />
</AsamBaseForm>
</section>
</div>
<AsamConfigProvider :size="density">
<section data-density="inherited">
<AsamBaseForm :model="model" label-position="top">
<AsamFormItem label="名称" prop="name">
<AsamInput v-model="model.name" />
</AsamFormItem>
<AsamFormActions />
</AsamBaseForm>
</section>
</AsamConfigProvider>
<div class="row">
<AsamButton type="default" @click="density = 'small'"> 继承 small </AsamButton>
<AsamButton type="default" @click="density = 'big'"> 继承 big </AsamButton>
</div>
<output>配置提供器:{{ density }}</output>
</div>
</template>
<script lang="ts" setup>
defineOptions({ name: 'AsamBaseFormSizesExample' });
import { ref, reactive } from 'vue';
import {
AsamBaseForm,
AsamFormItem,
AsamInput,
AsamFormActions,
AsamConfigProvider,
AsamButton
} from '@asam-ui/ui';
import type { AsamControlSize } from '@asam-ui/ui';
const density = ref<AsamControlSize>('big');
const model = reactive({ name: 'ASAM' });
</script>
<style scoped>
.example {
display: grid;
gap: var(--asam-space-md, 16px);
min-width: 0;
}
.row {
display: flex;
flex-wrap: wrap;
align-items: center;
gap: var(--asam-space-sm, 8px);
}
.density-grid {
display: grid;
gap: var(--asam-space-md, 16px);
grid-template-columns: repeat(auto-fit, minmax(min(100%, 260px), 1fr));
}
section {
display: grid;
gap: var(--asam-space-sm, 8px);
min-width: 0;
}
output {
overflow-wrap: anywhere;
color: var(--asam-color-text-secondary);
}
</style>
<template>
<div class="example">
<div class="density-grid">
<section data-density="large">
<strong> large </strong>
<AsamBaseForm size="large" :model="model" label-position="top">
<AsamFormItem label="名称" prop="name">
<AsamInput v-model="model.name" />
</AsamFormItem>
<AsamFormActions />
</AsamBaseForm>
</section>
<section data-density="big">
<strong> big </strong>
<AsamBaseForm size="big" :model="model" label-position="top">
<AsamFormItem label="名称" prop="name">
<AsamInput v-model="model.name" />
</AsamFormItem>
<AsamFormActions />
</AsamBaseForm>
</section>
<section data-density="default">
<strong> default </strong>
<AsamBaseForm size="default" :model="model" label-position="top">
<AsamFormItem label="名称" prop="name">
<AsamInput v-model="model.name" />
</AsamFormItem>
<AsamFormActions />
</AsamBaseForm>
</section>
<section data-density="small">
<strong> small </strong>
<AsamBaseForm size="small" :model="model" label-position="top">
<AsamFormItem label="名称" prop="name">
<AsamInput v-model="model.name" />
</AsamFormItem>
<AsamFormActions />
</AsamBaseForm>
</section>
</div>
<AsamConfigProvider :size="density">
<section data-density="inherited">
<AsamBaseForm :model="model" label-position="top">
<AsamFormItem label="名称" prop="name">
<AsamInput v-model="model.name" />
</AsamFormItem>
<AsamFormActions />
</AsamBaseForm>
</section>
</AsamConfigProvider>
<div class="row">
<AsamButton type="default" @click="density = 'small'"> 继承 small </AsamButton>
<AsamButton type="default" @click="density = 'big'"> 继承 big </AsamButton>
</div>
<output>配置提供器:{{ density }}</output>
</div>
</template>
<script setup>
defineOptions({ name: 'AsamBaseFormSizesExample' });
import { ref, reactive } from 'vue';
import {
AsamBaseForm,
AsamFormItem,
AsamInput,
AsamFormActions,
AsamConfigProvider,
AsamButton
} from '@asam-ui/ui';
const density = ref('big');
const model = reactive({ name: 'ASAM' });
</script>
<style scoped>
.example {
display: grid;
gap: var(--asam-space-md, 16px);
min-width: 0;
}
.row {
display: flex;
flex-wrap: wrap;
align-items: center;
gap: var(--asam-space-sm, 8px);
}
.density-grid {
display: grid;
gap: var(--asam-space-md, 16px);
grid-template-columns: repeat(auto-fit, minmax(min(100%, 260px), 1fr));
}
section {
display: grid;
gap: var(--asam-space-sm, 8px);
min-width: 0;
}
output {
overflow-wrap: anywhere;
color: var(--asam-color-text-secondary);
}
</style>
异步规则、行内布局与字段实例 ​
inline 控制行内排列;labelPosition 可为 left/right/top,FormItem 的位置覆盖表单继承值。 完整说明。
下面的异步 validator 返回 Promise,确认账号规则读取同一响应式 model。 完整说明。
异步校验、布局与全部实例方法
<template>
<div class="example">
<div class="controls">
<div class="control-field">
<label for="control-position">标签位置</label>
<AsamSelect id="control-position" v-model="position">
<AsamOption :label="'left'" :value="'left'">left</AsamOption>
<AsamOption :label="'right'" :value="'right'">right</AsamOption>
<AsamOption :label="'top'" :value="'top'">top</AsamOption>
</AsamSelect>
</div>
<AsamCheckboxItem v-model="inline"> 行内布局</AsamCheckboxItem>
<AsamCheckboxItem v-model="disabled"> 禁用表单</AsamCheckboxItem>
<AsamCheckboxItem v-model="showMessage"> 显示校验消息</AsamCheckboxItem>
</div>
<AsamBaseForm
ref="form"
:model="model"
:rules="rules"
:label-position="position"
:label-width="position === 'top' ? 0 : '110px'"
label-suffix=":"
:inline="inline"
:disabled="disabled"
:show-message="showMessage"
status-icon
scroll-to-error
:scroll-into-view-options="{ behavior: 'smooth', block: 'center' }"
@validate="(prop, valid, message) => events.push(`${prop}:${valid}:${message}`)"
@submit.prevent="validate"
>
<AsamFormSection title="基础资料" description="异步规则与布局组合由使用方定义">
<AsamFormGrid :columns="2" :tablet-columns="2" :mobile-columns="1">
<AsamFormItem label="账号" prop="account" help="输入 taken 将触发异步占用检查">
<AsamInput v-model="model.account" aria-label="账号" />
</AsamFormItem>
<AsamFormItem label="确认账号" prop="confirm" label-position="top">
<AsamInput v-model="model.confirm" aria-label="确认账号" />
</AsamFormItem>
</AsamFormGrid>
</AsamFormSection>
<AsamFormActions
:saving="saving"
submit-native-type="submit"
@cancel="form?.resetFields()"
>
<template #leading><span>原生 submit 只在表单处理一次</span></template>
</AsamFormActions>
</AsamBaseForm>
<div class="controls">
<AsamButton type="default" @click="setInitial">设置新的初始值</AsamButton>
<AsamButton type="default" @click="form?.resetFields()">恢复初始值</AsamButton>
<AsamButton type="default" @click="form?.clearValidate()">清除全部提示</AsamButton>
<AsamButton type="default" @click="inspect">查看注册字段</AsamButton>
</div>
<output>{{ result }}</output>
<pre>{{ JSON.stringify(model) }}</pre>
<AsamCollapse
><AsamCollapseItem name="auxiliary-content">
<template #title><span>校验事件</span></template>
<pre>{{ events.join('\n') }}</pre>
</AsamCollapseItem></AsamCollapse
>
</div>
</template>
<script lang="ts" setup>
defineOptions({ name: 'AsamBaseFormAdvancedExample' });
import { reactive, ref } from 'vue';
import {
AsamCollapse,
AsamCollapseItem,
AsamSelect,
AsamOption,
AsamCheckboxItem,
AsamBaseForm,
AsamFormItem,
AsamInput,
AsamFormActions,
AsamFormSection,
AsamFormGrid,
AsamButton
} from '@asam-ui/ui';
import type { AsamBaseFormExpose, AsamBaseFormProps } from '@asam-ui/ui';
const form = ref<AsamBaseFormExpose>();
const model = reactive({ account: '', confirm: '' });
const position = ref<'left' | 'right' | 'top'>('right');
const inline = ref(false);
const disabled = ref(false);
const showMessage = ref(true);
const saving = ref(false);
const result = ref('尚未校验');
const events = ref<string[]>([]);
const rules: AsamBaseFormProps['rules'] = {
account: [
{ required: true, message: '请输入账号', trigger: 'blur' },
{
async validator(_rule, value) {
await new Promise((resolve) => setTimeout(resolve, 100));
if (value === 'taken') throw new Error('账号已占用');
},
trigger: 'blur'
}
],
confirm: [
{
validator(_rule, value, callback) {
callback(
value === model.account && value ? undefined : new Error('两次账号需一致')
);
},
trigger: 'blur'
}
]
};
async function validate(): Promise<void> {
saving.value = true;
try {
await form.value?.validate();
result.value = '校验通过';
} catch {
result.value = '校验失败';
} finally {
saving.value = false;
}
}
function setInitial(): void {
form.value?.setInitialValues({ account: 'seed', confirm: 'seed' });
result.value = '新的初始值已保存;点击恢复初始值';
}
function inspect(): void {
result.value = `字段数 ${form.value?.fields.length};账号 ${form.value?.getField('account')?.validateState}`;
}
</script>
<style scoped>
.control-field {
display: grid;
gap: var(--asam-space-sm);
}
.example {
display: grid;
gap: var(--asam-space-md);
}
.controls {
display: flex;
flex-wrap: wrap;
gap: var(--asam-space-sm);
}
pre {
white-space: pre-wrap;
overflow-wrap: anywhere;
}
</style>
<template>
<div class="example">
<div class="controls">
<div class="control-field">
<label for="control-position">标签位置</label>
<AsamSelect id="control-position" v-model="position">
<AsamOption :label="'left'" :value="'left'">left</AsamOption>
<AsamOption :label="'right'" :value="'right'">right</AsamOption>
<AsamOption :label="'top'" :value="'top'">top</AsamOption>
</AsamSelect>
</div>
<AsamCheckboxItem v-model="inline"> 行内布局</AsamCheckboxItem>
<AsamCheckboxItem v-model="disabled"> 禁用表单</AsamCheckboxItem>
<AsamCheckboxItem v-model="showMessage"> 显示校验消息</AsamCheckboxItem>
</div>
<AsamBaseForm
ref="form"
:model="model"
:rules="rules"
:label-position="position"
:label-width="position === 'top' ? 0 : '110px'"
label-suffix=":"
:inline="inline"
:disabled="disabled"
:show-message="showMessage"
status-icon
scroll-to-error
:scroll-into-view-options="{ behavior: 'smooth', block: 'center' }"
@validate="(prop, valid, message) => events.push(`${prop}:${valid}:${message}`)"
@submit.prevent="validate"
>
<AsamFormSection title="基础资料" description="异步规则与布局组合由使用方定义">
<AsamFormGrid :columns="2" :tablet-columns="2" :mobile-columns="1">
<AsamFormItem label="账号" prop="account" help="输入 taken 将触发异步占用检查">
<AsamInput v-model="model.account" aria-label="账号" />
</AsamFormItem>
<AsamFormItem label="确认账号" prop="confirm" label-position="top">
<AsamInput v-model="model.confirm" aria-label="确认账号" />
</AsamFormItem>
</AsamFormGrid>
</AsamFormSection>
<AsamFormActions
:saving="saving"
submit-native-type="submit"
@cancel="form?.resetFields()"
>
<template #leading><span>原生 submit 只在表单处理一次</span></template>
</AsamFormActions>
</AsamBaseForm>
<div class="controls">
<AsamButton type="default" @click="setInitial">设置新的初始值</AsamButton>
<AsamButton type="default" @click="form?.resetFields()">恢复初始值</AsamButton>
<AsamButton type="default" @click="form?.clearValidate()">清除全部提示</AsamButton>
<AsamButton type="default" @click="inspect">查看注册字段</AsamButton>
</div>
<output>{{ result }}</output>
<pre>{{ JSON.stringify(model) }}</pre>
<AsamCollapse
><AsamCollapseItem name="auxiliary-content">
<template #title><span>校验事件</span></template>
<pre>{{ events.join('\n') }}</pre>
</AsamCollapseItem></AsamCollapse
>
</div>
</template>
<script setup>
defineOptions({ name: 'AsamBaseFormAdvancedExample' });
import { reactive, ref } from 'vue';
import {
AsamCollapse,
AsamCollapseItem,
AsamSelect,
AsamOption,
AsamCheckboxItem,
AsamBaseForm,
AsamFormItem,
AsamInput,
AsamFormActions,
AsamFormSection,
AsamFormGrid,
AsamButton
} from '@asam-ui/ui';
const form = ref();
const model = reactive({ account: '', confirm: '' });
const position = ref('right');
const inline = ref(false);
const disabled = ref(false);
const showMessage = ref(true);
const saving = ref(false);
const result = ref('尚未校验');
const events = ref([]);
const rules = {
account: [
{ required: true, message: '请输入账号', trigger: 'blur' },
{
async validator(_rule, value) {
await new Promise((resolve) => setTimeout(resolve, 100));
if (value === 'taken') throw new Error('账号已占用');
},
trigger: 'blur'
}
],
confirm: [
{
validator(_rule, value, callback) {
callback(
value === model.account && value ? undefined : new Error('两次账号需一致')
);
},
trigger: 'blur'
}
]
};
async function validate() {
saving.value = true;
try {
await form.value?.validate();
result.value = '校验通过';
} catch {
result.value = '校验失败';
} finally {
saving.value = false;
}
}
function setInitial() {
form.value?.setInitialValues({ account: 'seed', confirm: 'seed' });
result.value = '新的初始值已保存;点击恢复初始值';
}
function inspect() {
result.value = `字段数 ${form.value?.fields.length};账号 ${form.value?.getField('account')?.validateState}`;
}
</script>
<style scoped>
.control-field {
display: grid;
gap: var(--asam-space-sm);
}
.example {
display: grid;
gap: var(--asam-space-md);
}
.controls {
display: flex;
flex-wrap: wrap;
gap: var(--asam-space-sm);
}
pre {
white-space: pre-wrap;
overflow-wrap: anywhere;
}
</style>
validate、validateField 支持 callback 和 Promise;验证失败应处理 rejection。 完整说明。
标签提示、规则变化与 callback ​
下面可以切换 auto/0/固定 labelWidth、必填星号隐藏与左右位置、showMessage 与 inlineMessage,并观察 validateOnRuleChange 对规则替换的处理。 完整说明。
标签提示、规则变化与 callback
<template>
<div class="example">
<div class="controls">
<AsamCheckboxItem v-model="hideStar"> 隐藏必填星号</AsamCheckboxItem>
<div class="control-field">
<label for="control-star">星号位置</label>
<AsamSelect id="control-star" v-model="star">
<AsamOption :label="'left'" :value="'left'">left</AsamOption>
<AsamOption :label="'right'" :value="'right'">right</AsamOption>
</AsamSelect>
</div>
<AsamCheckboxItem v-model="showMessage"> 显示消息</AsamCheckboxItem>
<AsamCheckboxItem v-model="inlineMessage"> 行内错误</AsamCheckboxItem>
<AsamCheckboxItem v-model="validateOnRuleChange"> 规则改变时校验</AsamCheckboxItem>
<div class="control-field">
<label for="control-labelWidth">标签宽度</label>
<AsamSelect id="control-labelWidth" v-model="labelWidth">
<AsamOption value="auto" :label="'auto'">auto</AsamOption>
<AsamOption :value="0" :label="'0'">0</AsamOption>
<AsamOption value="120px" :label="'120px'">120px</AsamOption>
</AsamSelect>
</div>
</div>
<AsamBaseForm
ref="form"
:model="model"
:rules="rules"
:label-width="labelWidth"
label-suffix=":"
:hide-required-asterisk="hideStar"
:require-asterisk-position="star"
:show-message="showMessage"
:inline-message="inlineMessage"
status-icon
:validate-on-rule-change="validateOnRuleChange"
>
<AsamFormItem label="必填项" prop="name">
<AsamInput v-model="model.name" aria-label="必填项" />
</AsamFormItem>
<AsamFormItem label="外部状态" :validate-status="status" :error="externalError">
<AsamInput v-model="model.other" aria-label="外部状态" />
</AsamFormItem>
</AsamBaseForm>
<div class="controls">
<AsamButton type="default" @click="validateCallback">callback 校验</AsamButton>
<AsamButton type="default" @click="changeRules">改变规则消息</AsamButton>
<AsamButton type="default" @click="form?.validateField('name', callback)">
callback 字段校验
</AsamButton>
<AsamButton type="default" @click="form?.clearValidate('name')"
>清除指定字段</AsamButton
>
<AsamButton
type="default"
@click="status = status === 'validating' ? 'success' : 'validating'"
>
切换外部状态
</AsamButton>
<AsamButton type="default" @click="externalError = externalError ? '' : '服务端提示'">
切换外部消息
</AsamButton>
</div>
<output>{{ result }}</output>
</div>
</template>
<script lang="ts" setup>
defineOptions({ name: 'AsamBaseFormPresentationExample' });
import { reactive, ref } from 'vue';
import {
AsamCheckboxItem,
AsamSelect,
AsamOption,
AsamBaseForm,
AsamFormItem,
AsamInput,
AsamButton
} from '@asam-ui/ui';
import type { AsamBaseFormExpose, AsamBaseFormProps, AsamFormItemProps } from '@asam-ui/ui';
const form = ref<AsamBaseFormExpose>();
const model = reactive({ name: '', other: '' });
const hideStar = ref(false);
const star = ref<'left' | 'right'>('left');
const showMessage = ref(true);
const inlineMessage = ref(false);
const validateOnRuleChange = ref(true);
const labelWidth = ref<string | number>('auto');
const status = ref<AsamFormItemProps['validateStatus']>('');
const externalError = ref('');
const result = ref('callback 尚未执行');
const rules = ref<AsamBaseFormProps['rules']>({
name: [{ required: true, message: '原规则消息' }]
});
const callback: NonNullable<Parameters<AsamBaseFormExpose['validate']>[0]> = (valid, fields) => {
result.value = `${valid ? '有效' : '无效'};错误字段 ${Object.keys(fields ?? {}).join(',')}`;
};
function validateCallback(): void {
void form.value?.validate(callback);
}
function changeRules(): void {
rules.value = { name: [{ required: true, message: '新规则消息' }] };
}
</script>
<style scoped>
.control-field {
display: grid;
gap: var(--asam-space-sm);
}
.example {
display: grid;
gap: var(--asam-space-md);
}
.controls {
display: flex;
flex-wrap: wrap;
gap: var(--asam-space-sm);
}
</style>
<template>
<div class="example">
<div class="controls">
<AsamCheckboxItem v-model="hideStar"> 隐藏必填星号</AsamCheckboxItem>
<div class="control-field">
<label for="control-star">星号位置</label>
<AsamSelect id="control-star" v-model="star">
<AsamOption :label="'left'" :value="'left'">left</AsamOption>
<AsamOption :label="'right'" :value="'right'">right</AsamOption>
</AsamSelect>
</div>
<AsamCheckboxItem v-model="showMessage"> 显示消息</AsamCheckboxItem>
<AsamCheckboxItem v-model="inlineMessage"> 行内错误</AsamCheckboxItem>
<AsamCheckboxItem v-model="validateOnRuleChange"> 规则改变时校验</AsamCheckboxItem>
<div class="control-field">
<label for="control-labelWidth">标签宽度</label>
<AsamSelect id="control-labelWidth" v-model="labelWidth">
<AsamOption value="auto" :label="'auto'">auto</AsamOption>
<AsamOption :value="0" :label="'0'">0</AsamOption>
<AsamOption value="120px" :label="'120px'">120px</AsamOption>
</AsamSelect>
</div>
</div>
<AsamBaseForm
ref="form"
:model="model"
:rules="rules"
:label-width="labelWidth"
label-suffix=":"
:hide-required-asterisk="hideStar"
:require-asterisk-position="star"
:show-message="showMessage"
:inline-message="inlineMessage"
status-icon
:validate-on-rule-change="validateOnRuleChange"
>
<AsamFormItem label="必填项" prop="name">
<AsamInput v-model="model.name" aria-label="必填项" />
</AsamFormItem>
<AsamFormItem label="外部状态" :validate-status="status" :error="externalError">
<AsamInput v-model="model.other" aria-label="外部状态" />
</AsamFormItem>
</AsamBaseForm>
<div class="controls">
<AsamButton type="default" @click="validateCallback">callback 校验</AsamButton>
<AsamButton type="default" @click="changeRules">改变规则消息</AsamButton>
<AsamButton type="default" @click="form?.validateField('name', callback)">
callback 字段校验
</AsamButton>
<AsamButton type="default" @click="form?.clearValidate('name')"
>清除指定字段</AsamButton
>
<AsamButton
type="default"
@click="status = status === 'validating' ? 'success' : 'validating'"
>
切换外部状态
</AsamButton>
<AsamButton type="default" @click="externalError = externalError ? '' : '服务端提示'">
切换外部消息
</AsamButton>
</div>
<output>{{ result }}</output>
</div>
</template>
<script setup>
defineOptions({ name: 'AsamBaseFormPresentationExample' });
import { reactive, ref } from 'vue';
import {
AsamCheckboxItem,
AsamSelect,
AsamOption,
AsamBaseForm,
AsamFormItem,
AsamInput,
AsamButton
} from '@asam-ui/ui';
const form = ref();
const model = reactive({ name: '', other: '' });
const hideStar = ref(false);
const star = ref('left');
const showMessage = ref(true);
const inlineMessage = ref(false);
const validateOnRuleChange = ref(true);
const labelWidth = ref('auto');
const status = ref('');
const externalError = ref('');
const result = ref('callback 尚未执行');
const rules = ref({
name: [{ required: true, message: '原规则消息' }]
});
const callback = (valid, fields) => {
result.value = `${valid ? '有效' : '无效'};错误字段 ${Object.keys(fields ?? {}).join(',')}`;
};
function validateCallback() {
void form.value?.validate(callback);
}
function changeRules() {
rules.value = { name: [{ required: true, message: '新规则消息' }] };
}
</script>
<style scoped>
.control-field {
display: grid;
gap: var(--asam-space-sm);
}
.example {
display: grid;
gap: var(--asam-space-md);
}
.controls {
display: flex;
flex-wrap: wrap;
gap: var(--asam-space-sm);
}
</style>
嵌套与动态字段、数字和辅助标签 ​
prop 支持 contact.email 字符串路径或 ['rows', '0', 'value'] 数组路径。 完整说明。
动态字段、嵌套路径与数字校验
<template>
<div class="example">
<AsamBaseForm
ref="form"
v-bind="{ model, labelPosition: 'top' }"
@submit.prevent="validate"
>
<AsamFormItem label="联系信息">
<div class="demo-slot-layout">
<AsamFormItem
label="邮箱"
prop="contact.email"
:rules="[{ type: 'email', required: true, message: '请输入有效邮箱' }]"
>
<AsamInput v-model="model.contact.email" aria-label="邮箱" />
</AsamFormItem>
<AsamFormItem
label="数量"
:prop="['contact', 'quantity']"
:rules="[{ type: 'number', min: 1, message: '数量至少为 1' }]"
>
<AsamInputNumber
v-model.number="model.contact.quantity"
aria-label="数量"
/>
</AsamFormItem>
</div>
</AsamFormItem>
<AsamFormItem
v-for="(row, index) in model.rows"
:key="row.id"
:label="`条目 ${index + 1}`"
:prop="['rows', String(index), 'value']"
:rules="[{ required: true, message: '条目不能为空' }]"
>
<div class="demo-slot-layout">
<AsamInput v-model="row.value" :aria-label="`条目 ${index + 1}`" />
<AsamButton type="default" @click="model.rows.splice(index, 1)">
删除条目 {{ index + 1 }}
</AsamButton>
</div>
</AsamFormItem>
<AsamButton type="default" @click="add">添加条目</AsamButton>
<AsamFormActions submit-native-type="submit" @cancel="form?.resetFields()" />
</AsamBaseForm>
<output>{{ result }};{{ model }}</output>
</div>
</template>
<script lang="ts" setup>
defineOptions({ name: 'AsamBaseFormDynamicExample' });
import { reactive, ref } from 'vue';
import {
AsamInputNumber,
AsamBaseForm,
AsamFormItem,
AsamInput,
AsamButton,
AsamFormActions
} from '@asam-ui/ui';
import type { AsamBaseFormExpose } from '@asam-ui/ui';
const form = ref<AsamBaseFormExpose>();
const model = reactive({ contact: { email: '', quantity: 0 }, rows: [{ id: 1, value: '' }] });
let id = 1;
const result = ref('动态字段由使用方维护;不使用 DATA 层 AsamForm schema');
function add(): void {
model.rows.push({ id: ++id, value: '' });
}
async function validate(): Promise<void> {
try {
await form.value?.validate();
result.value = '全部字段有效';
} catch {
result.value = '请检查动态字段';
}
}
</script>
<style scoped>
.example {
display: grid;
gap: var(--asam-space-md);
}
output {
overflow-wrap: anywhere;
}
</style>
<style scoped>
.demo-slot-layout {
display: grid;
gap: var(--asam-space-md);
width: 100%;
min-width: 0;
}
.demo-slot-layout > .el-button {
justify-self: start;
}
.demo-slot-layout > :is(p, pre, output) {
margin-block: 0;
}
.demo-slot-actions {
display: flex;
flex-wrap: wrap;
align-items: center;
gap: var(--asam-space-sm);
}
.demo-slot-actions > .el-button + .el-button {
margin-left: 0;
}
</style>
<template>
<div class="example">
<AsamBaseForm
ref="form"
v-bind="{ model, labelPosition: 'top' }"
@submit.prevent="validate"
>
<AsamFormItem label="联系信息">
<div class="demo-slot-layout">
<AsamFormItem
label="邮箱"
prop="contact.email"
:rules="[{ type: 'email', required: true, message: '请输入有效邮箱' }]"
>
<AsamInput v-model="model.contact.email" aria-label="邮箱" />
</AsamFormItem>
<AsamFormItem
label="数量"
:prop="['contact', 'quantity']"
:rules="[{ type: 'number', min: 1, message: '数量至少为 1' }]"
>
<AsamInputNumber
v-model.number="model.contact.quantity"
aria-label="数量"
/>
</AsamFormItem>
</div>
</AsamFormItem>
<AsamFormItem
v-for="(row, index) in model.rows"
:key="row.id"
:label="`条目 ${index + 1}`"
:prop="['rows', String(index), 'value']"
:rules="[{ required: true, message: '条目不能为空' }]"
>
<div class="demo-slot-layout">
<AsamInput v-model="row.value" :aria-label="`条目 ${index + 1}`" />
<AsamButton type="default" @click="model.rows.splice(index, 1)">
删除条目 {{ index + 1 }}
</AsamButton>
</div>
</AsamFormItem>
<AsamButton type="default" @click="add">添加条目</AsamButton>
<AsamFormActions submit-native-type="submit" @cancel="form?.resetFields()" />
</AsamBaseForm>
<output>{{ result }};{{ model }}</output>
</div>
</template>
<script setup>
defineOptions({ name: 'AsamBaseFormDynamicExample' });
import { reactive, ref } from 'vue';
import {
AsamInputNumber,
AsamBaseForm,
AsamFormItem,
AsamInput,
AsamButton,
AsamFormActions
} from '@asam-ui/ui';
const form = ref();
const model = reactive({ contact: { email: '', quantity: 0 }, rows: [{ id: 1, value: '' }] });
let id = 1;
const result = ref('动态字段由使用方维护;不使用 DATA 层 AsamForm schema');
function add() {
model.rows.push({ id: ++id, value: '' });
}
async function validate() {
try {
await form.value?.validate();
result.value = '全部字段有效';
} catch {
result.value = '请检查动态字段';
}
}
</script>
<style scoped>
.example {
display: grid;
gap: var(--asam-space-md);
}
output {
overflow-wrap: anywhere;
}
</style>
<style scoped>
.demo-slot-layout {
display: grid;
gap: var(--asam-space-md);
width: 100%;
min-width: 0;
}
.demo-slot-layout > .el-button {
justify-self: start;
}
.demo-slot-layout > :is(p, pre, output) {
margin-block: 0;
}
.demo-slot-actions {
display: flex;
flex-wrap: wrap;
align-items: center;
gap: var(--asam-space-sm);
}
.demo-slot-actions > .el-button + .el-button {
margin-left: 0;
}
</style>
嵌套 FormItem 的标签宽度默认归零,可单独指定 labelWidth。 完整说明。
ASAM 扩展与迁移 ​
ASAM 四档 size 由表单上下文传递到 FormItem 和子控件,单项显式 size 优先。默认插槽放表单项;公开表单方法直接转发到实际实例。setInitialValues 与 getField/fields 使用当前公开类型中的参数和返回值。业务提交、请求与成功跳转由调用方处理。
API 阅读方式 ​
下方 Props、Events、Slots、Exposes 按当前实际公开类型与运行默认值生成。组合属性按分支生效,不能任意混搭值模式。标为“未知 / 未声明”的默认值不代表 false 或空值。源码区域提供对应语言的独立 Demo.vue,可直接复制或下载;本地辅助组件、数据和素材已内联到当前文件。
API
属性 AsamBaseFormProps
| 属性名 | 说明 | 类型 | 默认值 |
|---|---|---|---|
disabled | 是否禁用表单中的全部控件;设为 true 时覆盖内部组件的 disabled。 | boolean | undefined | false |
labelWidth | 标签宽度,例如 '50px'。可以使用 auto。 | string | number | undefined | "" |
model | 表单数据对象 | Record<string, any> | undefined | — |
scrollIntoViewOptions | 校验失败时,根据 scrollIntoView 配置滚动到首个错误字段。 | boolean | ScrollIntoViewOptions | undefined | true |
rules | 表单验证规则, 具体配置见下表, 更多内容可以参考async-validator | (AsamBaseFormProps)["rules"] | — |
labelPosition | 表单域标签的位置,当设置为 left 或 right 时,则也需要设置 label-width 属性 | enum"top" | "right" | "left"完整类型:"top" | "right" | "left" | undefined | "right" |
requireAsteriskPosition | 星号的位置。 | enum"right" | "left"完整类型:"right" | "left" | undefined | "left" |
labelSuffix | 表单域标签的后缀 | string | undefined | "" |
inline | 行内表单模式 | boolean | undefined | false |
inlineMessage | 是否在行内显示校验信息 | boolean | undefined | false |
statusIcon | 是否在输入框中显示校验结果反馈图标 | boolean | undefined | false |
showMessage | 是否显示校验错误信息 | boolean | undefined | true |
validateOnRuleChange | 是否在 rules 属性改变后立即触发一次验证 | boolean | undefined | true |
hideRequiredAsterisk | 是否隐藏必填字段标签旁边的红色星号。 | boolean | undefined | false |
scrollToError | 当校验失败时,滚动到第一个错误表单项 | boolean | undefined | false |
size | — | enum"large" | "big" | "default" | "small"完整类型:AsamControlSize | undefined | undefined |
事件 AsamBaseFormEmits
| 属性名 | 说明 | 类型 | 默认值 |
|---|---|---|---|
validate | — | (AsamBaseFormEmits)["validate"] | — |
插槽 AsamBaseFormSlots
| 属性名 | 说明 | 类型 | 默认值 |
|---|---|---|---|
default | — | (() => unknown) | undefined | — |
实例方法与状态 AsamBaseFormExpose
| 属性名 | 说明 | 类型 | 默认值 |
|---|---|---|---|
validate | 验证表单项 | (AsamBaseFormExpose)["validate"] | — |
validateField | 验证具体的某个字段。 | (AsamBaseFormExpose)["validateField"] | — |
resetFields | 重置该表单项,将其值重置为初始值,并移除校验结果 | (AsamBaseFormExpose)["resetFields"] | — |
clearValidate | 清除指定字段的校验消息。 | (AsamBaseFormExpose)["clearValidate"] | — |
scrollToField | 滚动到指定的字段 | (AsamBaseFormExpose)["scrollToField"] | — |
getField | 获取字段的 context | (AsamBaseFormExpose)["getField"] | — |
fields | 全部字段的上下文。 | (AsamBaseFormExpose)["fields"] | — |
setInitialValues | 设置表单字段的初始值。当调用 resetFields 时,字段将重置为这些值。 | (initModel: Record<string, any>) => void | — |
用法与契约补充说明 ​
异步规则、行内布局与字段实例 ​
inline 控制行内排列;labelPosition 可为 left/right/top,FormItem 的位置覆盖表单继承值。left/right 通常配合 labelWidth;数值 0 保持零宽度,不转换为 auto。labelSuffix、required 星号位置、hideRequiredAsterisk、statusIcon、showMessage、inlineMessage 分别控制标签与提示。disabled 是控件的继承默认值,子控件显式的 disabled 配置优先。
异步规则、行内布局与字段实例 ​
下面的异步 validator 返回 Promise,确认账号规则读取同一响应式 model。提交时 await validate,结束后在 finally 恢复 saving;callback 风格的 validator 必须调用 callback。规则依赖的其他字段改变后,使用 validateField 重新检查相关字段;validateOnRuleChange 只处理规则本身的变化。scrollToError 和 scrollIntoViewOptions 用于失败定位。
异步规则、行内布局与字段实例 ​
validate、validateField 支持 callback 和 Promise;验证失败应处理 rejection。validate 事件传出字段路径、布尔结果和消息。fields 是已注册字段的实时列表,getField 返回上下文或 undefined;不要把布局分区误当注册字段。clearValidate 清提示而不改模型,resetFields 可指定路径;setInitialValues 设置后续 resetFields 的基线,并不等于立即改写当前 model。scrollToField 可显式定位。
标签提示、规则变化与 callback ​
下面可以切换 auto/0/固定 labelWidth、必填星号隐藏与左右位置、showMessage 与 inlineMessage,并观察 validateOnRuleChange 对规则替换的处理。validate/validateField 的 callback 接收 valid 和错误字段;提供 callback 后仍可 await 返回的 Promise,但无需将 callback 的 false 结果当未处理异常。FormItem 的外部 error、validateStatus 展示服务端消息和显式校验状态。
嵌套与动态字段、数字和辅助标签 ​
prop 支持 contact.email 字符串路径或 ['rows', '0', 'value'] 数组路径。动态列表使用稳定 key;新增、删除或 prop 路径改变时,表单项注册与初始值跟随真实字段。resetFields 重置字段值,不恢复使用方已删除的列表条目。数字规则要求数字模型,原生 input 使用 .number;空值、范围和 required 仍由规则决定。
嵌套与动态字段、数字和辅助标签 ​
嵌套 FormItem 的标签宽度默认归零,可单独指定 labelWidth。一个控件的 label 自动关联;多个控件组成 group 时,应逐个提供辅助名称,见 AsamFormItem。BaseForm 负责模型、规则和表单实例;动态字段 schema、异步选项和数据 provider 的组合由 AsamForm 承接。使用方维护的 v-for 字段列表与 schema 驱动表单各有用途。
关联组件
参数与事件补充说明
完整透传 2.14.7 表单参数,并支持 ASAM 四档控件尺寸。
参数与事件说明
disabled
必填:否;声明来源:上游声明。
disabled 参数与事件数据
下列为声明可读视图;可导入类型以公开类型视图为准。分支条件与父属性一致。
枚举:false / true
默认值与来源
false(隐式 Boolean 默认;已安装组件)固定上游文档默认:false(2.14.7;文档事实,实际默认以 ASAM 源码 / 安装包为准)
labelWidth
必填:否;声明来源:上游声明。
默认值与来源
""(已安装运行时;已安装组件)固定上游文档默认:''(2.14.7;文档事实,实际默认以 ASAM 源码 / 安装包为准)
固定上游源码默认表达式:''(2.14.7;源码事实,未作为 ASAM 运行实测)
model
必填:否;声明来源:上游声明。
默认值与来源
未知 / 未声明固定上游文档默认:未声明(2.14.7;文档事实,实际默认以 ASAM 源码 / 安装包为准)
scrollIntoViewOptions
必填:否;声明来源:上游声明。
scrollIntoViewOptions 参数与事件数据
下列为声明可读视图;可导入类型以公开类型视图为准。分支条件与父属性一致。
枚举:false / true
scrollIntoViewOptions.block:ScrollLogicalPosition | undefined— 依赖声明枚举:
"start"/"center"/"end"/"nearest"scrollIntoViewOptions.inline:ScrollLogicalPosition | undefined— 依赖声明枚举:
"start"/"center"/"end"/"nearest"scrollIntoViewOptions.behavior:ScrollBehavior | undefined— 依赖声明枚举:
"auto"/"smooth"/"instant"
默认值与来源
true(已安装运行时;已安装组件)固定上游文档默认:true(2.14.7;文档事实,实际默认以 ASAM 源码 / 安装包为准)
固定上游源码默认表达式:true(2.14.7;源码事实,未作为 ASAM 运行实测)
rules
必填:否;声明来源:上游声明。
默认值与来源
未知 / 未声明固定上游文档默认:未声明(2.14.7;文档事实,实际默认以 ASAM 源码 / 安装包为准)
固定上游源码未声明 default(2.14.7;源码事实,未作为 ASAM 运行实测)
labelPosition
必填:否;声明来源:上游声明。
labelPosition 参数与事件数据
下列为声明可读视图;可导入类型以公开类型视图为准。分支条件与父属性一致。
枚举:"top" / "right" / "left"
默认值与来源
"right"(已安装运行时;已安装组件)固定上游文档默认:right(2.14.7;文档事实,实际默认以 ASAM 源码 / 安装包为准)
固定上游源码默认表达式:'right'(2.14.7;源码事实,未作为 ASAM 运行实测)
requireAsteriskPosition
必填:否;声明来源:上游声明。
requireAsteriskPosition 参数与事件数据
下列为声明可读视图;可导入类型以公开类型视图为准。分支条件与父属性一致。
枚举:"right" / "left"
默认值与来源
"left"(已安装运行时;已安装组件)固定上游文档默认:left(2.14.7;文档事实,实际默认以 ASAM 源码 / 安装包为准)
固定上游源码默认表达式:'left'(2.14.7;源码事实,未作为 ASAM 运行实测)
labelSuffix
必填:否;声明来源:上游声明。
默认值与来源
""(已安装运行时;已安装组件)固定上游文档默认:''(2.14.7;文档事实,实际默认以 ASAM 源码 / 安装包为准)
固定上游源码默认表达式:''(2.14.7;源码事实,未作为 ASAM 运行实测)
inline
必填:否;声明来源:上游声明。
inline 参数与事件数据
下列为声明可读视图;可导入类型以公开类型视图为准。分支条件与父属性一致。
枚举:false / true
默认值与来源
false(隐式 Boolean 默认;已安装组件)固定上游文档默认:false(2.14.7;文档事实,实际默认以 ASAM 源码 / 安装包为准)
inlineMessage
必填:否;声明来源:上游声明。
inlineMessage 参数与事件数据
下列为声明可读视图;可导入类型以公开类型视图为准。分支条件与父属性一致。
枚举:false / true
默认值与来源
false(隐式 Boolean 默认;已安装组件)固定上游文档默认:false(2.14.7;文档事实,实际默认以 ASAM 源码 / 安装包为准)
statusIcon
必填:否;声明来源:上游声明。
statusIcon 参数与事件数据
下列为声明可读视图;可导入类型以公开类型视图为准。分支条件与父属性一致。
枚举:false / true
默认值与来源
false(隐式 Boolean 默认;已安装组件)固定上游文档默认:false(2.14.7;文档事实,实际默认以 ASAM 源码 / 安装包为准)
showMessage
必填:否;声明来源:上游声明。
showMessage 参数与事件数据
下列为声明可读视图;可导入类型以公开类型视图为准。分支条件与父属性一致。
枚举:false / true
默认值与来源
true(已安装运行时;已安装组件)固定上游文档默认:true(2.14.7;文档事实,实际默认以 ASAM 源码 / 安装包为准)
固定上游源码默认表达式:true(2.14.7;源码事实,未作为 ASAM 运行实测)
validateOnRuleChange
必填:否;声明来源:上游声明。
validateOnRuleChange 参数与事件数据
下列为声明可读视图;可导入类型以公开类型视图为准。分支条件与父属性一致。
枚举:false / true
默认值与来源
true(已安装运行时;已安装组件)固定上游文档默认:true(2.14.7;文档事实,实际默认以 ASAM 源码 / 安装包为准)
固定上游源码默认表达式:true(2.14.7;源码事实,未作为 ASAM 运行实测)
hideRequiredAsterisk
必填:否;声明来源:上游声明。
hideRequiredAsterisk 参数与事件数据
下列为声明可读视图;可导入类型以公开类型视图为准。分支条件与父属性一致。
枚举:false / true
默认值与来源
false(隐式 Boolean 默认;已安装组件)固定上游文档默认:false(2.14.7;文档事实,实际默认以 ASAM 源码 / 安装包为准)
scrollToError
必填:否;声明来源:上游声明。
scrollToError 参数与事件数据
下列为声明可读视图;可导入类型以公开类型视图为准。分支条件与父属性一致。
枚举:false / true
默认值与来源
false(隐式 Boolean 默认;已安装组件)固定上游文档默认:false(2.14.7;文档事实,实际默认以 ASAM 源码 / 安装包为准)
size
必填:否;声明来源:ASAM 声明。
size 参数与事件数据
下列为声明可读视图;可导入类型以公开类型视图为准。分支条件与父属性一致。
枚举:"large" / "big" / "default" / "small"
默认值与来源
undefined(源码表达式;ASAM 声明)AsamBaseFormProps 公开类型视图
import type { AsamBaseFormProps, AsamControlSize } from '@asam-ui/ui';
type PublicMember<T, K extends PropertyKey> = T extends unknown ? K extends keyof T ? T[K] : never : never;
// AsamBaseFormProps
type PublicContract = {
"disabled"?: boolean | undefined;
"labelWidth"?: string | number | undefined;
"model"?: Record<string, any> | undefined;
"scrollIntoViewOptions"?: boolean | ScrollIntoViewOptions | undefined;
"rules"?: (AsamBaseFormProps)["rules"];
"labelPosition"?: "top" | "right" | "left" | undefined;
"requireAsteriskPosition"?: "right" | "left" | undefined;
"labelSuffix"?: string | undefined;
"inline"?: boolean | undefined;
"inlineMessage"?: boolean | undefined;
"statusIcon"?: boolean | undefined;
"showMessage"?: boolean | undefined;
"validateOnRuleChange"?: boolean | undefined;
"hideRequiredAsterisk"?: boolean | undefined;
"scrollToError"?: boolean | undefined;
"size"?: AsamControlSize | undefined;
};
参数与事件说明
validate
必填:是;声明来源:上游声明。
AsamBaseFormEmits 公开类型视图
import type { AsamBaseFormEmits } from '@asam-ui/ui';
// AsamBaseFormEmits
type PublicContract = {
"validate": (AsamBaseFormEmits)["validate"];
};
参数与事件说明
default
必填:否;声明来源:ASAM 声明。
default 参数与事件数据
下列为声明可读视图;可导入类型以公开类型视图为准。分支条件与父属性一致。
事件参数:(): unknown
AsamBaseFormSlots 公开类型视图
import type { AsamBaseFormSlots } from '@asam-ui/ui';
// AsamBaseFormSlots
type PublicContract = {
"default"?: (() => unknown) | undefined;
};
参数与事件说明
validate
必填:是;声明来源:上游声明。
validate 参数与事件数据
下列为声明可读视图;可导入类型以公开类型视图为准。分支条件与父属性一致。
事件参数:(callback?: Parameters<Extract<NonNullable<(AsamBaseFormExpose)["validate"]>, (...args: never[]) => unknown>>[0]): ReturnType<Extract<NonNullable<(AsamBaseFormExpose)["validate"]>, (...args: never[]) => unknown>>
validateField
必填:是;声明来源:上游声明。
validateField 参数与事件数据
下列为声明可读视图;可导入类型以公开类型视图为准。分支条件与父属性一致。
事件参数:(props?: Parameters<Extract<NonNullable<(AsamBaseFormExpose)["validateField"]>, (...args: never[]) => unknown>>[0], callback?: Parameters<Extract<NonNullable<(AsamBaseFormExpose)["validateField"]>, (...args: never[]) => unknown>>[1]): ReturnType<Extract<NonNullable<(AsamBaseFormExpose)["validateField"]>, (...args: never[]) => unknown>>
resetFields
必填:是;声明来源:上游声明。
resetFields 参数与事件数据
下列为声明可读视图;可导入类型以公开类型视图为准。分支条件与父属性一致。
事件参数:(props?: Parameters<Extract<NonNullable<(AsamBaseFormExpose)["resetFields"]>, (...args: never[]) => unknown>>[0]): void
clearValidate
必填:是;声明来源:上游声明。
clearValidate 参数与事件数据
下列为声明可读视图;可导入类型以公开类型视图为准。分支条件与父属性一致。
事件参数:(props?: Parameters<Extract<NonNullable<(AsamBaseFormExpose)["clearValidate"]>, (...args: never[]) => unknown>>[0]): void
scrollToField
必填:是;声明来源:上游声明。
scrollToField 参数与事件数据
下列为声明可读视图;可导入类型以公开类型视图为准。分支条件与父属性一致。
事件参数:(prop: Parameters<Extract<NonNullable<(AsamBaseFormExpose)["scrollToField"]>, (...args: never[]) => unknown>>[0]): void
getField
必填:是;声明来源:上游声明。
getField 参数与事件数据
下列为声明可读视图;可导入类型以公开类型视图为准。分支条件与父属性一致。
事件参数:(prop: Parameters<Extract<NonNullable<(AsamBaseFormExpose)["getField"]>, (...args: never[]) => unknown>>[0]): ReturnType<Extract<NonNullable<(AsamBaseFormExpose)["getField"]>, (...args: never[]) => unknown>>
fields
必填:是;声明来源:上游声明。
fields 参数与事件数据
下列为声明可读视图;可导入类型以公开类型视图为准。分支条件与父属性一致。
嵌套展开边界:框架 / 平台类型;完整类型见公开类型视图。
setInitialValues
必填:是;声明来源:上游声明。
setInitialValues 参数与事件数据
下列为声明可读视图;可导入类型以公开类型视图为准。分支条件与父属性一致。
事件参数:(initModel: Record<string, any>): void
AsamBaseFormExpose 公开类型视图
import type { AsamBaseFormExpose } from '@asam-ui/ui';
// AsamBaseFormExpose
type PublicContract = {
"validate": (AsamBaseFormExpose)["validate"];
"validateField": (AsamBaseFormExpose)["validateField"];
"resetFields": (AsamBaseFormExpose)["resetFields"];
"clearValidate": (AsamBaseFormExpose)["clearValidate"];
"scrollToField": (AsamBaseFormExpose)["scrollToField"];
"getField": (AsamBaseFormExpose)["getField"];
"fields": (AsamBaseFormExpose)["fields"];
"setInitialValues": (initModel: Record<string, any>) => void;
};