任务卡片 ​
AsamTaskCard 展示任务编号、发布时间、批量、产品型号、班组、工位与状态,并将操作 key 交给使用方。状态展示不自动执行业务流程或请求接口。
状态与操作 ​
示例的任务数据拆在独立文件中。点击操作后,父组件根据 action 的 key 更新本地状态和按钮文案;恢复按钮重建初始数据。
状态与操作
<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";
Object.defineProperty(exports, "__esModule", { value: true });
const vue_1: any = require("vue");
const vue_2: any = require("vue");
const _hoisted_1: any = { class: "example-paragraph" };
const vue_3: any = require("vue");
const ui_1: any = require("@asam-ui/ui");
const task_js_1: any = require("./task.js");
exports.default = (0, vue_1.defineComponent)({
...{ name: 'AsamTaskCardBasicDemo' },
__name: 'Demo',
setup(__props?: any) {
const task: any = (0, vue_3.ref)((0, task_js_1.createTask)());
const lastAction: any = (0, vue_3.ref)('');
function advance(key?: any) {
lastAction.value = key;
if (key !== 'advance')
return;
if (task.value.status === 'pending') {
task.value.status = 'inProgress';
task.value.actions = [{ key: 'advance', label: '完成任务', variant: 'success' }];
}
else {
task.value.status = 'completed';
task.value.stage = 'finish';
task.value.actions = [];
}
}
function reset() {
task.value = (0, task_js_1.createTask)();
lastAction.value = '';
}
return (_ctx?: any, _cache?: any) => {
return ((0, vue_2.openBlock)(), (0, vue_2.createElementBlock)(vue_2.Fragment, null, [
(0, vue_2.createVNode)((0, vue_2.unref)(ui_1.AsamTaskCard), (0, vue_2.mergeProps)(task.value, { onAction: advance }), null, 16 /* FULL_PROPS */),
(0, vue_2.createElementVNode)("p", _hoisted_1, [
(0, vue_2.createElementVNode)("output", null, "最近操作:" + (0, vue_2.toDisplayString)(lastAction.value || '尚未操作') + ";状态:" + (0, vue_2.toDisplayString)(task.value.status), 1 /* TEXT */)
]),
(0, vue_2.createVNode)((0, vue_2.unref)(ui_1.AsamButton), {
type: "default",
onClick: reset
}, {
default: (0, vue_2.withCtx)(() => [...(_cache[0] || (_cache[0] = [
(0, vue_2.createTextVNode)("恢复任务", -1 /* CACHED */)
]))]),
_: 1 /* STABLE */
})
], 64 /* STABLE_FRAGMENT */));
};
}
});
exports.default.__scopeId = "data-v-4ab3660c";
},
"task.ts": (module: any, exports: any, require: any) => {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.createTask = createTask;
function createTask() {
return {
taskNo: 'TASK-001',
releaseTime: '2026-10-03 08:30:00',
batchCount: 24,
productModel: 'A-01',
teamName: '一班',
stations: ['装配', '复核'],
status: 'pending',
stage: 'mark',
actions: [{ key: 'advance', label: '开始', variant: 'primary' }]
};
}
},
};
const __dependencies: any = {"Demo.vue":{"./task.js":"task.ts"},"task.ts":{}};
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>
p[data-v-4ab3660c]:where(.example-paragraph) {
margin-block: 16px;
line-height: 1.8;
overflow-wrap: anywhere;
}
</style>
<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";
Object.defineProperty(exports, "__esModule", { value: true });
const vue_1 = require("vue");
const _hoisted_1 = { class: "example-paragraph" };
const vue_2 = require("vue");
const ui_1 = require("@asam-ui/ui");
const task_js_1 = require("./task.js");
exports.default = Object.assign({ name: 'AsamTaskCardBasicDemo' }, {
__name: 'Demo',
setup(__props) {
const task = (0, vue_2.ref)((0, task_js_1.createTask)());
const lastAction = (0, vue_2.ref)('');
function advance(key) {
lastAction.value = key;
if (key !== 'advance')
return;
if (task.value.status === 'pending') {
task.value.status = 'inProgress';
task.value.actions = [{ key: 'advance', label: '完成任务', variant: 'success' }];
}
else {
task.value.status = 'completed';
task.value.stage = 'finish';
task.value.actions = [];
}
}
function reset() {
task.value = (0, task_js_1.createTask)();
lastAction.value = '';
}
return (_ctx, _cache) => {
return ((0, vue_1.openBlock)(), (0, vue_1.createElementBlock)(vue_1.Fragment, null, [
(0, vue_1.createVNode)((0, vue_1.unref)(ui_1.AsamTaskCard), (0, vue_1.mergeProps)(task.value, { onAction: advance }), null, 16 /* FULL_PROPS */),
(0, vue_1.createElementVNode)("p", _hoisted_1, [
(0, vue_1.createElementVNode)("output", null, "最近操作:" + (0, vue_1.toDisplayString)(lastAction.value || '尚未操作') + ";状态:" + (0, vue_1.toDisplayString)(task.value.status), 1 /* TEXT */)
]),
(0, vue_1.createVNode)((0, vue_1.unref)(ui_1.AsamButton), {
type: "default",
onClick: reset
}, {
default: (0, vue_1.withCtx)(() => [...(_cache[0] || (_cache[0] = [
(0, vue_1.createTextVNode)("恢复任务", -1 /* CACHED */)
]))]),
_: 1 /* STABLE */
})
], 64 /* STABLE_FRAGMENT */));
};
}
});
exports.default.__scopeId = "data-v-89652024";
},
"task.js": (module, exports, require) => {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.createTask = createTask;
function createTask() {
return {
taskNo: 'TASK-001',
releaseTime: '2026-10-03 08:30:00',
batchCount: 24,
productModel: 'A-01',
teamName: '一班',
stations: ['装配', '复核'],
status: 'pending',
stage: 'mark',
actions: [{ key: 'advance', label: '开始', variant: 'primary' }]
};
}
},
};
const __dependencies = {"Demo.vue":{"./task.js":"task.js"},"task.js":{}};
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>
p[data-v-89652024]:where(.example-paragraph) {
margin-block: 16px;
line-height: 1.8;
overflow-wrap: anywhere;
}
</style>
status 为 pending、inProgress 或 completed,stage 可选 mark 或 finish。任务编号、发布时间、批量、型号、班组、工位数组和状态是公开必需输入。组件将完整的 YYYY-MM-DD HH:mm:ss 发布时间显示到分钟,其他文本保持原样;工位用顿号连接。
actions 中的 key 标识操作,label 是显示文案,variant 沿用 AsamButton 的语义类型。默认操作按钮采用 small 尺寸,事件只返回 key,业务数据应由调用方根据当前任务取得。
自定义卡片内容 ​
示例使用全部内容插槽,并显式处理自定义操作按钮。
自定义全部内容插槽
<template>
<div class="demo-root-layout">
<AsamTaskCard
task-no="TASK-SLOT"
release-time="今日 09:00"
:batch-count="8"
product-model="B-02"
team-name="二班"
:stations="['检验']"
status="inProgress"
stage="mark"
>
<template #icon><span aria-hidden="true">✓</span></template>
<template #title>检验任务</template>
<template #subTitle>班组自定义副标题</template>
<p class="example-paragraph">该内容由 default 插槽提供,任务基础输入仍完整保留。</p>
<template #action>
<AsamButton size="small" type="default" @click="count++"> 查看记录 </AsamButton>
</template>
</AsamTaskCard>
<output>自定义操作次数:{{ count }}</output>
</div>
</template>
<script lang="ts" setup>
defineOptions({ name: 'AsamTaskCardSlotsDemo' });
import { ref } from 'vue';
import { AsamButton, AsamTaskCard } from '@asam-ui/ui';
const count = ref(0);
</script>
<style scoped>
.demo-root-layout {
display: grid;
gap: var(--asam-space-md);
justify-items: start;
}
.demo-root-layout > :is(p, pre, output) {
margin-block: 0;
}
</style>
<style scoped>
p:where(.example-paragraph) {
margin-block: 16px;
line-height: 1.8;
overflow-wrap: anywhere;
}
</style>
<template>
<div class="demo-root-layout">
<AsamTaskCard
task-no="TASK-SLOT"
release-time="今日 09:00"
:batch-count="8"
product-model="B-02"
team-name="二班"
:stations="['检验']"
status="inProgress"
stage="mark"
>
<template #icon><span aria-hidden="true">✓</span></template>
<template #title>检验任务</template>
<template #subTitle>班组自定义副标题</template>
<p class="example-paragraph">该内容由 default 插槽提供,任务基础输入仍完整保留。</p>
<template #action>
<AsamButton size="small" type="default" @click="count++"> 查看记录 </AsamButton>
</template>
</AsamTaskCard>
<output>自定义操作次数:{{ count }}</output>
</div>
</template>
<script setup>
defineOptions({ name: 'AsamTaskCardSlotsDemo' });
import { ref } from 'vue';
import { AsamButton, AsamTaskCard } from '@asam-ui/ui';
const count = ref(0);
</script>
<style scoped>
.demo-root-layout {
display: grid;
gap: var(--asam-space-md);
justify-items: start;
}
.demo-root-layout > :is(p, pre, output) {
margin-block: 0;
}
</style>
<style scoped>
p:where(.example-paragraph) {
margin-block: 16px;
line-height: 1.8;
overflow-wrap: anywhere;
}
</style>
icon、title、subTitle、default、action 替换对应区域;subTitle 的大小写需保持一致。action 插槽覆盖默认操作,使用方应自己绑定处理函数,不会自动触发组件的 action 事件。没有操作数组且没有操作插槽时不显示操作区。
组件没有实例方法。外层卡片接收透传属性;任务状态和阶段负责视觉表达,权限检查、持久化和异常处理由宿主实现。
组合用法 ​
在 AsamCard 的完整场景中使用本入口;包含 basic、simple、with-images、shadow。
任务状态、阶段与动作 ​
status 的 pending/inProgress/completed 与 stage 的 mark/finish 分开表达。 完整说明。
任务状态、阶段与动作
<template>
<div class="demo-root-layout">
<AsamButton type="default" native-type="button" @click="step = (step + 1) % states.length"
>切换任务状态</AsamButton
>
<AsamButton type="default" native-type="button" @click="withActions = !withActions"
>切换任务动作</AsamButton
>
<AsamTaskCard
task-no="TASK-LONG-012345678901234567890123456789"
release-time="2026-10-05 08:30:45"
batch-count="12"
product-model="长型号测试"
team-name="测试班组"
:stations="['A01', 'A02']"
:status="states[step]"
:stage="step === 0 ? 'mark' : 'finish'"
:actions="withActions ? actions : []"
@action="action = $event"
/>
<output v-bind="domDataAttrs('data-task-action')">{{ action }}</output>
</div>
</template>
<script lang="ts" setup>
import type { HTMLAttributes } from 'vue';
import { ref } from 'vue';
import { AsamButton, AsamTaskCard } from '@asam-ui/ui';
import type { AsamTaskCardAction, AsamTaskCardStatus } from '@asam-ui/ui';
defineOptions({ name: 'AsamTaskCardBoundariesDemo' });
const step = ref(0);
const withActions = ref(true);
const states: AsamTaskCardStatus[] = ['pending', 'inProgress', 'completed'];
const actions: AsamTaskCardAction[] = [{ key: 'confirm', label: '确认任务', variant: 'primary' }];
const action = ref('');
type DemoDataAttributes = Record<`data-${string}`, string | number | boolean | null | undefined>;
const domDataAttrs = (
name: `data-${string}`,
value: string | number | boolean | null | undefined = ''
): Pick<HTMLAttributes, 'class'> & DemoDataAttributes => ({
class: 'ui032-data-marker',
[name]: value
});
</script>
<style scoped>
.demo-root-layout {
display: grid;
gap: var(--asam-space-md);
justify-items: start;
}
.demo-root-layout > :is(p, pre, output) {
margin-block: 0;
}
</style>
<template>
<div class="demo-root-layout">
<AsamButton type="default" native-type="button" @click="step = (step + 1) % states.length"
>切换任务状态</AsamButton
>
<AsamButton type="default" native-type="button" @click="withActions = !withActions"
>切换任务动作</AsamButton
>
<AsamTaskCard
task-no="TASK-LONG-012345678901234567890123456789"
release-time="2026-10-05 08:30:45"
batch-count="12"
product-model="长型号测试"
team-name="测试班组"
:stations="['A01', 'A02']"
:status="states[step]"
:stage="step === 0 ? 'mark' : 'finish'"
:actions="withActions ? actions : []"
@action="action = $event"
/>
<output v-bind="domDataAttrs('data-task-action')">{{ action }}</output>
</div>
</template>
<script setup>
import { ref } from 'vue';
import { AsamButton, AsamTaskCard } from '@asam-ui/ui';
defineOptions({ name: 'AsamTaskCardBoundariesDemo' });
const step = ref(0);
const withActions = ref(true);
const states = ['pending', 'inProgress', 'completed'];
const actions = [{ key: 'confirm', label: '确认任务', variant: 'primary' }];
const action = ref('');
const domDataAttrs = (name, value = '') => ({ class: 'ui032-data-marker', [name]: value });
</script>
<style scoped>
.demo-root-layout {
display: grid;
gap: var(--asam-space-md);
justify-items: start;
}
.demo-root-layout > :is(p, pre, output) {
margin-block: 0;
}
</style>
API
属性 AsamTaskCardProps
| 属性名 | 说明 | 类型 | 默认值 |
|---|---|---|---|
taskNo | — | string | — |
releaseTime | — | string | — |
batchCount | — | string | number | '' |
productModel | — | string | — |
teamName | — | string | — |
stations | — | string[] | () => [] |
status | — | enum"pending" | "inProgress" | "completed"完整类型:AsamTaskCardStatus | — |
stage | — | enum"mark" | "finish"完整类型:AsamTaskCardStage | undefined | undefined |
actions | — | AsamTaskCardAction[] | undefined | () => [] |
事件 AsamTaskCardEmits
| 属性名 | 说明 | 类型 | 默认值 |
|---|---|---|---|
action | — | [key: string] | — |
插槽 AsamTaskCardSlots
| 属性名 | 说明 | 类型 | 默认值 |
|---|---|---|---|
icon | — | (() => unknown) | undefined | — |
title | — | (() => unknown) | undefined | — |
subTitle | — | (() => unknown) | undefined | — |
default | — | (() => unknown) | undefined | — |
action | — | (() => unknown) | undefined | — |
类型 AsamTaskCardStatus
类型 AsamTaskCardStage
类型 AsamTaskCardAction
| 属性名 | 说明 | 类型 | 默认值 |
|---|---|---|---|
key | — | string | — |
label | — | string | — |
variant | 任务卡操作外观,透传给 AsamButton.type。 | enum"" | "default" | "text" | "primary" | "gradient" | "secondary" | "accent" | "success" | "danger" | "warning" | "info" | "ghost"完整类型:AsamButtonType | undefined | — |
用法与契约补充说明 ​
任务状态、阶段与动作 ​
status 的 pending/inProgress/completed 与 stage 的 mark/finish 分开表达。时间仅对完整秒数格式省略秒,工位以顿号连接。动作事件保留业务 key;无动作且无 action 插槽时不创建空页脚。已有 slots 示例覆盖五个可替换区域。长文本完整保留在 title 与正文,不隐式省略字段。
关联组件
参数与事件补充说明
参数与事件说明
taskNo
必填:是;声明来源:ASAM 声明。
releaseTime
必填:是;声明来源:ASAM 声明。
batchCount
必填:是;声明来源:ASAM 声明。
默认值与来源
''(源码表达式;ASAM 声明)productModel
必填:是;声明来源:ASAM 声明。
teamName
必填:是;声明来源:ASAM 声明。
stations
必填:是;声明来源:ASAM 声明。
stations 参数与事件数据
下列为声明可读视图;可导入类型以公开类型视图为准。分支条件与父属性一致。
嵌套展开边界:框架 / 平台类型;完整类型见公开类型视图。
默认值与来源
() => [](源码表达式;ASAM 声明)status
必填:是;声明来源:ASAM 声明。
status 参数与事件数据
下列为声明可读视图;可导入类型以公开类型视图为准。分支条件与父属性一致。
枚举:"pending" / "inProgress" / "completed"
stage
必填:否;声明来源:ASAM 声明。
stage 参数与事件数据
下列为声明可读视图;可导入类型以公开类型视图为准。分支条件与父属性一致。
枚举:"mark" / "finish"
默认值与来源
undefined(源码表达式;ASAM 声明)actions
必填:否;声明来源:ASAM 声明。
默认值与来源
() => [](源码表达式;ASAM 声明)AsamTaskCardProps 公开类型视图
import type { AsamTaskCardProps, AsamTaskCardAction, AsamTaskCardStatus, AsamTaskCardStage } from '@asam-ui/ui';
// AsamTaskCardProps
type PublicContract = {
"taskNo": string;
"releaseTime": string;
"batchCount": string | number;
"productModel": string;
"teamName": string;
"stations": string[];
"status": AsamTaskCardStatus;
"stage"?: AsamTaskCardStage | undefined;
"actions"?: AsamTaskCardAction[] | undefined;
};
参数与事件说明
action
必填:是;声明来源:ASAM 声明。
AsamTaskCardEmits 公开类型视图
import type { AsamTaskCardEmits } from '@asam-ui/ui';
// AsamTaskCardEmits
type PublicContract = {
"action": [key: string];
};
参数与事件说明
icon
必填:否;声明来源:ASAM 声明。
icon 参数与事件数据
下列为声明可读视图;可导入类型以公开类型视图为准。分支条件与父属性一致。
事件参数:(): unknown
title
必填:否;声明来源:ASAM 声明。
title 参数与事件数据
下列为声明可读视图;可导入类型以公开类型视图为准。分支条件与父属性一致。
事件参数:(): unknown
subTitle
必填:否;声明来源:ASAM 声明。
subTitle 参数与事件数据
下列为声明可读视图;可导入类型以公开类型视图为准。分支条件与父属性一致。
事件参数:(): unknown
default
必填:否;声明来源:ASAM 声明。
default 参数与事件数据
下列为声明可读视图;可导入类型以公开类型视图为准。分支条件与父属性一致。
事件参数:(): unknown
action
必填:否;声明来源:ASAM 声明。
action 参数与事件数据
下列为声明可读视图;可导入类型以公开类型视图为准。分支条件与父属性一致。
事件参数:(): unknown
AsamTaskCardSlots 公开类型视图
import type { AsamTaskCardSlots } from '@asam-ui/ui';
// AsamTaskCardSlots
type PublicContract = {
"icon"?: (() => unknown) | undefined;
"title"?: (() => unknown) | undefined;
"subTitle"?: (() => unknown) | undefined;
"default"?: (() => unknown) | undefined;
"action"?: (() => unknown) | undefined;
};
组合契约按分支生效;请同时查看公开类型。
AsamTaskCardStatus 公开类型视图
import type { AsamTaskCardStatus } from '@asam-ui/ui';
// AsamTaskCardStatus
type PublicContract = AsamTaskCardStatus;
组合契约按分支生效;请同时查看公开类型。
AsamTaskCardStage 公开类型视图
import type { AsamTaskCardStage } from '@asam-ui/ui';
// AsamTaskCardStage
type PublicContract = AsamTaskCardStage;
参数与事件说明
key
必填:是;声明来源:ASAM 声明。
label
必填:是;声明来源:ASAM 声明。
variant
必填:否;声明来源:ASAM 声明。
variant 参数与事件数据
下列为声明可读视图;可导入类型以公开类型视图为准。分支条件与父属性一致。
枚举:"" / "default" / "text" / "primary" / "gradient" / "secondary" / "accent" / "success" / "danger" / "warning" / "info" / "ghost"
AsamTaskCardAction 公开类型视图
import type { AsamTaskCardAction, AsamButtonType } from '@asam-ui/ui';
// AsamTaskCardAction
type PublicContract = {
"key": string;
"label": string;
"variant"?: AsamButtonType | undefined;
};