@morya-ui/mcp 0.5.0 → 0.5.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/data/catalog.json +69 -92
- package/data/example-coverage.json +7 -11
- package/data/golden-pages/dashboard-page.vue +20 -14
- package/data/golden-pages/detail-page.vue +3 -2
- package/data/golden-pages/empty-state.vue +7 -6
- package/data/golden-pages/form-in-dialog.vue +4 -5
- package/data/golden-pages/form-page.vue +1 -1
- package/data/golden-pages/landing-page.vue +8 -41
- package/data/golden-pages/list-page-dense.vue +12 -14
- package/data/golden-pages/list-page-rail.vue +16 -82
- package/data/golden-pages/list-page.vue +10 -8
- package/data/golden-pages/login-page.vue +10 -29
- package/data/golden-pages/result-page.vue +7 -18
- package/data/golden-pages/settings-page.vue +3 -3
- package/data/golden-pages/wizard-form.vue +2 -2
- package/dist/__tests__/tools.test.js +24 -1
- package/dist/index.js +1 -1
- package/dist/page-snippets.d.ts +4 -0
- package/dist/page-snippets.js +5 -0
- package/dist/tools.js +16 -0
- package/package.json +1 -1
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
|
-
"generatedAt": "2026-10-
|
|
3
|
-
"catalogGeneratedAt": "2026-10-
|
|
2
|
+
"generatedAt": "2026-10-14T09:30:52.509Z",
|
|
3
|
+
"catalogGeneratedAt": "2026-10-14T09:30:48.391Z",
|
|
4
4
|
"components": [
|
|
5
5
|
{
|
|
6
6
|
"id": "Accordion",
|
|
@@ -1555,13 +1555,12 @@
|
|
|
1555
1555
|
"exportName": "MInput",
|
|
1556
1556
|
"examples": 28,
|
|
1557
1557
|
"props": {
|
|
1558
|
-
"total":
|
|
1558
|
+
"total": 21,
|
|
1559
1559
|
"covered": 14,
|
|
1560
1560
|
"missing": [
|
|
1561
1561
|
"status",
|
|
1562
1562
|
"id",
|
|
1563
1563
|
"readonly",
|
|
1564
|
-
"allowClear",
|
|
1565
1564
|
"errorMessage",
|
|
1566
1565
|
"name",
|
|
1567
1566
|
"autocomplete",
|
|
@@ -1704,7 +1703,7 @@
|
|
|
1704
1703
|
"exportName": "MInputPassword",
|
|
1705
1704
|
"examples": 12,
|
|
1706
1705
|
"props": {
|
|
1707
|
-
"total":
|
|
1706
|
+
"total": 19,
|
|
1708
1707
|
"covered": 10,
|
|
1709
1708
|
"missing": [
|
|
1710
1709
|
"toggleMask",
|
|
@@ -1714,7 +1713,6 @@
|
|
|
1714
1713
|
"status",
|
|
1715
1714
|
"disabled",
|
|
1716
1715
|
"readonly",
|
|
1717
|
-
"allowClear",
|
|
1718
1716
|
"id",
|
|
1719
1717
|
"pt"
|
|
1720
1718
|
]
|
|
@@ -2050,7 +2048,7 @@
|
|
|
2050
2048
|
"exportName": "MMentions",
|
|
2051
2049
|
"examples": 6,
|
|
2052
2050
|
"props": {
|
|
2053
|
-
"total":
|
|
2051
|
+
"total": 20,
|
|
2054
2052
|
"covered": 4,
|
|
2055
2053
|
"missing": [
|
|
2056
2054
|
"split",
|
|
@@ -2066,7 +2064,6 @@
|
|
|
2066
2064
|
"fluid",
|
|
2067
2065
|
"emptyMessage",
|
|
2068
2066
|
"clearable",
|
|
2069
|
-
"allowClear",
|
|
2070
2067
|
"loading",
|
|
2071
2068
|
"id",
|
|
2072
2069
|
"pt"
|
|
@@ -2589,7 +2586,7 @@
|
|
|
2589
2586
|
"covered": 4,
|
|
2590
2587
|
"missing": [
|
|
2591
2588
|
"stars",
|
|
2592
|
-
"
|
|
2589
|
+
"clearable",
|
|
2593
2590
|
"disabled",
|
|
2594
2591
|
"ariaLabel",
|
|
2595
2592
|
"errorMessage",
|
|
@@ -3483,7 +3480,7 @@
|
|
|
3483
3480
|
"exportName": "MTextarea",
|
|
3484
3481
|
"examples": 10,
|
|
3485
3482
|
"props": {
|
|
3486
|
-
"total":
|
|
3483
|
+
"total": 23,
|
|
3487
3484
|
"covered": 13,
|
|
3488
3485
|
"missing": [
|
|
3489
3486
|
"status",
|
|
@@ -3492,7 +3489,6 @@
|
|
|
3492
3489
|
"resize",
|
|
3493
3490
|
"disabled",
|
|
3494
3491
|
"readonly",
|
|
3495
|
-
"allowClear",
|
|
3496
3492
|
"name",
|
|
3497
3493
|
"autocomplete",
|
|
3498
3494
|
"autofocus",
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
<script setup lang="ts">
|
|
2
2
|
/**
|
|
3
|
-
*
|
|
3
|
+
* 黄金样例:仪表盘页(结构母版)
|
|
4
|
+
* 结构骨架:面包屑 → 页头 → 可选告警 → KPI 网格 → 主区两栏。
|
|
5
|
+
* 视觉(密度/阴影/插画/文案)跟 styleDirection / 参考走,本样例仅镜像块顺序,不是唯一正确答案。
|
|
4
6
|
* @see DESIGN.md · morya-ui-pages references/page-layouts.md · visual-craft § Ops polish
|
|
5
7
|
*/
|
|
6
8
|
import {
|
|
@@ -77,16 +79,19 @@ function statusType(s: string) {
|
|
|
77
79
|
</MLayoutHeader>
|
|
78
80
|
|
|
79
81
|
<MLayoutContent>
|
|
80
|
-
|
|
82
|
+
<!-- density 跟 styleDirection;仪表盘常用 spacious,但不强制 -->
|
|
83
|
+
<MPageContent>
|
|
84
|
+
<!-- 标题/描述用领域真实文案替换 -->
|
|
81
85
|
<MPageHeader
|
|
82
|
-
title="
|
|
83
|
-
description="
|
|
86
|
+
title="{{页面标题}}"
|
|
87
|
+
description="{{页面说明}}"
|
|
84
88
|
/>
|
|
85
89
|
|
|
90
|
+
<!-- 可选告警:有实时性/延迟等提示时用 -->
|
|
86
91
|
<MAlert
|
|
87
92
|
type="info"
|
|
88
|
-
title="
|
|
89
|
-
description="
|
|
93
|
+
title="{{可选告警标题}}"
|
|
94
|
+
description="{{可选告警说明}}"
|
|
90
95
|
closable
|
|
91
96
|
/>
|
|
92
97
|
|
|
@@ -106,28 +111,29 @@ function statusType(s: string) {
|
|
|
106
111
|
|
|
107
112
|
<MGrid :cols="2" :x-gap="16" :y-gap="16" responsive="screen">
|
|
108
113
|
<MGridItem :span="1">
|
|
109
|
-
|
|
114
|
+
<!-- shadow / 是否用 MCard 包图表区跟 styleDirection -->
|
|
115
|
+
<MCard title="{{主图表区标题}}">
|
|
110
116
|
<MEmpty
|
|
111
|
-
title="
|
|
112
|
-
description="
|
|
117
|
+
title="{{图表空态标题}}"
|
|
118
|
+
description="{{图表空态说明}}"
|
|
113
119
|
illustration="activity-low"
|
|
114
120
|
/>
|
|
115
121
|
</MCard>
|
|
116
122
|
</MGridItem>
|
|
117
123
|
<MGridItem :span="1">
|
|
118
|
-
<MCard title="
|
|
124
|
+
<MCard title="{{最近列表区标题}}">
|
|
119
125
|
<div class="dashboard-plain-stats">
|
|
120
|
-
<MStatistic title="
|
|
121
|
-
<MStatistic title="
|
|
126
|
+
<MStatistic title="{{统计1}}" :value="128" />
|
|
127
|
+
<MStatistic title="{{统计2}}" :value="2.4" suffix="h" :precision="1" />
|
|
122
128
|
</div>
|
|
129
|
+
<!-- 嵌入式次要表格:不用 fill/paginator;bordered/size 跟密度 -->
|
|
123
130
|
<MTable
|
|
124
131
|
:columns="recentColumns"
|
|
125
132
|
:rows="recentRows"
|
|
126
133
|
size="small"
|
|
127
134
|
:paginator="false"
|
|
128
|
-
bordered
|
|
129
135
|
row-key="id"
|
|
130
|
-
aria-label="
|
|
136
|
+
aria-label="{{最近列表}}"
|
|
131
137
|
>
|
|
132
138
|
<template #cell-priority="{ value }">
|
|
133
139
|
<MTag
|
|
@@ -59,7 +59,7 @@ const activityRows = [
|
|
|
59
59
|
<MPageContent>
|
|
60
60
|
<MPageHeader
|
|
61
61
|
:title="profile.name"
|
|
62
|
-
description="
|
|
62
|
+
description="{{详情页说明}}"
|
|
63
63
|
>
|
|
64
64
|
<template #actions>
|
|
65
65
|
<MSpace>
|
|
@@ -90,7 +90,8 @@ const activityRows = [
|
|
|
90
90
|
</p>
|
|
91
91
|
</MPageSection>
|
|
92
92
|
|
|
93
|
-
|
|
93
|
+
<!-- bordered 跟密度,非默认 -->
|
|
94
|
+
<MDescriptions title="{{信息分组标题}}" :column="2">
|
|
94
95
|
<MDescriptionsItem label="姓名">
|
|
95
96
|
{{ profile.name }}
|
|
96
97
|
</MDescriptionsItem>
|
|
@@ -27,25 +27,26 @@ import {
|
|
|
27
27
|
|
|
28
28
|
<MLayoutContent>
|
|
29
29
|
<MPageContent>
|
|
30
|
-
<MPageHeader title="
|
|
30
|
+
<MPageHeader title="{{页面标题}}" description="{{页面说明}}">
|
|
31
31
|
<template #actions>
|
|
32
32
|
<MButton type="primary">
|
|
33
|
-
|
|
33
|
+
{{主操作}}
|
|
34
34
|
</MButton>
|
|
35
35
|
</template>
|
|
36
36
|
</MPageHeader>
|
|
37
37
|
|
|
38
|
+
<!-- 空态说明"接下来做什么";illustration 跟 styleDirection -->
|
|
38
39
|
<MEmpty
|
|
39
|
-
title="
|
|
40
|
-
description="
|
|
40
|
+
title="{{空态标题}}"
|
|
41
|
+
description="{{空态说明}}"
|
|
41
42
|
illustration="no-content"
|
|
42
43
|
>
|
|
43
44
|
<template #extra>
|
|
44
45
|
<MButton type="primary">
|
|
45
|
-
|
|
46
|
+
{{空态主操作}}
|
|
46
47
|
</MButton>
|
|
47
48
|
<MButton type="text">
|
|
48
|
-
|
|
49
|
+
{{空态次操作}}
|
|
49
50
|
</MButton>
|
|
50
51
|
</template>
|
|
51
52
|
</MEmpty>
|
|
@@ -101,21 +101,20 @@ async function onSave() {
|
|
|
101
101
|
|
|
102
102
|
<MLayoutContent>
|
|
103
103
|
<MPageContent>
|
|
104
|
-
<MPageHeader title="
|
|
104
|
+
<MPageHeader title="{{页面标题}}" description="{{页面说明}}">
|
|
105
105
|
<template #actions>
|
|
106
106
|
<MButton @click="openCreate" type="primary">
|
|
107
|
-
|
|
107
|
+
{{新建操作}}
|
|
108
108
|
</MButton>
|
|
109
109
|
</template>
|
|
110
110
|
</MPageHeader>
|
|
111
111
|
|
|
112
|
+
<!-- 列表内弹窗演示:striped/bordered 跟密度,非默认 -->
|
|
112
113
|
<MTable
|
|
113
114
|
:columns="columns"
|
|
114
115
|
:rows="rows"
|
|
115
116
|
row-key="id"
|
|
116
|
-
|
|
117
|
-
bordered
|
|
118
|
-
aria-label="用户列表"
|
|
117
|
+
aria-label="{{列表}}"
|
|
119
118
|
>
|
|
120
119
|
<template #cell-status="{ value }">
|
|
121
120
|
<MStatus
|
|
@@ -60,7 +60,7 @@ async function onSubmit() {
|
|
|
60
60
|
|
|
61
61
|
<MLayoutContent>
|
|
62
62
|
<MPageContent width="narrow">
|
|
63
|
-
<MPageHeader title="
|
|
63
|
+
<MPageHeader title="{{表单标题}}" description="{{表单说明}}" />
|
|
64
64
|
|
|
65
65
|
<MPageSection variant="form">
|
|
66
66
|
<MForm @submit="onSubmit">
|
|
@@ -34,13 +34,14 @@ const faqTabs = [
|
|
|
34
34
|
<MButton label="免费试用" size="small" />
|
|
35
35
|
</header>
|
|
36
36
|
|
|
37
|
+
<!-- 首屏单一任务;品牌/氛围跟 styleDirection,不默认渐变/发光 -->
|
|
37
38
|
<section class="landing-hero" aria-labelledby="hero-title">
|
|
38
|
-
<p class="landing-hero__brand"
|
|
39
|
+
<p class="landing-hero__brand">{{品牌名}}</p>
|
|
39
40
|
<MTitle id="hero-title" class="landing-hero__title">
|
|
40
|
-
|
|
41
|
+
{{首屏主张}}
|
|
41
42
|
</MTitle>
|
|
42
43
|
<MParagraph class="landing-hero__lead" type="secondary">
|
|
43
|
-
|
|
44
|
+
{{首屏导语}}
|
|
44
45
|
</MParagraph>
|
|
45
46
|
<div class="landing-hero__cta">
|
|
46
47
|
<MButton label="开始使用" />
|
|
@@ -228,12 +229,8 @@ const faqTabs = [
|
|
|
228
229
|
padding: var(--m-space-5);
|
|
229
230
|
border: 1px solid var(--m-color-border);
|
|
230
231
|
border-radius: var(--m-radius-md);
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
135deg,
|
|
234
|
-
color-mix(in srgb, var(--m-color-primary) 12%, var(--m-color-surface)),
|
|
235
|
-
var(--m-color-surface) 60%
|
|
236
|
-
);
|
|
232
|
+
/* hero 氛围跟 styleDirection;默认 token-only 平壳 */
|
|
233
|
+
background: var(--m-color-surface);
|
|
237
234
|
}
|
|
238
235
|
|
|
239
236
|
.landing-hero__track {
|
|
@@ -245,41 +242,11 @@ const faqTabs = [
|
|
|
245
242
|
.landing-hero__track span {
|
|
246
243
|
padding: var(--m-space-3) var(--m-space-4);
|
|
247
244
|
border-left: 3px solid var(--m-color-primary);
|
|
248
|
-
background:
|
|
245
|
+
background: var(--m-color-surface);
|
|
249
246
|
font-size: 0.875rem;
|
|
250
247
|
font-weight: 600;
|
|
251
248
|
}
|
|
252
249
|
|
|
253
|
-
@media (prefers-reduced-motion: no-preference) {
|
|
254
|
-
.landing-hero__track span {
|
|
255
|
-
animation: landing-fade-up 480ms ease both;
|
|
256
|
-
}
|
|
257
|
-
|
|
258
|
-
.landing-hero__track span:nth-child(2) {
|
|
259
|
-
animation-delay: 60ms;
|
|
260
|
-
}
|
|
261
|
-
|
|
262
|
-
.landing-hero__track span:nth-child(3) {
|
|
263
|
-
animation-delay: 120ms;
|
|
264
|
-
}
|
|
265
|
-
|
|
266
|
-
.landing-hero__track span:nth-child(4) {
|
|
267
|
-
animation-delay: 180ms;
|
|
268
|
-
}
|
|
269
|
-
}
|
|
270
|
-
|
|
271
|
-
@keyframes landing-fade-up {
|
|
272
|
-
from {
|
|
273
|
-
opacity: 0;
|
|
274
|
-
transform: translateY(0.4rem);
|
|
275
|
-
}
|
|
276
|
-
|
|
277
|
-
to {
|
|
278
|
-
opacity: 1;
|
|
279
|
-
transform: translateY(0);
|
|
280
|
-
}
|
|
281
|
-
}
|
|
282
|
-
|
|
283
250
|
.landing-section {
|
|
284
251
|
padding: clamp(2.5rem, 6vw, 4rem) clamp(1.25rem, 4vw, 3rem);
|
|
285
252
|
max-width: 72rem;
|
|
@@ -287,7 +254,7 @@ const faqTabs = [
|
|
|
287
254
|
|
|
288
255
|
.landing-section--alt {
|
|
289
256
|
border-block: 1px solid var(--m-color-border);
|
|
290
|
-
background:
|
|
257
|
+
background: var(--m-color-surface);
|
|
291
258
|
max-width: none;
|
|
292
259
|
}
|
|
293
260
|
|
|
@@ -2,7 +2,9 @@
|
|
|
2
2
|
/**
|
|
3
3
|
* 黄金样例:列表页 · dense(高密度工具台)
|
|
4
4
|
* structure: list · style: dense
|
|
5
|
-
*
|
|
5
|
+
* 结构与 list-page.vue 完全相同;差异只在「密度」一处,通过一组联动 craft 表达:
|
|
6
|
+
* MPageContent density="compact" · 控件 size="small" · MTable size="small" · 筛选 variant="plain"。
|
|
7
|
+
* 气质跟 styleDirection / 参考走,不要把本文件当唯一审美。
|
|
6
8
|
* @see list-page.vue · style-presets.md · page-layouts.md
|
|
7
9
|
*/
|
|
8
10
|
import {
|
|
@@ -59,11 +61,6 @@ const rows = [
|
|
|
59
61
|
{ id: '1', name: '示例项目 A', status: 'active', updatedAt: '09-01' },
|
|
60
62
|
{ id: '2', name: '示例项目 B', status: 'inactive', updatedAt: '08-28' },
|
|
61
63
|
{ id: '3', name: '示例项目 C', status: 'active', updatedAt: '08-25' },
|
|
62
|
-
{ id: '4', name: '示例项目 D', status: 'active', updatedAt: '08-20' },
|
|
63
|
-
{ id: '5', name: '示例项目 E', status: 'inactive', updatedAt: '08-15' },
|
|
64
|
-
{ id: '6', name: '示例项目 F', status: 'active', updatedAt: '08-12' },
|
|
65
|
-
{ id: '7', name: '示例项目 G', status: 'inactive', updatedAt: '08-10' },
|
|
66
|
-
{ id: '8', name: '示例项目 H', status: 'active', updatedAt: '08-08' },
|
|
67
64
|
]
|
|
68
65
|
</script>
|
|
69
66
|
|
|
@@ -85,15 +82,17 @@ const rows = [
|
|
|
85
82
|
</MLayoutHeader>
|
|
86
83
|
|
|
87
84
|
<MLayoutContent>
|
|
85
|
+
<!-- dense 关键:整页 density="compact" -->
|
|
88
86
|
<MPageContent fill density="compact">
|
|
89
|
-
<MPageHeader title="
|
|
87
|
+
<MPageHeader title="{{页面标题}}">
|
|
90
88
|
<template #actions>
|
|
91
89
|
<MButton size="small" type="primary">
|
|
92
|
-
|
|
90
|
+
{{主操作}}
|
|
93
91
|
</MButton>
|
|
94
92
|
</template>
|
|
95
93
|
</MPageHeader>
|
|
96
94
|
|
|
95
|
+
<!-- dense 关键:筛选 variant="plain" + 控件 size="small" -->
|
|
97
96
|
<MPageFilters aria-label="筛选" variant="plain">
|
|
98
97
|
<MSpace wrap>
|
|
99
98
|
<MInput
|
|
@@ -122,6 +121,7 @@ const rows = [
|
|
|
122
121
|
</template>
|
|
123
122
|
</MPageFilters>
|
|
124
123
|
|
|
124
|
+
<!-- dense 关键:MTable size="small" -->
|
|
125
125
|
<MTable
|
|
126
126
|
:columns="columns"
|
|
127
127
|
:rows="rows"
|
|
@@ -129,10 +129,8 @@ const rows = [
|
|
|
129
129
|
fill
|
|
130
130
|
paginator
|
|
131
131
|
size="small"
|
|
132
|
-
striped
|
|
133
|
-
bordered
|
|
134
132
|
row-key="id"
|
|
135
|
-
aria-label="
|
|
133
|
+
aria-label="{{列表}}"
|
|
136
134
|
>
|
|
137
135
|
<template #cell-status="{ value }">
|
|
138
136
|
<MStatus
|
|
@@ -151,10 +149,10 @@ const rows = [
|
|
|
151
149
|
</MSpace>
|
|
152
150
|
</template>
|
|
153
151
|
<template #empty>
|
|
154
|
-
<MEmpty title="
|
|
152
|
+
<MEmpty title="{{空态标题}}" description="{{空态说明}}" icon="user">
|
|
155
153
|
<template #extra>
|
|
156
154
|
<MButton size="small" type="primary">
|
|
157
|
-
|
|
155
|
+
{{空态主操作}}
|
|
158
156
|
</MButton>
|
|
159
157
|
</template>
|
|
160
158
|
</MEmpty>
|
|
@@ -165,4 +163,4 @@ const rows = [
|
|
|
165
163
|
</MLayout>
|
|
166
164
|
</MLayout>
|
|
167
165
|
</MConfigProvider>
|
|
168
|
-
</template>
|
|
166
|
+
</template>
|
|
@@ -2,7 +2,8 @@
|
|
|
2
2
|
/**
|
|
3
3
|
* 黄金样例:列表页 · rail(侧栏强调)
|
|
4
4
|
* structure: list · style: rail
|
|
5
|
-
*
|
|
5
|
+
* 结构与 list-page.vue 完全相同;差异只在「侧栏 chrome」一处(品牌区 + 侧栏氛围),
|
|
6
|
+
* 内容区(筛选/表格/空态)与 list-page 一致。氛围跟 styleDirection / 参考走。
|
|
6
7
|
* @see list-page.vue · style-presets.md · visual-craft § Atmosphere
|
|
7
8
|
*/
|
|
8
9
|
import {
|
|
@@ -17,22 +18,18 @@ import {
|
|
|
17
18
|
MLayoutSider,
|
|
18
19
|
MMenu,
|
|
19
20
|
MPageContent,
|
|
20
|
-
MPageFilterChips,
|
|
21
21
|
MPageFilters,
|
|
22
22
|
MPageHeader,
|
|
23
23
|
MSelect,
|
|
24
24
|
MSpace,
|
|
25
25
|
MStatus,
|
|
26
26
|
MTable,
|
|
27
|
-
MTag,
|
|
28
27
|
zhCN,
|
|
29
28
|
} from 'morya-ui'
|
|
30
|
-
import {
|
|
29
|
+
import { ref } from 'vue'
|
|
31
30
|
|
|
32
31
|
const keyword = ref('')
|
|
33
32
|
const status = ref<string | undefined>()
|
|
34
|
-
const department = ref<string | null>(null)
|
|
35
|
-
const filtersExpanded = ref(false)
|
|
36
33
|
const siderCollapsed = ref(false)
|
|
37
34
|
|
|
38
35
|
const menuModel = [
|
|
@@ -47,37 +44,9 @@ const statusOptions = [
|
|
|
47
44
|
{ label: '停用', value: 'inactive' },
|
|
48
45
|
]
|
|
49
46
|
|
|
50
|
-
const departmentOptions = [
|
|
51
|
-
{ label: '研发', value: '研发' },
|
|
52
|
-
{ label: '运营', value: '运营' },
|
|
53
|
-
{ label: '市场', value: '市场' },
|
|
54
|
-
]
|
|
55
|
-
|
|
56
|
-
const activeFilters = computed(() => {
|
|
57
|
-
const items: Array<{ key: string; label: string }> = []
|
|
58
|
-
if (keyword.value.trim()) {
|
|
59
|
-
items.push({ key: 'keyword', label: `关键词:${keyword.value.trim()}` })
|
|
60
|
-
}
|
|
61
|
-
if (status.value) {
|
|
62
|
-
const label = statusOptions.find((o) => o.value === status.value)?.label ?? status.value
|
|
63
|
-
items.push({ key: 'status', label: `状态:${label}` })
|
|
64
|
-
}
|
|
65
|
-
if (department.value) {
|
|
66
|
-
items.push({ key: 'department', label: `部门:${department.value}` })
|
|
67
|
-
}
|
|
68
|
-
return items
|
|
69
|
-
})
|
|
70
|
-
|
|
71
|
-
function clearFilter(key: string) {
|
|
72
|
-
if (key === 'keyword') keyword.value = ''
|
|
73
|
-
if (key === 'status') status.value = undefined
|
|
74
|
-
if (key === 'department') department.value = null
|
|
75
|
-
}
|
|
76
|
-
|
|
77
47
|
function resetFilters() {
|
|
78
48
|
keyword.value = ''
|
|
79
49
|
status.value = undefined
|
|
80
|
-
department.value = null
|
|
81
50
|
}
|
|
82
51
|
|
|
83
52
|
const columns = [
|
|
@@ -91,14 +60,13 @@ const rows = [
|
|
|
91
60
|
{ id: '1', name: '示例项目 A', status: 'active', updatedAt: '2026-09-01' },
|
|
92
61
|
{ id: '2', name: '示例项目 B', status: 'inactive', updatedAt: '2026-08-28' },
|
|
93
62
|
{ id: '3', name: '示例项目 C', status: 'active', updatedAt: '2026-08-25' },
|
|
94
|
-
{ id: '4', name: '示例项目 D', status: 'active', updatedAt: '2026-08-20' },
|
|
95
|
-
{ id: '5', name: '示例项目 E', status: 'inactive', updatedAt: '2026-08-15' },
|
|
96
63
|
]
|
|
97
64
|
</script>
|
|
98
65
|
|
|
99
66
|
<template>
|
|
100
67
|
<MConfigProvider :locale="zhCN">
|
|
101
68
|
<MLayout has-sider fill-viewport>
|
|
69
|
+
<!-- rail 关键:侧栏承载品牌区 + 侧栏氛围;内容区保持克制 -->
|
|
102
70
|
<MLayoutSider
|
|
103
71
|
v-model:collapsed="siderCollapsed"
|
|
104
72
|
bordered
|
|
@@ -107,7 +75,7 @@ const rows = [
|
|
|
107
75
|
>
|
|
108
76
|
<div class="gp-rail-sider__brand">
|
|
109
77
|
<span class="gp-rail-sider__mark" aria-hidden="true" />
|
|
110
|
-
<span v-if="!siderCollapsed" class="gp-rail-sider__name">
|
|
78
|
+
<span v-if="!siderCollapsed" class="gp-rail-sider__name">{{品牌名}}</span>
|
|
111
79
|
</div>
|
|
112
80
|
<MMenu
|
|
113
81
|
:model="menuModel"
|
|
@@ -122,22 +90,18 @@ const rows = [
|
|
|
122
90
|
<MBreadcrumb :model="[{ label: '首页', to: '/' }, { label: '用户管理' }]" />
|
|
123
91
|
</MLayoutHeader>
|
|
124
92
|
|
|
93
|
+
<!-- 内容区与 list-page 一致;视觉(variant/内联宽度)跟 styleDirection -->
|
|
125
94
|
<MLayoutContent>
|
|
126
95
|
<MPageContent fill>
|
|
127
|
-
<MPageHeader title="
|
|
96
|
+
<MPageHeader title="{{页面标题}}" description="{{页面说明}}">
|
|
128
97
|
<template #actions>
|
|
129
98
|
<MButton type="primary">
|
|
130
|
-
|
|
99
|
+
{{主操作}}
|
|
131
100
|
</MButton>
|
|
132
101
|
</template>
|
|
133
102
|
</MPageHeader>
|
|
134
103
|
|
|
135
|
-
<MPageFilters
|
|
136
|
-
v-model:expanded="filtersExpanded"
|
|
137
|
-
aria-label="筛选"
|
|
138
|
-
variant="filled"
|
|
139
|
-
collapsible
|
|
140
|
-
>
|
|
104
|
+
<MPageFilters aria-label="筛选" collapsible>
|
|
141
105
|
<MSpace wrap>
|
|
142
106
|
<MInput v-model="keyword" placeholder="搜索名称" clearable style="width: 14rem" />
|
|
143
107
|
<MSelect
|
|
@@ -156,41 +120,16 @@ const rows = [
|
|
|
156
120
|
重置
|
|
157
121
|
</MButton>
|
|
158
122
|
</template>
|
|
159
|
-
<template #advanced>
|
|
160
|
-
<MSpace wrap>
|
|
161
|
-
<MSelect
|
|
162
|
-
v-model="department"
|
|
163
|
-
:options="departmentOptions"
|
|
164
|
-
placeholder="部门"
|
|
165
|
-
clearable
|
|
166
|
-
style="width: 10rem"
|
|
167
|
-
/>
|
|
168
|
-
</MSpace>
|
|
169
|
-
</template>
|
|
170
123
|
</MPageFilters>
|
|
171
124
|
|
|
172
|
-
<MPageFilterChips v-if="activeFilters.length" label="已选" aria-label="已选筛选">
|
|
173
|
-
<MTag
|
|
174
|
-
v-for="item in activeFilters"
|
|
175
|
-
:key="item.key"
|
|
176
|
-
:value="item.label"
|
|
177
|
-
size="small"
|
|
178
|
-
bordered
|
|
179
|
-
closable
|
|
180
|
-
@close="clearFilter(item.key)"
|
|
181
|
-
/>
|
|
182
|
-
</MPageFilterChips>
|
|
183
|
-
|
|
184
125
|
<MTable
|
|
185
126
|
:columns="columns"
|
|
186
127
|
:rows="rows"
|
|
187
128
|
:rows-per-page="5"
|
|
188
129
|
fill
|
|
189
130
|
paginator
|
|
190
|
-
striped
|
|
191
|
-
bordered
|
|
192
131
|
row-key="id"
|
|
193
|
-
aria-label="
|
|
132
|
+
aria-label="{{列表}}"
|
|
194
133
|
>
|
|
195
134
|
<template #cell-status="{ value }">
|
|
196
135
|
<MStatus
|
|
@@ -210,13 +149,13 @@ const rows = [
|
|
|
210
149
|
</template>
|
|
211
150
|
<template #empty>
|
|
212
151
|
<MEmpty
|
|
213
|
-
title="
|
|
214
|
-
description="
|
|
152
|
+
title="{{空态标题}}"
|
|
153
|
+
description="{{空态说明}}"
|
|
215
154
|
icon="user"
|
|
216
155
|
>
|
|
217
156
|
<template #extra>
|
|
218
157
|
<MButton type="primary">
|
|
219
|
-
|
|
158
|
+
{{空态主操作}}
|
|
220
159
|
</MButton>
|
|
221
160
|
</template>
|
|
222
161
|
</MEmpty>
|
|
@@ -230,13 +169,9 @@ const rows = [
|
|
|
230
169
|
</template>
|
|
231
170
|
|
|
232
171
|
<style scoped>
|
|
172
|
+
/* rail 关键:侧栏氛围(token-only,不默认渐变/发光) */
|
|
233
173
|
.gp-rail-sider {
|
|
234
|
-
background:
|
|
235
|
-
linear-gradient(
|
|
236
|
-
180deg,
|
|
237
|
-
color-mix(in srgb, var(--m-color-primary) 14%, var(--m-color-surface)) 0%,
|
|
238
|
-
var(--m-color-surface) 42%
|
|
239
|
-
);
|
|
174
|
+
background: var(--m-color-surface);
|
|
240
175
|
}
|
|
241
176
|
|
|
242
177
|
.gp-rail-sider__brand {
|
|
@@ -267,6 +202,5 @@ const rows = [
|
|
|
267
202
|
|
|
268
203
|
.gp-rail-header {
|
|
269
204
|
border-bottom: 1px solid var(--m-color-border);
|
|
270
|
-
box-shadow: inset 0 -1px 0 color-mix(in srgb, var(--m-color-primary) 18%, transparent);
|
|
271
205
|
}
|
|
272
|
-
</style>
|
|
206
|
+
</style>
|