表单网格 ​
AsamFormGrid 为表单字段提供响应式列布局,可放在 AsamFormSection 中。字段值、校验和提交由使用方或表单组件负责。
响应式字段排列 ​
示例将可复用字段拆到独立 SFC,输入值保存在父组件。改变浏览器宽度可比较桌面三列、平板两列和手机一列;点击恢复默认值可重置演示数据。
响应式字段排列
vue
<template><StandaloneDemo /></template>
<script lang="ts" setup>
import * as __external0 from "vue";
import * as __external1 from "@asam-ui/ui";
const __external: any = {"vue": { ...__external0, __esModule: true },
"@asam-ui/ui": { ...__external1, __esModule: true }};
const __modules: any = {
"Demo.vue": (module: any, exports: any, require: any) => {
"use strict";
var __importDefault: any = function (mod?: any) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const vue_1: any = require("vue");
const vue_2: any = require("vue");
const _hoisted_1: any = { class: "demo-root-layout" };
const vue_3: any = require("vue");
const ui_1: any = require("@asam-ui/ui");
const Field_vue_1: any = __importDefault(require("./Field.vue"));
exports.default = (0, vue_1.defineComponent)({
...{ name: 'AsamFormGridBasicExample' },
__name: 'Demo',
setup(__props?: any) {
const invalid: any = (0, vue_3.ref)(false);
const form: any = (0, vue_3.reactive)({ name: '装配任务', model: 'A-01', team: '一班' });
function reset() {
Object.assign(form, { name: '装配任务', model: 'A-01', team: '一班' });
}
return (_ctx?: any, _cache?: any) => {
return ((0, vue_2.openBlock)(), (0, vue_2.createElementBlock)("div", _hoisted_1, [
(0, vue_2.createVNode)((0, vue_2.unref)(ui_1.AsamCheckboxItem), {
modelValue: invalid.value,
"onUpdate:modelValue": _cache[0] || (_cache[0] = ($event?: any) => ((invalid).value = $event))
}, {
default: (0, vue_2.withCtx)(() => [...(_cache[4] || (_cache[4] = [
(0, vue_2.createTextVNode)(" 无效列数回退", -1 /* CACHED */)
]))]),
_: 1 /* STABLE */
}, 8 /* PROPS */, ["modelValue"]),
(0, vue_2.createVNode)((0, vue_2.unref)(ui_1.AsamFormGrid), {
columns: invalid.value ? 0 : 3,
"tablet-columns": invalid.value ? -1 : 2,
"mobile-columns": invalid.value ? 1.5 : 1,
gap: "var(--asam-space-lg)"
}, {
default: (0, vue_2.withCtx)(() => [
(0, vue_2.createVNode)(Field_vue_1.default, {
modelValue: form.name,
"onUpdate:modelValue": _cache[1] || (_cache[1] = ($event?: any) => ((form.name) = $event)),
label: "任务名称"
}, null, 8 /* PROPS */, ["modelValue"]),
(0, vue_2.createVNode)(Field_vue_1.default, {
modelValue: form.model,
"onUpdate:modelValue": _cache[2] || (_cache[2] = ($event?: any) => ((form.model) = $event)),
label: "产品型号"
}, null, 8 /* PROPS */, ["modelValue"]),
(0, vue_2.createVNode)(Field_vue_1.default, {
modelValue: form.team,
"onUpdate:modelValue": _cache[3] || (_cache[3] = ($event?: any) => ((form.team) = $event)),
label: "班组"
}, null, 8 /* PROPS */, ["modelValue"])
]),
_: 1 /* STABLE */
}, 8 /* PROPS */, ["columns", "tablet-columns", "mobile-columns"]),
(0, vue_2.createVNode)((0, vue_2.unref)(ui_1.AsamButton), {
type: "default",
class: "demo-reset",
onClick: reset
}, {
default: (0, vue_2.withCtx)(() => [...(_cache[5] || (_cache[5] = [
(0, vue_2.createTextVNode)("恢复默认值", -1 /* CACHED */)
]))]),
_: 1 /* STABLE */
}),
(0, vue_2.createElementVNode)("output", null, (0, vue_2.toDisplayString)(form.name) + " / " + (0, vue_2.toDisplayString)(form.model) + " / " + (0, vue_2.toDisplayString)(form.team), 1 /* TEXT */)
]));
};
}
});
exports.default.__scopeId = "data-v-b1faaae2";
},
"Field.vue": (module: any, exports: any, require: any) => {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const vue_1: any = require("vue");
const vue_2: any = require("vue");
const _hoisted_1: any = { class: "demo-field" };
const ui_1: any = require("@asam-ui/ui");
exports.default = (0, vue_1.defineComponent)({
...{ name: 'AsamFormGridFieldExample' },
__name: 'Field',
props: {
label: { type: String, required: true },
modelValue: { type: String, required: true }
},
emits: ["update:modelValue"],
setup(__props: any, { emit: __emit }: any) {
const emit: any = __emit;
return (_ctx?: any, _cache?: any) => {
return ((0, vue_2.openBlock)(), (0, vue_2.createElementBlock)("label", _hoisted_1, [
(0, vue_2.createElementVNode)("span", null, (0, vue_2.toDisplayString)(__props.label), 1 /* TEXT */),
(0, vue_2.createVNode)((0, vue_2.unref)(ui_1.AsamInput), {
"model-value": __props.modelValue,
"onUpdate:modelValue": _cache[0] || (_cache[0] = ($event?: any) => (emit('update:modelValue', String($event))))
}, null, 8 /* PROPS */, ["model-value"])
]));
};
}
});
exports.default.__scopeId = "data-v-ebae8c93";
},
};
const __dependencies: any = {"Demo.vue":{"./Field.vue":"Field.vue"},"Field.vue":{}};
const __cache: any = Object.create(null);
function __require(id: any): any {
if (__external[id]) return __external[id];
if (__cache[id]) return __cache[id].exports;
const module: any = { exports: {} };
__cache[id] = module;
__modules[id](module, module.exports, (dependency: any) => __require(__dependencies[id][dependency] || dependency));
return module.exports;
}
const StandaloneDemo = __require('Demo.vue').default;
</script>
<style>
.demo-reset[data-v-b1faaae2] {
margin: var(--asam-space-lg);
}
.demo-root-layout[data-v-b1faaae2] {
display: grid;
gap: var(--asam-space-md);
justify-items: start;
}
.demo-root-layout[data-v-b1faaae2] > :is(p, pre, output) {
margin-block: 0;
}
.demo-field[data-v-ebae8c93] {
display: grid;
gap: var(--asam-space-sm);
}
</style>
vue
<template><StandaloneDemo /></template>
<script setup>
import * as __external0 from "vue";
import * as __external1 from "@asam-ui/ui";
const __external = {"vue": { ...__external0, __esModule: true },
"@asam-ui/ui": { ...__external1, __esModule: true }};
const __modules = {
"Demo.vue": (module, exports, require) => {
"use strict";
var __importDefault = function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const vue_1 = require("vue");
const _hoisted_1 = { class: "demo-root-layout" };
const vue_2 = require("vue");
const ui_1 = require("@asam-ui/ui");
const Field_vue_1 = __importDefault(require("./Field.vue"));
exports.default = Object.assign({ name: 'AsamFormGridBasicExample' }, {
__name: 'Demo',
setup(__props) {
const invalid = (0, vue_2.ref)(false);
const form = (0, vue_2.reactive)({ name: '装配任务', model: 'A-01', team: '一班' });
function reset() {
Object.assign(form, { name: '装配任务', model: 'A-01', team: '一班' });
}
return (_ctx, _cache) => {
return ((0, vue_1.openBlock)(), (0, vue_1.createElementBlock)("div", _hoisted_1, [
(0, vue_1.createVNode)((0, vue_1.unref)(ui_1.AsamCheckboxItem), {
modelValue: invalid.value,
"onUpdate:modelValue": _cache[0] || (_cache[0] = $event => ((invalid).value = $event))
}, {
default: (0, vue_1.withCtx)(() => [...(_cache[4] || (_cache[4] = [
(0, vue_1.createTextVNode)(" 无效列数回退", -1 /* CACHED */)
]))]),
_: 1 /* STABLE */
}, 8 /* PROPS */, ["modelValue"]),
(0, vue_1.createVNode)((0, vue_1.unref)(ui_1.AsamFormGrid), {
columns: invalid.value ? 0 : 3,
"tablet-columns": invalid.value ? -1 : 2,
"mobile-columns": invalid.value ? 1.5 : 1,
gap: "var(--asam-space-lg)"
}, {
default: (0, vue_1.withCtx)(() => [
(0, vue_1.createVNode)(Field_vue_1.default, {
modelValue: form.name,
"onUpdate:modelValue": _cache[1] || (_cache[1] = $event => ((form.name) = $event)),
label: "任务名称"
}, null, 8 /* PROPS */, ["modelValue"]),
(0, vue_1.createVNode)(Field_vue_1.default, {
modelValue: form.model,
"onUpdate:modelValue": _cache[2] || (_cache[2] = $event => ((form.model) = $event)),
label: "产品型号"
}, null, 8 /* PROPS */, ["modelValue"]),
(0, vue_1.createVNode)(Field_vue_1.default, {
modelValue: form.team,
"onUpdate:modelValue": _cache[3] || (_cache[3] = $event => ((form.team) = $event)),
label: "班组"
}, null, 8 /* PROPS */, ["modelValue"])
]),
_: 1 /* STABLE */
}, 8 /* PROPS */, ["columns", "tablet-columns", "mobile-columns"]),
(0, vue_1.createVNode)((0, vue_1.unref)(ui_1.AsamButton), {
type: "default",
class: "demo-reset",
onClick: reset
}, {
default: (0, vue_1.withCtx)(() => [...(_cache[5] || (_cache[5] = [
(0, vue_1.createTextVNode)("恢复默认值", -1 /* CACHED */)
]))]),
_: 1 /* STABLE */
}),
(0, vue_1.createElementVNode)("output", null, (0, vue_1.toDisplayString)(form.name) + " / " + (0, vue_1.toDisplayString)(form.model) + " / " + (0, vue_1.toDisplayString)(form.team), 1 /* TEXT */)
]));
};
}
});
exports.default.__scopeId = "data-v-4304d554";
},
"Field.vue": (module, exports, require) => {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const vue_1 = require("vue");
const _hoisted_1 = { class: "demo-field" };
const ui_1 = require("@asam-ui/ui");
exports.default = Object.assign({ name: 'AsamFormGridFieldExample' }, {
__name: 'Field',
props: {
label: { type: String, required: true },
modelValue: { type: String, required: true }
},
emits: ['update:modelValue'],
setup(__props, { emit: __emit }) {
const emit = __emit;
return (_ctx, _cache) => {
return ((0, vue_1.openBlock)(), (0, vue_1.createElementBlock)("label", _hoisted_1, [
(0, vue_1.createElementVNode)("span", null, (0, vue_1.toDisplayString)(__props.label), 1 /* TEXT */),
(0, vue_1.createVNode)((0, vue_1.unref)(ui_1.AsamInput), {
"model-value": __props.modelValue,
"onUpdate:modelValue": _cache[0] || (_cache[0] = $event => (emit('update:modelValue', String($event))))
}, null, 8 /* PROPS */, ["model-value"])
]));
};
}
});
exports.default.__scopeId = "data-v-b9921cca";
},
};
const __dependencies = {"Demo.vue":{"./Field.vue":"Field.vue"},"Field.vue":{}};
const __cache = Object.create(null);
function __require(id) {
if (__external[id]) return __external[id];
if (__cache[id]) return __cache[id].exports;
const module = { exports: {} };
__cache[id] = module;
__modules[id](module, module.exports, (dependency) => __require(__dependencies[id][dependency] || dependency));
return module.exports;
}
const StandaloneDemo = __require('Demo.vue').default;
</script>
<style>
.demo-reset[data-v-4304d554] {
margin: var(--asam-space-lg);
}
.demo-root-layout[data-v-4304d554] {
display: grid;
gap: var(--asam-space-md);
justify-items: start;
}
.demo-root-layout[data-v-4304d554] > :is(p, pre, output) {
margin-block: 0;
}
.demo-field[data-v-b9921cca] {
display: grid;
gap: var(--asam-space-sm);
}
</style>
当前样式按视口宽度切换:小于 1024px 使用 tabletColumns,小于 640px 使用 mobileColumns,其余使用 columns。默认分别为 2、2、1;无效的列数回退到 1。断点基于视口,不根据局部容器宽度切换。
布局与表单职责 ​
gap 接受 CSS 长度字符串,省略时使用字段间距 token。网格只提供默认插槽,不注册字段,也不触发校验、提交或 reset。与表单配合时,将真实字段组件放入插槽,并在对应表单实例上执行校验与重置。
网格没有 size 属性。输入控件的四档尺寸在控件或主题层配置,列数与间距仍由网格控制。
API
属性 AsamFormGridProps
| 属性名 | 说明 | 类型 | 默认值 |
|---|---|---|---|
columns | — | number | undefined | 2 |
tabletColumns | — | number | undefined | 2 |
mobileColumns | — | number | undefined | 1 |
gap | — | string | undefined | — |
插槽 AsamFormGridSlots
| 属性名 | 说明 | 类型 | 默认值 |
|---|---|---|---|
default | — | (() => unknown) | undefined | — |
关联组件
参数与事件补充说明
参数与事件说明
columns
必填:否;声明来源:ASAM 声明。
默认值与来源
2(源码表达式;ASAM 声明)tabletColumns
必填:否;声明来源:ASAM 声明。
默认值与来源
2(源码表达式;ASAM 声明)mobileColumns
必填:否;声明来源:ASAM 声明。
默认值与来源
1(源码表达式;ASAM 声明)gap
必填:否;声明来源:ASAM 声明。
AsamFormGridProps 公开类型视图
ts
import type { AsamFormGridProps } from '@asam-ui/ui';
// AsamFormGridProps
type PublicContract = {
"columns"?: number | undefined;
"tabletColumns"?: number | undefined;
"mobileColumns"?: number | undefined;
"gap"?: string | undefined;
};
参数与事件说明
default
必填:否;声明来源:ASAM 声明。
default 参数与事件数据
下列为声明可读视图;可导入类型以公开类型视图为准。分支条件与父属性一致。
事件参数:(): unknown
AsamFormGridSlots 公开类型视图
ts
import type { AsamFormGridSlots } from '@asam-ui/ui';
// AsamFormGridSlots
type PublicContract = {
"default"?: (() => unknown) | undefined;
};