签入版本
This commit is contained in:
@@ -165,93 +165,168 @@ export function exampleExport(params) {
|
||||
| `querySchemas.ts` | 搜索表单字段定义 |
|
||||
|
||||
:::tip 关于以下示例
|
||||
以下代码使用原生 `el-table` / `el-form` 简化展示核心逻辑。实际项目中应使用封装好的 `BasicTable` + `useForm` 等组合式组件,详见[第 9 章组件文档](/zh/frontend/overview.html)。
|
||||
以下代码来自项目实际的 `example` 演示模块,使用封装好的 `BasicTable` + `BasicForm` 组合式组件,详见[第 9 章组件文档](/zh/frontend/overview.html)。
|
||||
:::
|
||||
|
||||
`index.vue`(列表页)示例:
|
||||
|
||||
```vue
|
||||
<!-- ui/src/views/tool/example/index.vue -->
|
||||
<!-- ui/src/views/tool/example/index.vue(节选,来自项目实际代码) -->
|
||||
<template>
|
||||
<div>
|
||||
<!-- 搜索表单 -->
|
||||
<el-form :model="searchForm" inline>
|
||||
<el-form-item label="名称">
|
||||
<el-input v-model="searchForm.name" placeholder="请输入名称" />
|
||||
</el-form-item>
|
||||
<el-form-item label="状态">
|
||||
<el-select v-model="searchForm.status" placeholder="请选择" clearable>
|
||||
<el-option label="启用" :value="1" />
|
||||
<el-option label="禁用" :value="0" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" @click="handleSearch">搜索</el-button>
|
||||
<el-button @click="handleReset">重置</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<!-- 搜索表单卡片 -->
|
||||
<n-card :bordered="false" class="pt-3 mb-3 proCard">
|
||||
<BasicForm @register="register" @submit="handleSubmit" @reset="handleReset" />
|
||||
</n-card>
|
||||
|
||||
<!-- 操作按钮 -->
|
||||
<el-button type="primary" @click="handleAdd">新增</el-button>
|
||||
<el-button type="danger" :disabled="!selectedIds.length" @click="handleBatchDelete">
|
||||
批量删除
|
||||
</el-button>
|
||||
|
||||
<!-- 数据表格 -->
|
||||
<el-table :data="tableData" @selection-change="handleSelectionChange">
|
||||
<el-table-column type="selection" width="55" />
|
||||
<el-table-column prop="id" label="ID" width="80" />
|
||||
<el-table-column prop="name" label="名称" />
|
||||
<el-table-column prop="typeText" label="类型" width="100" />
|
||||
<el-table-column prop="statusText" label="状态" width="100" />
|
||||
<el-table-column prop="sort" label="排序" width="80" />
|
||||
<el-table-column prop="createTime" label="创建时间" width="180" />
|
||||
<el-table-column label="操作" width="200">
|
||||
<template #default="{ row }">
|
||||
<el-button size="small" @click="handleEdit(row)">编辑</el-button>
|
||||
<el-button size="small" type="danger" @click="handleDelete(row.id)">删除</el-button>
|
||||
<!-- 数据表格卡片 -->
|
||||
<n-card :bordered="false" class="proCard">
|
||||
<BasicTable
|
||||
:columns="columns"
|
||||
:request="loadDataTable"
|
||||
:row-key="(row) => row.id"
|
||||
ref="basicTableRef"
|
||||
:actionColumn="actionColumn"
|
||||
@update:checked-row-keys="onCheckedRow"
|
||||
>
|
||||
<!-- 表格顶部工具栏 -->
|
||||
<template #tableTitle>
|
||||
<n-space>
|
||||
<n-button type="primary" @click="handleAdd" v-perm="['sys:example:add']">
|
||||
添加案例演示
|
||||
</n-button>
|
||||
<n-button
|
||||
type="error"
|
||||
@click="handleDelete()"
|
||||
:disabled="!rowKeys.length"
|
||||
v-perm="['sys:example:batchDelete']"
|
||||
>
|
||||
批量删除
|
||||
</n-button>
|
||||
</n-space>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</BasicTable>
|
||||
</n-card>
|
||||
|
||||
<!-- 分页 -->
|
||||
<el-pagination
|
||||
v-model:current-page="pageNo"
|
||||
v-model:page-size="pageSize"
|
||||
:total="total"
|
||||
@current-change="fetchData"
|
||||
<!-- 新增/编辑弹窗 -->
|
||||
<editDialog
|
||||
ref="createModalRef"
|
||||
v-if="editVisible"
|
||||
v-model:visible="editVisible"
|
||||
@success="reloadTable('noRefresh')"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, onMounted } from 'vue';
|
||||
import { getExamplePage, exampleDelete, exampleBatchDelete } from '@/api/tool/example';
|
||||
<script lang="ts" setup>
|
||||
import { h, nextTick, reactive, ref } from 'vue';
|
||||
import { useMessage, useDialog } from 'naive-ui';
|
||||
import { BasicTable, TableAction } from '@/components/Table';
|
||||
import { BasicForm, useForm } from '@/components/Form';
|
||||
import {
|
||||
getExamplePage,
|
||||
exampleDelete,
|
||||
exampleBatchDelete,
|
||||
} from '@/api/tool/example';
|
||||
import { columns } from './columns';
|
||||
import { schemas } from './querySchemas';
|
||||
import editDialog from './edit.vue';
|
||||
|
||||
const searchForm = ref({ name: '', status: '' });
|
||||
const tableData = ref([]);
|
||||
const pageNo = ref(1);
|
||||
const pageSize = ref(20);
|
||||
const total = ref(0);
|
||||
const selectedIds = ref([]);
|
||||
const message = useMessage();
|
||||
const dialog = useDialog();
|
||||
const basicTableRef = ref();
|
||||
const createModalRef = ref();
|
||||
const editVisible = ref(false);
|
||||
const rowKeys = ref([]);
|
||||
|
||||
const fetchData = async () => {
|
||||
const res = await getExamplePage({
|
||||
pageNo: pageNo.value,
|
||||
pageSize: pageSize.value,
|
||||
...searchForm.value,
|
||||
});
|
||||
tableData.value = res.records;
|
||||
total.value = res.total;
|
||||
// 查询参数(与搜索表单字段一一对应)
|
||||
const formParams = reactive({ name: '', type: '', status: '' });
|
||||
|
||||
// 操作列(固定右侧,auth 控制按钮权限)
|
||||
const actionColumn = reactive({
|
||||
width: 280,
|
||||
title: '操作',
|
||||
key: 'action',
|
||||
fixed: 'right',
|
||||
render(record) {
|
||||
return h(TableAction as any, {
|
||||
actions: [
|
||||
{ label: '编辑', type: 'info', onClick: handleEdit.bind(null, record), auth: ['sys:example:update'] },
|
||||
{ label: '删除', type: 'error', onClick: handleDelete.bind(null, record), auth: ['sys:example:delete'] },
|
||||
],
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
// 分页数据请求(BasicTable 内置分页)
|
||||
const loadDataTable = async (params) => {
|
||||
rowKeys.value = [];
|
||||
return await getExamplePage({ ...formParams, ...params });
|
||||
};
|
||||
|
||||
const handleSearch = () => { pageNo.value = 1; fetchData(); };
|
||||
const handleReset = () => { searchForm.value = { name: '', status: '' }; handleSearch(); };
|
||||
const handleDelete = async (id: number) => { await exampleDelete(id); fetchData(); };
|
||||
const handleBatchDelete = async () => { await exampleBatchDelete({ ids: selectedIds.value }); fetchData(); };
|
||||
const handleSelectionChange = (rows: any[]) => { selectedIds.value = rows.map((r) => r.id); };
|
||||
// 数据行选中
|
||||
function onCheckedRow(keys) {
|
||||
rowKeys.value = keys;
|
||||
}
|
||||
|
||||
onMounted(() => fetchData());
|
||||
// 刷新表格
|
||||
function reloadTable(noRefresh = '') {
|
||||
basicTableRef.value.reload(noRefresh ? {} : { pageNo: 1 });
|
||||
}
|
||||
|
||||
// 注册搜索表单
|
||||
const [register] = useForm({
|
||||
gridProps: { cols: '1 s:1 m:2 l:3 xl:4 2xl:4' },
|
||||
labelWidth: 80,
|
||||
schemas,
|
||||
});
|
||||
|
||||
// 提交搜索(条件写回后回第一页)
|
||||
function handleSubmit(values) {
|
||||
for (const key in formParams) formParams[key] = '';
|
||||
Object.assign(formParams, values);
|
||||
reloadTable();
|
||||
}
|
||||
|
||||
// 重置搜索
|
||||
function handleReset() {
|
||||
for (const key in formParams) formParams[key] = '';
|
||||
reloadTable();
|
||||
}
|
||||
|
||||
// 新增
|
||||
const handleAdd = async () => {
|
||||
editVisible.value = true;
|
||||
await nextTick();
|
||||
createModalRef.value.openModal();
|
||||
};
|
||||
|
||||
// 编辑
|
||||
async function handleEdit(record) {
|
||||
editVisible.value = true;
|
||||
await nextTick();
|
||||
createModalRef.value.openModal(record.id);
|
||||
}
|
||||
|
||||
// 删除(单条 / 批量,先弹确认框)
|
||||
function handleDelete(record?) {
|
||||
const ids = record ? [record.id] : rowKeys.value;
|
||||
if (!ids.length) {
|
||||
message.warning('请选择要删除的数据');
|
||||
return;
|
||||
}
|
||||
dialog.warning({
|
||||
title: '提示',
|
||||
content: record ? '确定删除该记录?' : `确定删除选中的 ${ids.length} 条记录?`,
|
||||
positiveText: '确定',
|
||||
negativeText: '取消',
|
||||
onPositiveClick: async () => {
|
||||
record ? await exampleDelete(record.id) : await exampleBatchDelete({ ids });
|
||||
message.success('删除成功');
|
||||
reloadTable();
|
||||
},
|
||||
});
|
||||
}
|
||||
</script>
|
||||
```
|
||||
|
||||
|
||||
Reference in New Issue
Block a user