327 lines
7.7 KiB
Vue
327 lines
7.7 KiB
Vue
<template>
|
||
<div class="container">
|
||
<Breadcrumb :items="['menu.list', '公共组件Demo']" />
|
||
|
||
<!-- 使用 SearchTable 公共组件 -->
|
||
<SearchTable
|
||
:form-model="formModel"
|
||
:form-items="formItems"
|
||
:data="tableData"
|
||
:columns="columns"
|
||
:loading="loading"
|
||
:pagination="pagination"
|
||
title="公共组件演示"
|
||
search-button-text="查询"
|
||
reset-button-text="重置"
|
||
download-button-text="导出"
|
||
refresh-tooltip-text="刷新数据"
|
||
density-tooltip-text="表格密度"
|
||
column-setting-tooltip-text="列设置"
|
||
@search="handleSearch"
|
||
@reset="handleReset"
|
||
@page-change="handlePageChange"
|
||
@refresh="handleRefresh"
|
||
@download="handleDownload"
|
||
>
|
||
<!-- 工具栏左侧按钮 -->
|
||
<template #toolbar-left>
|
||
<a-button type="primary" @click="handleAdd">
|
||
<template #icon>
|
||
<icon-plus />
|
||
</template>
|
||
新增
|
||
</a-button>
|
||
<a-button status="success" @click="handleBatchDelete">
|
||
<template #icon>
|
||
<icon-delete />
|
||
</template>
|
||
批量删除
|
||
</a-button>
|
||
</template>
|
||
|
||
<!-- 表格自定义列:序号 -->
|
||
<template #index="{ rowIndex }">
|
||
{{ rowIndex + 1 + (pagination.current - 1) * pagination.pageSize }}
|
||
</template>
|
||
|
||
<!-- 表格自定义列:状态 -->
|
||
<template #status="{ record }">
|
||
<a-tag :color="record.status === 'active' ? 'green' : 'red'">
|
||
{{ record.status === 'active' ? '启用' : '禁用' }}
|
||
</a-tag>
|
||
</template>
|
||
|
||
<!-- 表格自定义列:头像 -->
|
||
<template #avatar="{ record }">
|
||
<a-avatar :style="{ backgroundColor: record.avatarColor }">
|
||
{{ record.name.charAt(0) }}
|
||
</a-avatar>
|
||
</template>
|
||
|
||
<!-- 表格自定义列:操作 -->
|
||
<template #operations="{ record }">
|
||
<a-space>
|
||
<a-button type="text" size="small" @click="handleView(record)">
|
||
查看
|
||
</a-button>
|
||
<a-button type="text" size="small" @click="handleEdit(record)">
|
||
编辑
|
||
</a-button>
|
||
<a-popconfirm content="确定要删除吗?" @ok="handleDelete(record)">
|
||
<a-button type="text" size="small" status="danger">
|
||
删除
|
||
</a-button>
|
||
</a-popconfirm>
|
||
</a-space>
|
||
</template>
|
||
</SearchTable>
|
||
</div>
|
||
</template>
|
||
|
||
<script lang="ts" setup>
|
||
import { computed, ref, reactive } from 'vue'
|
||
import { Message } from '@arco-design/web-vue'
|
||
import type { TableColumnData } from '@arco-design/web-vue/es/table/interface'
|
||
import type { FormItem } from '@/components/search-form/types'
|
||
|
||
// 定义表格数据类型
|
||
interface UserRecord {
|
||
id: number
|
||
name: string
|
||
email: string
|
||
department: string
|
||
role: string
|
||
status: 'active' | 'inactive'
|
||
avatarColor: string
|
||
createdAt: string
|
||
}
|
||
|
||
// 模拟数据生成
|
||
const generateMockData = (count: number): UserRecord[] => {
|
||
const departments = ['技术部', '产品部', '运营部', '市场部', '财务部']
|
||
const roles = ['管理员', '普通用户', '访客']
|
||
const names = ['张三', '李四', '王五', '赵六', '钱七', '孙八', '周九', '吴十']
|
||
const colors = ['#165DFF', '#0FC6C2', '#722ED1', '#F53F3F', '#FF7D00', '#00B42A']
|
||
|
||
return Array.from({ length: count }, (_, i) => ({
|
||
id: i + 1,
|
||
name: names[i % names.length] + (Math.floor(i / names.length) || ''),
|
||
email: `user${i + 1}@example.com`,
|
||
department: departments[i % departments.length],
|
||
role: roles[i % roles.length],
|
||
status: i % 3 === 0 ? 'inactive' : 'active',
|
||
avatarColor: colors[i % colors.length],
|
||
createdAt: `2024-${String((i % 12) + 1).padStart(2, '0')}-${String((i % 28) + 1).padStart(2, '0')}`,
|
||
}))
|
||
}
|
||
|
||
// 状态管理
|
||
const loading = ref(false)
|
||
const tableData = ref<UserRecord[]>([])
|
||
const formModel = ref({
|
||
name: '',
|
||
department: '',
|
||
status: '',
|
||
email: '',
|
||
})
|
||
|
||
const pagination = reactive({
|
||
current: 1,
|
||
pageSize: 10,
|
||
total: 0,
|
||
})
|
||
|
||
// 表单项配置
|
||
const formItems = computed<FormItem[]>(() => [
|
||
{
|
||
field: 'name',
|
||
label: '用户名',
|
||
type: 'input',
|
||
placeholder: '请输入用户名',
|
||
},
|
||
{
|
||
field: 'email',
|
||
label: '邮箱',
|
||
type: 'input',
|
||
placeholder: '请输入邮箱',
|
||
},
|
||
{
|
||
field: 'department',
|
||
label: '部门',
|
||
type: 'select',
|
||
placeholder: '请选择部门',
|
||
options: [
|
||
{ label: '技术部', value: '技术部' },
|
||
{ label: '产品部', value: '产品部' },
|
||
{ label: '运营部', value: '运营部' },
|
||
{ label: '市场部', value: '市场部' },
|
||
{ label: '财务部', value: '财务部' },
|
||
],
|
||
},
|
||
{
|
||
field: 'status',
|
||
label: '状态',
|
||
type: 'select',
|
||
placeholder: '请选择状态',
|
||
options: [
|
||
{ label: '启用', value: 'active' },
|
||
{ label: '禁用', value: 'inactive' },
|
||
],
|
||
},
|
||
])
|
||
|
||
// 表格列配置
|
||
const columns = computed<TableColumnData[]>(() => [
|
||
{
|
||
title: '序号',
|
||
dataIndex: 'index',
|
||
slotName: 'index',
|
||
width: 80,
|
||
},
|
||
{
|
||
title: '头像',
|
||
dataIndex: 'avatar',
|
||
slotName: 'avatar',
|
||
width: 80,
|
||
},
|
||
{
|
||
title: '用户名',
|
||
dataIndex: 'name',
|
||
width: 120,
|
||
},
|
||
{
|
||
title: '邮箱',
|
||
dataIndex: 'email',
|
||
width: 200,
|
||
},
|
||
{
|
||
title: '部门',
|
||
dataIndex: 'department',
|
||
width: 120,
|
||
},
|
||
{
|
||
title: '角色',
|
||
dataIndex: 'role',
|
||
width: 100,
|
||
},
|
||
{
|
||
title: '状态',
|
||
dataIndex: 'status',
|
||
slotName: 'status',
|
||
width: 100,
|
||
},
|
||
{
|
||
title: '创建时间',
|
||
dataIndex: 'createdAt',
|
||
width: 120,
|
||
},
|
||
{
|
||
title: '操作',
|
||
dataIndex: 'operations',
|
||
slotName: 'operations',
|
||
width: 200,
|
||
fixed: 'right',
|
||
},
|
||
])
|
||
|
||
// 模拟异步获取数据
|
||
const fetchData = async () => {
|
||
loading.value = true
|
||
|
||
// 模拟网络延迟
|
||
await new Promise(resolve => setTimeout(resolve, 500))
|
||
|
||
let data = generateMockData(86)
|
||
|
||
// 根据搜索条件过滤
|
||
if (formModel.value.name) {
|
||
data = data.filter(item => item.name.includes(formModel.value.name))
|
||
}
|
||
if (formModel.value.email) {
|
||
data = data.filter(item => item.email.includes(formModel.value.email))
|
||
}
|
||
if (formModel.value.department) {
|
||
data = data.filter(item => item.department === formModel.value.department)
|
||
}
|
||
if (formModel.value.status) {
|
||
data = data.filter(item => item.status === formModel.value.status)
|
||
}
|
||
|
||
// 更新分页
|
||
pagination.total = data.length
|
||
|
||
// 分页截取
|
||
const start = (pagination.current - 1) * pagination.pageSize
|
||
const end = start + pagination.pageSize
|
||
tableData.value = data.slice(start, end)
|
||
|
||
loading.value = false
|
||
}
|
||
|
||
// 事件处理
|
||
const handleSearch = () => {
|
||
pagination.current = 1
|
||
fetchData()
|
||
}
|
||
|
||
const handleReset = () => {
|
||
formModel.value = {
|
||
name: '',
|
||
department: '',
|
||
status: '',
|
||
email: '',
|
||
}
|
||
pagination.current = 1
|
||
fetchData()
|
||
}
|
||
|
||
const handlePageChange = (current: number) => {
|
||
pagination.current = current
|
||
fetchData()
|
||
}
|
||
|
||
const handleRefresh = () => {
|
||
fetchData()
|
||
Message.success('数据已刷新')
|
||
}
|
||
|
||
const handleDownload = () => {
|
||
Message.info('导出功能开发中...')
|
||
}
|
||
|
||
const handleAdd = () => {
|
||
Message.info('新增功能开发中...')
|
||
}
|
||
|
||
const handleBatchDelete = () => {
|
||
Message.warning('请先选择要删除的数据')
|
||
}
|
||
|
||
const handleView = (record: UserRecord) => {
|
||
Message.info(`查看用户:${record.name}`)
|
||
}
|
||
|
||
const handleEdit = (record: UserRecord) => {
|
||
Message.info(`编辑用户:${record.name}`)
|
||
}
|
||
|
||
const handleDelete = (record: UserRecord) => {
|
||
Message.success(`已删除用户:${record.name}`)
|
||
}
|
||
|
||
// 初始化加载数据
|
||
fetchData()
|
||
</script>
|
||
|
||
<script lang="ts">
|
||
export default {
|
||
name: 'SearchTableDemo',
|
||
}
|
||
</script>
|
||
|
||
<style scoped lang="less">
|
||
.container {
|
||
padding: 0 20px 20px 20px;
|
||
}
|
||
</style>
|