feat(table): 用户管理名片卡片官方示例

This commit is contained in:
augushong
2026-09-11 12:58:46 +00:00
parent 4a047e428c
commit 0708afddf0
2 changed files with 124 additions and 1 deletions

View File

@@ -3,4 +3,122 @@
<table id="currentTable" class="layui-table layui-hide" data-auth-add="{:auth('system.admin/add')}" data-auth-edit="{:auth('system.admin/edit')}" data-auth-delete="{:auth('system.admin/delete')}" data-auth-password="{:auth('system.admin/password')}" data-auth-modify="{:auth('system.admin/modify')}" lay-filter="currentTable">
</table>
</div>
</div>
</div>
<!-- 用户管理名片形态(layoutList 自定义 Vue 形态官方示例,任务 19)
硬约束:本节点必须位于页面根容器之外、Vue 渲染容器(#ua-layout-{tableId},
由框架在表格容器后动态创建)之外,否则会被 Vue 编译吞掉。
上下文契约(admin-table.js buildLayoutContext / 任务 17 定稿):
- rows:行上下文数组,d 与表格行数据同构(含原始字段 + _cells/_operatHtml/_checked/_disabled)
- list:列表上下文 {tableId, page, count, checkedAll}(Vue 形态不叫 _list)
- 行根元素携带 data-table-id + data-id 两属性即获得统一行选中委托(点击卡片
切换勾选,按钮/表单控件/layui 美化层自动豁免),选中态经 :class 高亮回显
- _cells/_operatHtml 含渲染产物 HTML,必须用 v-html 输出;纯文本字段用
{{ }} 原生插值(自动转义,与 laytpl 的 {{- }} 不同)
- 事件无需自行绑定:操作按钮与 switch 经页面级委托和 form 事件天然生效 -->
<script type="text/x-template" id="usercardTpl">
<div class="usercard-list">
<div class="ua-data-card usercard"
v-for="d in rows"
:key="d.id"
:data-id="d.id"
:data-table-id="list.tableId"
:class="{'ua-data-card-checked': d._checked, 'ua-data-card-disabled': d._disabled}">
<!-- 头部:圆形头像 + 账户名。head_img 直接取原始行字段绑定 src(渲染器
_cells.head_img 的内联缩略图样式不适合名片);无头像时显示内置图标
占位(当前库内数据均有头像,此分支为约定兜底) -->
<div class="usercard-header">
<img v-if="d.head_img" :src="d.head_img" :alt="d.username" class="usercard-avatar">
<span v-else class="usercard-avatar usercard-avatar-empty" title="未设置头像"><i class="layui-icon layui-icon-username"></i></span>
<div class="usercard-name">
<span class="usercard-username">{{ d.username }}</span>
<span v-if="d.nickname" class="usercard-nickname">{{ d.nickname }}</span>
</div>
</div>
<!-- 状态 switch:_cells.status 为 switch 渲染器输出的原生 checkbox,
容器 layui-form 祖先 + 挂载后 form.render 美化;切换经页面级
switch 委托提交 modify 接口,失败自动回滚重渲 -->
<div class="usercard-status" v-html="d._cells.status"></div>
<!-- 创建时间与手机:无渲染器的纯文本列不进 _cells(值为空串),
直接取原始行字段插值输出(模型获取器已将 create_time 格式化) -->
<div class="usercard-meta">
<span class="usercard-time"><i class="layui-icon layui-icon-time"></i> {{ d.create_time }}</span>
<span v-if="d.phone" class="usercard-phone"><i class="layui-icon layui-icon-cellphone"></i> {{ d.phone }}</span>
</div>
<!-- 操作按钮组:_operatHtml 为操作列渲染产物(编辑/设置密码/删除,
已按 data-auth-* 裁剪权限),点击行为由框架页面级委托承接 -->
<div class="usercard-operat" v-html="d._operatHtml"></div>
</div>
</div>
</script>
<!-- 名片形态页面级样式(示例边界:网格布局与头像圆形为本页自建,卡片基础
观感——边框/白底/hover/选中描边/操作按钮排布——复用 public.css 的
.ua-data-card 族,不修改公共样式) -->
<style>
.usercard-list {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
gap: 12px;
}
.usercard-header {
display: flex;
align-items: center;
}
.usercard-avatar {
flex: none;
width: 48px;
height: 48px;
border-radius: 50%;
object-fit: cover;
border: 1px solid #eee;
background-color: #f6f6f6;
}
.usercard-avatar-empty {
display: flex;
align-items: center;
justify-content: center;
color: #c2c2c2;
font-size: 24px;
}
.usercard-name {
min-width: 0;
margin-left: 10px;
line-height: 20px;
}
.usercard-username {
display: block;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
font-weight: bold;
}
.usercard-nickname {
display: block;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
color: #999;
font-size: 12px;
}
.usercard-status {
margin-top: 8px;
text-align: right;
}
.usercard-meta {
display: flex;
align-items: center;
justify-content: space-between;
margin-top: 8px;
color: #999;
font-size: 12px;
}
.usercard-meta .layui-icon {
font-size: 12px;
}
@media (max-width: 768px) {
.usercard-list {
grid-template-columns: 1fr;
}
}
</style>

View File

@@ -3,6 +3,11 @@ $(function () {
ua.table.render({
init: init,
controlled: true,
// 多形态视图官方示例:table(默认首选)+ 名片(Vue 自定义模板)。
// layoutList 条目 >1 时工具栏自动出现"视图"切换按钮;tplVueId 指向
// index.html 中的 <script type="text/x-template" id="usercardTpl">
// 节点(须位于渲染容器之外),模板上下文契约见该节点处注释。
layoutList: ['table', {name: 'usercard', title: '名片', tplVueId: '#usercardTpl'}],
cols: [[
{ type: "checkbox" },
{ field: 'id', width: 80, title: 'ID' },