Appearance
DataGrid 数据表格
用于展示多条结构类似的数据,可对数据进行排序、筛选、对比或其他自定义操作。
基础用法
基础的表格展示用法。
<template>
<div class="demo-container">
<MDataGrid
:columns="columns"
:data-source="dataSource"
height="400px"
/>
</div>
</template>
<script setup lang="ts">
import { MDataGrid } from 'moonwind-ui'
import type { DataGridColumn } from 'moonwind-ui'
interface User {
id: number
name: string
email: string
age: number
department: string
status: string
}
const columns: DataGridColumn[] = [
{ field: 'id', headerName: 'ID', width: 80 },
{ field: 'name', headerName: '姓名', width: 120 },
{ field: 'email', headerName: '邮箱', width: 200 },
{ field: 'age', headerName: '年龄', width: 80 },
{ field: 'department', headerName: '部门', width: 120 },
{ field: 'status', headerName: '状态', width: 100 }
]
const dataSource: User[] = [
{ id: 1, name: '张三', email: 'zhangsan@example.com', age: 28, department: '技术部', status: '在职' },
{ id: 2, name: '李四', email: 'lisi@example.com', age: 32, department: '产品部', status: '在职' },
{ id: 3, name: '王五', email: 'wangwu@example.com', age: 25, department: '设计部', status: '在职' },
{ id: 4, name: '赵六', email: 'zhaoliu@example.com', age: 30, department: '市场部', status: '离职' },
{ id: 5, name: '钱七', email: 'qianqi@example.com', age: 27, department: '技术部', status: '在职' },
{ id: 6, name: '孙八', email: 'sunba@example.com', age: 35, department: '人事部', status: '在职' },
{ id: 7, name: '周九', email: 'zhoujiu@example.com', age: 29, department: '财务部', status: '在职' },
{ id: 8, name: '吴十', email: 'wushi@example.com', age: 26, department: '技术部', status: '在职' }
]
</script>
<style scoped>
.demo-container {
margin: 20px 0;
border: 1px solid #e1e5e9;
border-radius: 6px;
padding: 16px;
background: #fff;
}
.hk-data-grid {
border: 1px solid #e8e8e8;
border-radius: 4px;
}
</style>分页
支持分页功能。
<template>
<div class="demo-container">
<MDataGrid
:columns="columns"
:data-source="dataSource"
:pagination="pagination"
:toolbar="{ visible: true, showQuickFilter: true, showReset: true }"
height="500px"
/>
</div>
</template>
<script setup lang="ts">
import { MDataGrid } from 'moonwind-ui'
import type { DataGridColumn, PaginationConfig } from 'moonwind-ui'
interface User {
id: number
name: string
email: string
age: number
department: string
status: string
joinDate: string
}
const columns: DataGridColumn<User>[] = [
{ field: 'id', headerName: 'ID', width: 80 },
{ field: 'name', headerName: '姓名', width: 120 },
{ field: 'email', headerName: '邮箱', width: 200 },
{ field: 'age', headerName: '年龄', width: 80 },
{ field: 'department', headerName: '部门', width: 120 },
{ field: 'status', headerName: '状态', width: 100 },
{ field: 'joinDate', headerName: '入职日期', width: 120 }
]
// 生成更多数据用于分页演示
const generateData = (): User[] => {
const departments = ['技术部', '产品部', '设计部', '市场部', '人事部', '财务部']
const statuses = ['在职', '离职', '试用期']
const data: User[] = []
for (let i = 1; i <= 50; i++) {
data.push({
id: i,
name: `用户${i}`,
email: `user${i}@example.com`,
age: 20 + Math.floor(Math.random() * 20),
department: departments[Math.floor(Math.random() * departments.length)],
status: statuses[Math.floor(Math.random() * statuses.length)],
joinDate: `2023-${String(Math.floor(Math.random() * 12) + 1).padStart(2, '0')}-${String(Math.floor(Math.random() * 28) + 1).padStart(2, '0')}`
})
}
return data
}
const dataSource = generateData()
const pagination: PaginationConfig = {
current: 1,
pageSize: 10,
total: dataSource.length,
showSizeChanger: true,
showQuickJumper: true,
showTotal: true,
pageSizeOptions: ['10', '20', '50', '100']
}
</script>
<style scoped>
.demo-container {
margin: 20px 0;
border: 1px solid #e1e5e9;
border-radius: 6px;
padding: 16px;
background: #fff;
}
.hk-data-grid {
border: 1px solid #e8e8e8;
border-radius: 4px;
}
</style>排序
对表格进行排序,可快速查找或对比数据。
<template>
<MDataGrid
:columns="columns"
:data-source="dataSource"
height="500px"
/>
</template>
<script setup lang="ts">
import { MDataGrid } from 'moonwind-ui'
import type { DataGridColumn } from 'moonwind-ui'
interface User {
id: number
name: string
email: string
age: number
salary: number
department: string
}
const columns: DataGridColumn[] = [
{ field: 'id', headerName: 'ID', width: 80, sortable: true },
{ field: 'name', headerName: '姓名', width: 120, sortable: true },
{ field: 'email', headerName: '邮箱', width: 200 },
{ field: 'age', headerName: '年龄', width: 80, sortable: true },
{
field: 'salary',
headerName: '薪资',
width: 120,
sortable: true,
cellRenderer: (params: any) => {
return `¥${params.value.toLocaleString()}`
}
},
{ field: 'department', headerName: '部门', width: 120, sortable: true }
]
const dataSource: User[] = [
{
id: 1,
name: '张三',
email: 'zhangsan@example.com',
age: 25,
salary: 8000,
department: '技术部'
},
{
id: 2,
name: '李四',
email: 'lisi@example.com',
age: 30,
salary: 12000,
department: '产品部'
},
{
id: 3,
name: '王五',
email: 'wangwu@example.com',
age: 28,
salary: 10000,
department: '设计部'
},
{
id: 4,
name: '赵六',
email: 'zhaoliu@example.com',
age: 32,
salary: 15000,
department: '技术部'
},
{
id: 5,
name: '钱七',
email: 'qianqi@example.com',
age: 27,
salary: 9000,
department: '运营部'
},
{
id: 6,
name: '孙八',
email: 'sunba@example.com',
age: 35,
salary: 18000,
department: '产品部'
},
{
id: 7,
name: '周九',
email: 'zhoujiu@example.com',
age: 26,
salary: 7500,
department: '设计部'
},
{
id: 8,
name: '吴十',
email: 'wushi@example.com',
age: 29,
salary: 11000,
department: '技术部'
}
]
</script>
<style scoped>
.hk-data-grid {
border: 1px solid #e8e8e8;
border-radius: 4px;
}
</style>筛选
对表格进行筛选,可快速查找数据。
<template>
<MDataGrid
:columns="columns"
:data-source="dataSource"
height="500px"
/>
</template>
<script setup lang="ts">
import { MDataGrid } from 'moonwind-ui'
import type { DataGridColumn } from 'moonwind-ui'
interface User {
id: number
name: string
email: string
age: number
department: string
status: string
}
const columns: DataGridColumn[] = [
{ field: 'id', headerName: 'ID', width: 80 },
{ field: 'name', headerName: '姓名', width: 120, filter: true },
{ field: 'email', headerName: '邮箱', width: 200, filter: true },
{ field: 'age', headerName: '年龄', width: 80, filter: 'agNumberColumnFilter' },
{
field: 'department',
headerName: '部门',
width: 120,
filter: 'agTextColumnFilter'
},
{
field: 'status',
headerName: '状态',
width: 100,
filter: 'agTextColumnFilter',
cellRenderer: (params: any) => {
const status = params.value
const colorMap: Record<string, string> = {
'在职': '#52c41a',
'离职': '#ff4d4f',
'试用期': '#faad14'
}
const color = colorMap[status] || '#666'
return `<span style="color: ${color}; font-weight: bold;">${status}</span>`
}
}
]
const dataSource: User[] = [
{
id: 1,
name: '张三',
email: 'zhangsan@example.com',
age: 25,
department: '技术部',
status: '在职'
},
{
id: 2,
name: '李四',
email: 'lisi@example.com',
age: 30,
department: '产品部',
status: '在职'
},
{
id: 3,
name: '王五',
email: 'wangwu@example.com',
age: 28,
department: '设计部',
status: '试用期'
},
{
id: 4,
name: '赵六',
email: 'zhaoliu@example.com',
age: 32,
department: '技术部',
status: '在职'
},
{
id: 5,
name: '钱七',
email: 'qianqi@example.com',
age: 27,
department: '运营部',
status: '离职'
},
{
id: 6,
name: '孙八',
email: 'sunba@example.com',
age: 35,
department: '产品部',
status: '在职'
},
{
id: 7,
name: '周九',
email: 'zhoujiu@example.com',
age: 26,
department: '设计部',
status: '试用期'
},
{
id: 8,
name: '吴十',
email: 'wushi@example.com',
age: 29,
department: '技术部',
status: '在职'
},
{
id: 9,
name: '郑十一',
email: 'zhengshiyi@example.com',
age: 31,
department: '运营部',
status: '在职'
},
{
id: 10,
name: '王十二',
email: 'wangshier@example.com',
age: 24,
department: '设计部',
status: '试用期'
}
]
</script>
<style scoped>
.hk-data-grid {
border: 1px solid #e8e8e8;
border-radius: 4px;
}
</style>自定义列
自定义列的显示内容。
<template>
<MDataGrid
:columns="columns"
:data-source="dataSource"
height="500px"
/>
</template>
<script setup lang="ts">
import { MDataGrid } from 'moonwind-ui'
import type { DataGridColumn } from 'moonwind-ui'
interface User {
id: number
name: string
email: string
age: number
status: 'active' | 'inactive'
avatar: string
}
const columns: DataGridColumn[] = [
{ field: 'id', headerName: 'ID', width: 80 },
{
field: 'avatar',
headerName: '头像',
width: 100,
cellRenderer: (params: any) => {
return `<img src="${params.value}" alt="头像" style="width: 32px; height: 32px; border-radius: 50%;" />`
}
},
{ field: 'name', headerName: '姓名', width: 120 },
{ field: 'email', headerName: '邮箱', width: 200 },
{ field: 'age', headerName: '年龄', width: 80 },
{
field: 'status',
headerName: '状态',
width: 100,
cellRenderer: (params: any) => {
const status = params.value
const color = status === 'active' ? '#52c41a' : '#ff4d4f'
const text = status === 'active' ? '活跃' : '非活跃'
return `<span style="color: ${color}; font-weight: bold;">${text}</span>`
}
}
]
const dataSource: User[] = [
{
id: 1,
name: '张三',
email: 'zhangsan@example.com',
age: 25,
status: 'active',
avatar: 'https://api.dicebear.com/7.x/avataaars/svg?seed=1'
},
{
id: 2,
name: '李四',
email: 'lisi@example.com',
age: 30,
status: 'inactive',
avatar: 'https://api.dicebear.com/7.x/avataaars/svg?seed=2'
},
{
id: 3,
name: '王五',
email: 'wangwu@example.com',
age: 28,
status: 'active',
avatar: 'https://api.dicebear.com/7.x/avataaars/svg?seed=3'
},
{
id: 4,
name: '赵六',
email: 'zhaoliu@example.com',
age: 32,
status: 'active',
avatar: 'https://api.dicebear.com/7.x/avataaars/svg?seed=4'
},
{
id: 5,
name: '钱七',
email: 'qianqi@example.com',
age: 27,
status: 'inactive',
avatar: 'https://api.dicebear.com/7.x/avataaars/svg?seed=5'
}
]
</script>
<style scoped>
.hk-data-grid {
border: 1px solid #e8e8e8;
border-radius: 4px;
}
</style>工具栏
显示工具栏,提供额外的操作功能。
<template>
<div class="demo-container">
<MDataGrid
:columns="columns"
:data-source="dataSource"
height="400px"
:toolbar="{
showQuickFilter: true,
showReset: true,
showColumnToggle: true,
placement: 'top'
}"
/>
</div>
</template>
<script setup lang="ts">
import { MDataGrid } from 'moonwind-ui'
import type { DataGridColumn, ToolbarConfig } from 'moonwind-ui'
interface User {
id: number
name: string
email: string
age: number
department: string
status: string
salary: number
}
const columns: DataGridColumn[] = [
{ field: 'id', headerName: 'ID', width: 80, sortable: true },
{ field: 'name', headerName: '姓名', width: 120, sortable: true },
{ field: 'email', headerName: '邮箱', width: 200 },
{ field: 'age', headerName: '年龄', width: 80, sortable: true },
{ field: 'department', headerName: '部门', width: 120, filter: true },
{ field: 'status', headerName: '状态', width: 100, filter: true },
{ field: 'salary', headerName: '薪资', width: 120, sortable: true }
]
const dataSource: User[] = [
{ id: 1, name: '张三', email: 'zhangsan@example.com', age: 28, department: '技术部', status: '在职', salary: 15000 },
{ id: 2, name: '李四', email: 'lisi@example.com', age: 32, department: '产品部', status: '在职', salary: 18000 },
{ id: 3, name: '王五', email: 'wangwu@example.com', age: 25, department: '设计部', status: '在职', salary: 12000 },
{ id: 4, name: '赵六', email: 'zhaoliu@example.com', age: 30, department: '市场部', status: '离职', salary: 14000 },
{ id: 5, name: '钱七', email: 'qianqi@example.com', age: 27, department: '技术部', status: '在职', salary: 16000 },
{ id: 6, name: '孙八', email: 'sunba@example.com', age: 35, department: '人事部', status: '在职', salary: 13000 },
{ id: 7, name: '周九', email: 'zhoujiu@example.com', age: 29, department: '财务部', status: '在职', salary: 17000 },
{ id: 8, name: '吴十', email: 'wushi@example.com', age: 26, department: '技术部', status: '试用期', salary: 11000 },
{ id: 9, name: '郑十一', email: 'zheng11@example.com', age: 31, department: '产品部', status: '在职', salary: 19000 },
{ id: 10, name: '王十二', email: 'wang12@example.com', age: 24, department: '设计部', status: '试用期', salary: 10000 }
]
</script>
<style scoped>
.demo-container {
margin: 20px 0;
border: 1px solid #e1e5e9;
border-radius: 6px;
padding: 16px;
background: #fff;
}
.hk-data-grid {
border: 1px solid #e8e8e8;
border-radius: 4px;
}
</style>行选择
支持行选择功能。
<template>
<div class="demo-container">
<div class="selection-info">
<p>已选择 {{ selectedKeys.length }} 行数</p>
<div v-if="selectedKeys.length > 0" class="selected-items">
<strong>选中的用户:</strong>
<span v-for="(key, index) in selectedKeys" :key="key">
{{ getSelectedUserName(key) }}{{ index < selectedKeys.length - 1 ? ', ' : '' }}
</span>
</div>
</div>
<MDataGrid
:columns="columns"
:data-source="dataSource"
:row-selection="rowSelection"
:toolbar="{ visible: true, showColumnToggle: true, showReset: true }"
height="400px"
/>
</div>
</template>
<script setup lang="ts">
import { ref } from 'vue'
import { MDataGrid } from 'moonwind-ui'
import type { DataGridColumn, RowSelectionConfig } from 'moonwind-ui'
interface User {
id: number
name: string
email: string
age: number
department: string
status: string
}
const columns: DataGridColumn<User>[] = [
{ field: 'id', headerName: 'ID', width: 80 },
{ field: 'name', headerName: '姓名', width: 120 },
{ field: 'email', headerName: '邮箱', width: 200 },
{ field: 'age', headerName: '年龄', width: 80 },
{ field: 'department', headerName: '部门', width: 120 },
{ field: 'status', headerName: '状态', width: 100 }
]
const dataSource: User[] = [
{ id: 1, name: '张三', email: 'zhangsan@example.com', age: 28, department: '技术部', status: '在职' },
{ id: 2, name: '李四', email: 'lisi@example.com', age: 32, department: '产品部', status: '在职' },
{ id: 3, name: '王五', email: 'wangwu@example.com', age: 25, department: '设计部', status: '在职' },
{ id: 4, name: '赵六', email: 'zhaoliu@example.com', age: 30, department: '市场部', status: '离职' },
{ id: 5, name: '钱七', email: 'qianqi@example.com', age: 27, department: '技术部', status: '在职' },
{ id: 6, name: '孙八', email: 'sunba@example.com', age: 35, department: '人事部', status: '在职' },
{ id: 7, name: '周九', email: 'zhoujiu@example.com', age: 29, department: '财务部', status: '在职' },
{ id: 8, name: '吴十', email: 'wushi@example.com', age: 26, department: '技术部', status: '在职' }
]
const selectedKeys = ref<number[]>([])
const rowSelection: RowSelectionConfig<User> = {
type: 'checkbox',
selectedKeys: selectedKeys.value,
onChange: (keys: number[], rows: User[]) => {
selectedKeys.value = keys
console.log('选中的行:', rows)
}
}
const getSelectedUserName = (id: number): string => {
const user = dataSource.find(u => u.id === id)
return user ? user.name : ''
}
</script>
<style scoped>
.demo-container {
margin: 20px 0;
border: 1px solid #e1e5e9;
border-radius: 6px;
padding: 20px;
}
.selection-info {
margin-bottom: 16px;
padding: 12px;
background-color: #f6f8fa;
border-radius: 4px;
border: 1px solid #e1e5e9;
}
.selection-info p {
margin: 0 0 8px 0;
font-weight: 500;
color: #24292f;
}
.selected-items {
color: #656d76;
font-size: 14px;
}
.selected-items strong {
color: #24292f;
}
</style>远程数据
通过 fetch 属性配置远程数据获取。
<template>
<MDataGrid
:columns="columns"
:fetch="fetchData"
:pagination="pagination"
height="500px"
/>
</template>
<script setup lang="ts">
import { MDataGrid } from 'moonwind-ui'
import type { DataGridColumn } from 'moonwind-ui'
interface User {
id: number
name: string
email: string
age: number
department: string
}
const columns: DataGridColumn[] = [
{ field: 'id', headerName: 'ID', width: 80 },
{ field: 'name', headerName: '姓名', width: 120 },
{ field: 'email', headerName: '邮箱', width: 200 },
{ field: 'age', headerName: '年龄', width: 80 },
{ field: 'department', headerName: '部门', width: 120 }
]
const pagination = {
current: 1,
pageSize: 10,
total: 0,
showSizeChanger: true,
showQuickJumper: true,
showTotal: true
}
const fetchData = async (params: any) => {
// 模拟 API 请求
await new Promise(resolve => setTimeout(resolve, 1000))
const { current = 1, pageSize = 10 } = params
const total = 100
const start = (current - 1) * pageSize
const data: User[] = Array.from({ length: pageSize }, (_, index) => ({
id: start + index + 1,
name: `用户${start + index + 1}`,
email: `user${start + index + 1}@example.com`,
age: 20 + (start + index) % 40,
department: ['技术部', '产品部', '设计部', '运营部'][index % 4]
}))
return {
data,
total
}
}
</script>
<style scoped>
.hk-data-grid {
border: 1px solid #e8e8e8;
border-radius: 4px;
}
</style>API
Props
| 属性名 | 说明 | 类型 | 默认值 |
|---|---|---|---|
| columns | 列配置 | DataGridColumn[] | [] |
| dataSource | 数据源 | any[] | [] |
| fetch | 远程数据获取函数 | Function | |
| pagination | 分页配置 | PaginationConfig | |
| rowSelection | 行选择配置 | RowSelectionConfig | |
| toolbar | 工具栏配置 | ToolbarConfig | |
| loading | 加载状态 | boolean | false |
| height | 表格高度 | string / number |
Events
| 事件名 | 说明 | 回调参数 |
|---|---|---|
| row-click | 行点击事件 | (row: any) |
| selection-change | 选择项发生变化时触发 | (selection: any[]) |
| page-change | 页码改变时触发 | (page: number) |
| page-size-change | 每页条数改变时触发 | (pageSize: number) |
Methods
| 方法名 | 说明 | 参数 |
|---|---|---|
| refresh | 刷新表格数据 | |
| clearSelection | 清空选择 | |
| getSelectedRows | 获取选中的行数据 |
DataGridColumn
| 属性名 | 说明 | 类型 | 默认值 |
|---|---|---|---|
| field | 列字段名 | string | |
| headerName | 列标题 | string | |
| width | 列宽度 | number | |
| sortable | 是否可排序 | boolean | false |
| filter | 是否可筛选 | boolean | false |
| hide | 是否隐藏 | boolean | false |