Crud 增删改查
z-crud
组件表格部分功能介绍。表格部分功能用法基本等同于z-table
。
表格使用
在z-table
上封装,表格属性直接传递即可。
<!-- eslint-disable no-console -->
<script lang="ts" setup>
import { ref } from 'vue'
interface RowData {
id: number
name: string
gender: string
age: number
time: string
}
const columns = ref([
{
type: 'selection',
reserveSelection: true,
},
{
label: '姓名',
prop: 'name',
},
{
prop: 'gender',
label: '性别',
},
{
prop: 'age',
label: '年龄',
},
{
prop: 'time',
label: '出生日期',
},
])
const request = ref({
searchApi: getTableData,
})
const tableData = ref([])
const pagination = ref({
page: 1,
pageSize: 2,
total: 0,
})
const loading = ref(false)
const selectionData = ref<RowData[]>([])
function getTableData(params: any) {
console.log(params, 'getTableData params')
return new Promise((resolve) => {
setTimeout(() => {
const data = [
{
id: 1,
name: 'Steven',
gender: 'male',
age: 22,
time: '2020-01-01',
},
{
id: 2,
name: 'Helen',
gender: 'male',
age: 12,
time: '2012-01-01',
},
{
id: 3,
name: 'Nancy',
gender: 'female',
age: 18,
time: '2018-01-01',
},
{
id: 4,
name: 'Jack',
gender: 'male',
age: 28,
time: '2028-01-01',
},
]
resolve({
data: {
page: 1,
pageSize: 2,
total: 4,
list: data.slice((pagination.value.page - 1) * pagination.value.pageSize, pagination.value.page * pagination.value.pageSize),
},
})
}, 100)
})
}
</script>
<template>
<z-crud
v-model:data="tableData"
v-model:pagination="pagination"
v-model:loading="loading"
v-model:selectionData="selectionData"
:columns="columns"
:request="request"
:action="false"
row-key="id"
stripe
/>
</template>
表格标题
配置title
属性生成表格标题,支持字符串和函数类型,也可使用tableTitle
插槽自定义。
<script lang="ts" setup>
import { ref } from 'vue'
const columns = ref([
{
label: '姓名',
prop: 'name',
},
{
prop: 'gender',
label: '性别',
},
{
prop: 'age',
label: '年龄',
},
{
prop: 'time',
label: '出生日期',
},
])
const request = ref({
searchApi: getTableData,
})
const tableData = ref([])
const pagination = ref({
page: 1,
pageSize: 2,
total: 0,
})
const loading = ref(false)
function getTableData() {
return new Promise((resolve) => {
setTimeout(() => {
const data = [
{
id: 1,
name: 'Steven',
gender: 'male',
age: 22,
time: '2020-01-01',
},
{
id: 2,
name: 'Helen',
gender: 'male',
age: 12,
time: '2012-01-01',
},
{
id: 3,
name: 'Nancy',
gender: 'female',
age: 18,
time: '2018-01-01',
},
{
id: 4,
name: 'Jack',
gender: 'male',
age: 28,
time: '2028-01-01',
},
]
resolve({
data: {
page: 1,
pageSize: 2,
total: 4,
list: data.slice((pagination.value.page - 1) * pagination.value.pageSize, pagination.value.page * pagination.value.pageSize),
},
})
}, 100)
})
}
</script>
<template>
<z-crud
v-model:data="tableData"
v-model:pagination="pagination"
v-model:loading="loading"
:columns="columns"
:request="request"
:action="false"
title="表格标题"
/>
</template>
操作项
操作项默认会拼接在columns
末尾,表格头为操作
,有查看
、编辑
、删除
三个操作。
操作内部具体配置请查看新增编辑配置、查看配置、删除配置等文档。
支持动态控制具体操作显隐。
<!-- eslint-disable no-console -->
<script lang="ts" setup>
import { ref } from 'vue'
import type { TableFormConfig } from 'ideaz-element'
interface RowData {
id: number
name: string
gender: string
age: number
time: string
}
interface GetTableDataRes { data: { page: number, pageSize: number, list: RowData[], total: number } }
const columns = ref([
{
label: '姓名',
prop: 'name',
},
{
prop: 'gender',
label: '性别',
},
{
prop: 'age',
label: '年龄',
},
{
prop: 'time',
label: '出生日期',
},
])
const request = ref({
searchApi: getTableData,
})
const tableData = ref<RowData[]>([])
const pagination = ref({
page: 1,
pageSize: 2,
total: 0,
})
const loading = ref(false)
const detailConfig = ref<TableFormConfig | boolean>(true)
const deleteConfig = ref<TableFormConfig | boolean>(true)
const editConfig = ref<TableFormConfig | boolean>(true)
function getTableData(params: any): Promise<GetTableDataRes> {
console.log(params, 'getTableData params')
return new Promise((resolve) => {
setTimeout(() => {
const data = [
{
id: 1,
name: 'Steven',
gender: 'male',
age: 22,
time: '2020-01-01',
},
{
id: 2,
name: 'Helen',
gender: 'male',
age: 12,
time: '2012-01-01',
},
{
id: 3,
name: 'Nancy',
gender: 'female',
age: 18,
time: '2018-01-01',
},
{
id: 4,
name: 'Jack',
gender: 'male',
age: 28,
time: '2028-01-01',
},
]
resolve({
data: {
page: 1,
pageSize: 2,
total: 4,
list: data.slice((pagination.value.page - 1) * pagination.value.pageSize, pagination.value.page * pagination.value.pageSize),
},
})
}, 100)
})
}
function handleChangeViewVisible() {
detailConfig.value = !detailConfig.value
}
function handleChangeDeleteVisible() {
deleteConfig.value = !deleteConfig.value
}
function handleChangeEditVisible() {
editConfig.value = !editConfig.value
}
</script>
<template>
<z-crud
v-model:data="tableData"
v-model:pagination="pagination"
v-model:loading="loading"
:columns="columns"
:request="request"
:detail="detailConfig"
:edit="editConfig"
:delete="deleteConfig"
>
<template #toolBarLeft>
<el-button type="primary" size="small" @click="handleChangeViewVisible">
查看按钮显隐
</el-button>
<el-button type="primary" size="small" @click="handleChangeDeleteVisible">
删除按钮显隐
</el-button>
<el-button type="primary" size="small" @click="handleChangeEditVisible">
编辑按钮显隐
</el-button>
</template>
</z-crud>
</template>
操作项自定义
配置action
为false
关闭默认的操作项,自定义表格操作。
操作按钮也支持动态属性,如:disabled
等。传入一个方法,参数为当前行相关数据。
<!-- eslint-disable unused-imports/no-unused-vars -->
<!-- eslint-disable no-console -->
<script lang="ts" setup>
import { ref } from 'vue'
import type { TableColumnScopeData } from 'ideaz-element'
interface RowData {
id: number
name: string
gender: string
age: number
time: string
}
const columns = ref([
{
label: '姓名',
prop: 'name',
},
{
prop: 'gender',
label: '性别',
},
{
prop: 'age',
label: '年龄',
},
{
prop: 'time',
label: '出生日期',
},
{
type: 'button',
label: '操作',
buttons: [
{
label: '查看',
link: true,
type: 'primary',
disabled: ({ row, column, $index }: TableColumnScopeData<RowData>) => row.name === 'Steven',
onClick: ({ row }: TableColumnScopeData<RowData>) => console.log(row, 'row'),
},
{
label: '删除',
link: true,
type: 'danger',
disabled: ({ row, column, $index }: TableColumnScopeData<RowData>) => row.age === 18,
onClick: ({ row }: TableColumnScopeData<RowData>) => console.log(row, 'row'),
},
],
},
])
const request = ref({
searchApi: getTableData,
})
const tableData = ref([])
const pagination = ref({
page: 1,
pageSize: 2,
total: 0,
})
const loading = ref(false)
function getTableData(params: any) {
console.log(params, 'getTableData params')
return new Promise((resolve) => {
setTimeout(() => {
const data = [
{
id: 1,
name: 'Steven',
gender: 'male',
age: 22,
time: '2020-01-01',
},
{
id: 2,
name: 'Helen',
gender: 'male',
age: 12,
time: '2012-01-01',
},
{
id: 3,
name: 'Nancy',
gender: 'female',
age: 18,
time: '2018-01-01',
},
{
id: 4,
name: 'Jack',
gender: 'male',
age: 28,
time: '2028-01-01',
},
]
resolve({
data: {
page: 1,
pageSize: 2,
total: 4,
list: data.slice((pagination.value.page - 1) * pagination.value.pageSize, pagination.value.page * pagination.value.pageSize),
},
})
}, 100)
})
}
</script>
<template>
<z-crud
v-model:data="tableData"
v-model:pagination="pagination"
v-model:loading="loading"
:columns="columns"
:request="request"
:action="false"
/>
</template>
操作项下拉
其他具体配置可参考
z-table
组件
在buttons
数组中配置type
为dropdown
,children
中配置下拉选项
<!-- eslint-disable no-console -->
<script lang="ts" setup>
import { ref } from 'vue'
import type { TableColumnScopeData } from 'ideaz-element'
interface RowData {
id: number
name: string
gender: string
age: number
time: string
}
const columns = ref([
{
label: '姓名',
prop: 'name',
},
{
prop: 'gender',
label: '性别',
},
{
prop: 'age',
label: '年龄',
},
{
prop: 'time',
label: '出生日期',
},
{
type: 'button',
label: '操作',
width: '200px',
buttons: [
{
type: 'primary',
link: true,
label: '编辑',
onClick: ({ row }: TableColumnScopeData<RowData>) => {
console.log(row, 'edit')
},
},
{
type: 'danger',
link: true,
label: '删除',
onClick: ({ row }: TableColumnScopeData<RowData>) => {
console.log(row, 'delete')
},
},
{
type: 'dropdown',
reference: '其他',
children: [
{
type: 'primary',
link: true,
label: '复制',
onClick: ({ row }: TableColumnScopeData<RowData>) => {
console.log(row, 'copy')
},
},
{
type: 'danger',
link: true,
label: '操作',
onClick: ({ row }: TableColumnScopeData<RowData>) => {
console.log(row, 'operate')
},
},
],
},
],
},
])
const request = ref({
searchApi: getTableData,
})
const tableData = ref([])
const pagination = ref({
page: 1,
pageSize: 2,
total: 0,
})
const loading = ref(false)
function getTableData(params: any) {
console.log(params, 'getTableData params')
return new Promise((resolve) => {
setTimeout(() => {
const data = [
{
id: 1,
name: 'Steven',
gender: 'male',
age: 22,
time: '2020-01-01',
},
{
id: 2,
name: 'Helen',
gender: 'male',
age: 12,
time: '2012-01-01',
},
{
id: 3,
name: 'Nancy',
gender: 'female',
age: 18,
time: '2018-01-01',
},
{
id: 4,
name: 'Jack',
gender: 'male',
age: 28,
time: '2028-01-01',
},
]
resolve({
data: {
page: 1,
pageSize: 2,
total: 4,
list: data.slice((pagination.value.page - 1) * pagination.value.pageSize, pagination.value.page * pagination.value.pageSize),
},
})
}, 100)
})
}
</script>
<template>
<z-crud
v-model:data="tableData"
v-model:pagination="pagination"
v-model:loading="loading"
:columns="columns"
:request="request"
:action="false"
/>
</template>
分页
配置pagination
,支持双向绑定,实现分页效果。
pageSize
为0
、pagination
为false
或pagination
不传,分页不展示。
<!-- eslint-disable no-console -->
<script lang="ts" setup>
import { ref } from 'vue'
import type { TableColumnScopeData } from 'ideaz-element'
interface RowData {
id: number
name: string
gender: string
age: number
time: string
}
const columns = ref([
{
label: '姓名',
prop: 'name',
},
{
prop: 'gender',
label: '性别',
},
{
prop: 'age',
label: '年龄',
},
{
prop: 'time',
label: '出生日期',
},
{
type: 'button',
label: '操作',
width: '200px',
buttons: [
{
type: 'primary',
link: true,
label: '编辑',
onClick: ({ row }: TableColumnScopeData<RowData>) => {
console.log(row, 'edit')
},
},
{
type: 'danger',
link: true,
label: '删除',
onClick: ({ row }: TableColumnScopeData<RowData>) => {
console.log(row, 'delete')
},
},
{
type: 'dropdown',
reference: '其他',
children: [
{
type: 'primary',
link: true,
label: '复制',
onClick: ({ row }: TableColumnScopeData<RowData>) => {
console.log(row, 'copy')
},
},
{
type: 'danger',
link: true,
label: '操作',
onClick: ({ row }: TableColumnScopeData<RowData>) => {
console.log(row, 'operate')
},
},
],
},
],
},
])
const request = ref({
searchApi: getTableData,
})
const tableData = ref([])
const pagination = ref({
page: 1,
pageSize: 2,
total: 0,
})
const loading = ref(false)
function getTableData(params: any) {
console.log(params, 'getTableData params')
return new Promise((resolve) => {
setTimeout(() => {
const data = [
{
id: 1,
name: 'Steven',
gender: 'male',
age: 22,
time: '2020-01-01',
},
{
id: 2,
name: 'Helen',
gender: 'male',
age: 12,
time: '2012-01-01',
},
{
id: 3,
name: 'Nancy',
gender: 'female',
age: 18,
time: '2018-01-01',
},
{
id: 4,
name: 'Jack',
gender: 'male',
age: 28,
time: '2028-01-01',
},
]
resolve({
data: {
page: 1,
pageSize: 2,
total: 4,
list: data.slice((pagination.value.page - 1) * pagination.value.pageSize, pagination.value.page * pagination.value.pageSize),
},
})
}, 100)
})
}
</script>
<template>
<z-crud
v-model:data="tableData"
v-model:pagination="pagination"
v-model:loading="loading"
:columns="columns"
:request="request"
:action="false"
/>
</template>
前端分页
配置pagination
的type
为front
,开启前端分页功能。
<!-- eslint-disable no-console -->
<script lang="ts" setup>
import { ref } from 'vue'
interface RowData {
name: string
gender: string
age: number
time: string
}
interface GetTableDataRes { result: { page: number, pageSize: number, list: RowData[], total: number } }
const loading = ref(false)
const tableData = ref<RowData[]>([])
const totalData = ref<RowData[]>([])
const pagination = ref({
type: 'front',
page: 1,
pageSize: 2,
total: 0,
layout: 'total, sizes, prev, pager, next, jumper',
})
const columns = ref([
{
prop: 'name',
label: '姓名',
},
{
prop: 'gender',
label: '性别',
},
{
prop: 'age',
label: '年龄',
},
{
prop: 'time',
label: '出生日期',
},
])
function mockApi(params: any): Promise<GetTableDataRes> {
console.log(params, 'params')
return new Promise((resolve) => {
setTimeout(() => {
const data = [
{
name: 'Steven',
gender: 'male',
age: 22,
time: '2020-01-01',
},
{
name: 'Helen',
gender: 'male',
age: 12,
time: '2012-01-01',
},
{
name: 'Nancy',
gender: 'female',
age: 18,
time: '2018-01-01',
},
{
name: 'Jack',
gender: 'male',
age: 28,
time: '2028-01-01',
},
]
resolve({
result: {
page: 1,
pageSize: 10,
total: 4,
list: data,
},
})
}, 100)
})
}
async function getTableData() {
loading.value = true
try {
const res = await mockApi({ ...pagination.value })
totalData.value = res.result.list
pagination.value.total = res.result.total
}
catch (error) {
console.log(error)
}
loading.value = false
}
getTableData()
</script>
<template>
{{ tableData }}
<z-crud
v-model:pagination="pagination"
v-model:data="tableData"
v-model:loading="loading"
:total-data="totalData"
:columns="columns"
:action="false"
@refresh="getTableData"
/>
</template>
列显隐
column
中配置hide
字段,支持函数或布尔值。
<script lang="ts" setup>
import { ref } from 'vue'
const isHide = ref(false)
const tableData = ref([
{
name: 'Steven',
gender: 'male',
age: 22,
time: '2020-01-01',
},
{
name: 'Helen',
gender: 'male',
age: 12,
time: '2012-01-01',
},
{
name: 'Nancy',
gender: 'female',
age: 18,
time: '2018-01-01',
},
{
name: 'Jack',
gender: 'male',
age: 28,
time: '2028-01-01',
},
])
const columns = ref([
{
prop: 'name',
label: '姓名',
hide: () => isHide.value,
},
{
prop: 'gender',
label: '性别',
hide: true,
},
{
prop: 'age',
label: '年龄',
},
{
prop: 'time',
label: '出生日期',
},
])
function changeVisible() {
isHide.value = !isHide.value
}
</script>
<template>
<el-button @click="changeVisible">
点击修改列显隐
</el-button>
<z-crud
v-model:data="tableData"
:columns="columns"
:action="false"
/>
</template>
自定义列
配置column
项的slot
或render
,可以自定义列内容。
<!-- eslint-disable no-console -->
<script lang="ts" setup>
import { h, ref } from 'vue'
import type { TableColumnScopeData } from 'ideaz-element'
interface RowData {
id: number
name: string
gender: string
age: number
time: string
}
const columns = ref([
{
label: '姓名',
slot: 'name',
form: {
component: 'input',
label: '姓名',
field: 'name',
},
},
{
slot: 'gender',
label: '性别',
form: {
component: 'select',
label: '性别',
field: 'gender',
},
},
{
render: ({ row }: TableColumnScopeData<RowData>) => h('span', row.age),
label: '年龄',
form: {
component: 'input',
label: '年龄',
field: 'age',
},
},
{
prop: 'time',
label: '出生日期',
},
])
const request = ref({
searchApi: getTableData,
deleteApi: commonApi,
submitApi: commonApi,
})
const tableData = ref([])
const pagination = ref({
page: 1,
pageSize: 2,
total: 0,
})
const loading = ref(false)
const formData = ref({})
const options = {
gender: [{ label: 'male', value: 'male' }, { label: 'female', value: 'female' }],
}
function getTableData(params: any) {
console.log(params, 'getTableData params')
return new Promise((resolve) => {
setTimeout(() => {
const data = [
{
id: 1,
name: 'Steven',
gender: 'male',
age: 22,
time: '2020-01-01',
},
{
id: 2,
name: 'Helen',
gender: 'male',
age: 12,
time: '2012-01-01',
},
{
id: 3,
name: 'Nancy',
gender: 'female',
age: 18,
time: '2018-01-01',
},
{
id: 4,
name: 'Jack',
gender: 'male',
age: 28,
time: '2028-01-01',
},
]
resolve({
data: {
page: 1,
pageSize: 2,
total: 4,
list: data.slice((pagination.value.page - 1) * pagination.value.pageSize, pagination.value.page * pagination.value.pageSize),
},
})
}, 100)
})
}
function commonApi(params: any) {
console.log(params, 'commonApi params')
return new Promise((resolve) => {
setTimeout(() => {
resolve({
msg: 'success',
code: 200,
})
}, 100)
})
}
</script>
<template>
<z-crud
v-model:formData="formData"
v-model:data="tableData"
v-model:pagination="pagination"
v-model:loading="loading"
:options="options"
:columns="columns"
:request="request"
>
<template #name>
sdf
</template>
<template #gender>
asdf
</template>
</z-crud>
</template>
列提示
column
中配置tooltip
实现表头提示功能,支持函数和字符串。
<script lang="ts" setup>
import { h, ref } from 'vue'
const tableData = ref([
{
name: 'Steven',
gender: 'male',
age: 22,
time: '2020-01-01',
},
{
name: 'Helen',
gender: 'male',
age: 12,
time: '2012-01-01',
},
{
name: 'Nancy',
gender: 'female',
age: 18,
time: '2018-01-01',
},
{
name: 'Jack',
gender: 'male',
age: 28,
time: '2028-01-01',
},
])
const columns = ref([
{
prop: 'name',
label: '姓名',
tooltip: () => h('span', '姓名提示'),
},
{
prop: 'gender',
label: '性别',
tooltip: '性别提示',
},
{
prop: 'age',
label: '年龄',
},
{
prop: 'time',
label: '出生日期',
},
])
</script>
<template>
<z-crud
v-model:data="tableData"
:columns="columns"
:action="false"
/>
</template>
列类型
column
中配置type
实现表格列类型,支持expand
、radio
、selection
、input
、select
。
TIP
type
为sort
、type
为radio
或者需要跨页选中checkbox
时,需要配合rowKey
使用(默认id
)。
<script lang="ts" setup>
import { ref } from 'vue'
const tableData = ref([
{
id: 1,
name: 'Steven',
gender: '1',
age: 22,
time: '2020-01-01',
},
{
id: 2,
name: 'Helen',
gender: '1',
age: 12,
time: '2012-01-01',
},
{
id: 3,
name: 'Nancy',
gender: '2',
age: 18,
time: '2018-01-01',
},
{
id: 4,
name: 'Jack',
gender: '1',
age: 28,
time: '2028-01-01',
},
])
const columns = ref([
{
type: 'sort',
},
{
type: 'expand',
},
{
type: 'index',
},
{
type: 'radio',
},
{
type: 'selection',
reserveSelection: true,
},
{
component: 'input',
prop: 'name',
label: '姓名',
},
{
component: 'select',
prop: 'gender',
label: '性别',
},
{
prop: 'age',
label: '年龄',
},
{
prop: 'time',
label: '出生日期',
},
])
const options = {
gender: [
{ label: '男', value: '1' },
{ label: '女', value: '2' },
],
}
</script>
<template>
<z-crud
v-model:data="tableData"
:columns="columns"
:options="options"
:action="false"
row-key="id"
>
<template #expand>
<span>展开内容</span>
</template>
</z-crud>
</template>
表格头自定义
column
中将label
配置为带slot
或Slot
的字符串或配置为render
函数实现自定义列表头。
<script lang="ts" setup>
import { h, ref } from 'vue'
const tableData = ref([
{
name: 'Steven',
gender: 'male',
age: 22,
time: '2020-01-01',
},
{
name: 'Helen',
gender: 'male',
age: 12,
time: '2012-01-01',
},
{
name: 'Nancy',
gender: 'female',
age: 18,
time: '2018-01-01',
},
{
name: 'Jack',
gender: 'male',
age: 28,
time: '2028-01-01',
},
])
const columns = ref([
{
prop: 'name',
label: () => h('span', '自定义表头'),
},
{
prop: 'gender',
label: 'genderHeaderSlot',
},
{
prop: 'age',
label: '年龄',
},
{
prop: 'time',
label: '出生日期',
},
])
</script>
<template>
<z-crud
v-model:data="tableData"
:columns="columns"
:action="false"
>
<template #genderHeaderSlot="scope">
<span>性别自定义表头{{ scope.$index }}</span>
</template>
</z-crud>
</template>
可编辑表格
详细文档请查看
z-table
可编辑表格内容。
editable
设置为true
,开启表格编辑模式,该字段支持布尔值或对象类型,可编辑表格type
默认为single
。
<!-- eslint-disable no-console -->
<script lang="ts" setup>
import { ref } from 'vue'
const tableData = ref([
{
name: 'Steven',
gender: '1',
age: 22,
time: '2020-01-01',
},
{
name: 'Helen',
gender: '1',
age: 12,
time: '2012-01-01',
},
{
name: 'Nancy',
gender: '2',
age: 18,
time: '2018-01-01',
},
{
name: 'Jack',
gender: '1',
age: 28,
time: '2028-01-01',
},
])
const columns = ref([
{
component: 'input',
prop: 'name',
label: '姓名',
},
{
component: 'select',
prop: 'gender',
label: '性别',
},
{
component: 'input',
prop: 'age',
label: '年龄',
},
{
component: 'el-date-picker',
prop: 'time',
label: '出生日期',
fieldProps: {
valueFormat: 'YYYY-MM-DD',
},
},
])
const options = {
gender: [
{ label: '男', value: '1' },
{ label: '女', value: '2' },
],
}
function handleClick() {
console.log(tableData.value, 'handleClick')
}
</script>
<template>
<el-button @click="handleClick">
click
</el-button>
<z-crud
v-model:data="tableData"
:columns="columns"
:options="options"
:editable="true"
:action="false"
/>
</template>
吸顶
通过配置sticky
属性的top
、parent(会出现滚动条的DOM元素)
和zIndex
实现吸顶功能。 top
默认为50px
,zIndex
默认为100
。
<!-- eslint-disable no-console -->
<script lang="ts" setup>
import { ref } from 'vue'
interface RowData {
id: number
name: string
gender: string
age: number
time: string
}
const searchFormData = ref({
name: '',
})
const columns = ref([
{
type: 'selection',
reserveSelection: true,
},
{
label: '姓名',
prop: 'name',
search: {
component: 'el-input',
},
},
{
prop: 'gender',
label: '性别',
},
{
prop: 'age',
label: '年龄',
},
{
prop: 'time',
label: '出生日期',
},
])
const request = ref({
searchApi: getTableData,
})
const tableData = ref([])
const pagination = ref({
page: 1,
pageSize: 2,
total: 0,
})
const loading = ref(false)
const selectionData = ref<RowData[]>([])
function getTableData(params: any) {
console.log(params, 'getTableData params')
return new Promise((resolve) => {
setTimeout(() => {
const data = [
{
id: 1,
name: 'Steven',
gender: 'male',
age: 22,
time: '2020-01-01',
},
{
id: 2,
name: 'Helen',
gender: 'male',
age: 12,
time: '2012-01-01',
},
{
id: 3,
name: 'Nancy',
gender: 'female',
age: 18,
time: '2018-01-01',
},
{
id: 4,
name: 'Jack',
gender: 'male',
age: 28,
time: '2028-01-01',
},
]
resolve({
data: {
page: 1,
pageSize: 2,
total: 4,
list: data.slice((pagination.value.page - 1) * pagination.value.pageSize, pagination.value.page * pagination.value.pageSize),
},
})
}, 100)
})
}
</script>
<template>
<z-crud
v-model:data="tableData"
v-model:pagination="pagination"
v-model:loading="loading"
v-model:selectionData="selectionData"
v-model:formData="searchFormData"
:columns="columns"
:request="request"
:action="false"
:sticky="{ parent: 'document' }"
row-key="id"
stripe
/>
</template>
水印
配置watermark
,支持字符串和对象类型,对象类型可配置属性请参考el-watermark
配置。
<script lang="ts" setup>
import { ref } from 'vue'
const tableData = ref([
{
name: 'Steven',
gender: '1',
age: 22,
time: '2020-01-01',
},
{
name: 'Helen',
gender: '1',
age: 12,
time: '2012-01-01',
},
{
name: 'Nancy',
gender: '2',
age: 18,
time: '2018-01-01',
},
{
name: 'Jack',
gender: '1',
age: 28,
time: '2028-01-01',
},
])
const formData = ref({})
const columns = ref([
{
prop: 'name',
label: '姓名',
form: {
component: 'input',
field: 'name',
},
},
{
prop: 'gender',
label: '性别',
},
{
prop: 'age',
label: '年龄',
},
{
prop: 'time',
label: '出生日期',
},
])
const options = {
gender: [
{ label: '男', value: '1' },
{ label: '女', value: '2' },
],
}
</script>
<template>
<z-crud
v-model:data="tableData"
v-model:formData="formData"
:columns="columns"
:options="options"
:action="false"
watermark="watermark"
/>
</template>
表格方法
z-crud
的表格方法按照el-table
使用即可。
<!-- eslint-disable no-console -->
<script lang="ts" setup>
import { ref } from 'vue'
interface RowData {
id: number
name: string
gender: string
age: number
time: string
}
const zTableRef = ref()
const radioData = ref({})
const selectionData = ref<RowData[]>([])
const tableData = ref([
{
id: 1,
name: 'Steven',
gender: 'male',
age: 22,
time: '2020-01-01',
},
{
id: 2,
name: 'Helen',
gender: 'male',
age: 12,
time: '2012-01-01',
},
{
id: 3,
name: 'Nancy',
gender: 'female',
age: 18,
time: '2018-01-01',
},
{
id: 4,
name: 'Jack',
gender: 'male',
age: 28,
time: '2028-01-01',
},
])
const columns = ref([
{
type: 'radio',
},
{
type: 'selection',
},
{
prop: 'name',
label: '姓名',
},
{
prop: 'gender',
label: '性别',
},
{
prop: 'age',
label: '年龄',
},
{
prop: 'time',
label: '出生日期',
},
])
function handleRadioChange(row: RowData) {
radioData.value = row
console.log(row, 'radio data')
}
function handleSelectionChange(selection: RowData[]) {
selectionData.value = selection
console.log(selection, 'selection data')
}
function handleClear() {
zTableRef.value.clearSelection()
}
</script>
<template>
<el-button @click="handleClear">
清空选中
</el-button>
<z-crud
ref="zTableRef"
:data="tableData"
:columns="columns"
:action="false"
@radio-change="handleRadioChange"
@selection-change="handleSelectionChange"
/>
</template>
z-crud表格属性
属性名 | 说明 | 类型 | 可选值 | 默认值 |
---|---|---|---|---|
modelValue:data | 显示的数据,支持双向绑定 | array | — | — |
modelValue:formData | 查询表单数据,支持双向绑定 | array | — | — |
modelValue:pagination | 分页配置,支持双向绑定 | object | — | — |
modelValue:loading | 表格加载,支持双向绑定 | boolean | — | — |
modelValue:selection | checkbox选中数据,支持双向绑定 | array | — | — |
columns | 表格配置项 | array | — | — |
toolBar | 工具栏配置 | object / boolean | — | — |
editable | 可编辑表格配置 | object / boolean | — | — |
options | 表格内部选项数据源 | object | — | — |
title | 表格标题 | string / function | — | — |
totalData | 表格所有数据(前端分页生效) | array | — | — |
name | 表格key ,配置name 默认开启缓存 | string | — | — |
paginationStorage | 分页数据缓存 | boolean | — | false |
formStorage | 查询表单数据缓存 | boolean | — | false |
formDecorator | 表单背景 | object | — | { name: 'el-card' } |
tableDecorator | 表格背景 | object | — | { name: 'el-card' } |
watermark | 水印配置 | object(具体配置可查看el-watermark 文档) | — | — |
height | Table 的高度, 默认为自动高度。 如果 height 为 number 类型,单位 px;如果 height 为 string 类型,则这个高度会设置为 Table 的 style.height 的值,Table 的高度会受控于外部样式。 | string / number | — | — |
max-height | Table 的最大高度。 合法的值为数字或者单位为 px 的高度。 | string / number | — | — |
stripe | 是否为斑马纹 table | boolean | — | false |
border | 是否带有纵向边框 | boolean | — | false |
size | Table 的尺寸 | string | large / default /small | — |
fit | 列的宽度是否自撑开 | boolean | — | true |
show-header | 是否显示表头 | boolean | — | true |
highlight-current-row | 是否要高亮当前行 | boolean | — | false |
current-row-key | 当前行的 key,只写属性 | string / number | — | — |
row-class-name | 行的 className 的回调方法,也可以使用字符串为所有行设置一个固定的 className。 | function({ row, rowIndex }) / string | — | — |
row-style | 行的 style 的回调方法,也可以使用一个固定的 Object 为所有行设置一样的 Style。 | function({ row, rowIndex }) / object | — | — |
cell-class-name | 单元格的 className 的回调方法,也可以使用字符串为所有单元格设置一个固定的 className。 | function({ row, column, rowIndex, columnIndex }) / string | — | — |
cell-style | 单元格的 style 的回调方法,也可以使用一个固定的 Object 为所有单元格设置一样的 Style。 | function({ row, column, rowIndex, columnIndex }) / object | — | — |
header-row-class-name | 表头行的 className 的回调方法,也可以使用字符串为所有表头行设置一个固定的 className。 | function({ row, rowIndex }) / string | — | — |
header-row-style | 表头行的 style 的回调方法,也可以使用一个固定的 Object 为所有表头行设置一样的 Style。 | function({ row, rowIndex }) / object | — | — |
header-cell-class-name | 表头单元格的 className 的回调方法,也可以使用字符串为所有表头单元格设置一个固定的 className。 | function({ row, column, rowIndex, columnIndex }) / string | — | — |
header-cell-style | 表头单元格的 style 的回调方法,也可以使用一个固定的 Object 为所有表头单元格设置一样的 Style。 | function({ row, column, rowIndex, columnIndex }) / object | — | — |
row-key | 行数据的 Key,用来优化 Table 的渲染; 在使用reserve-selection 功能与显示树形数据时,该属性是必填的。 类型为 String 时,支持多层访问:user.info.id ,但不支持 user.info[0].id ,此种情况请使用 Function 。 | function(row) / string | — | — |
empty-text | 空数据时显示的文本内容, 也可以通过 #empty 设置 | string | — | No Data |
default-expand-all | 是否默认展开所有行,当 Table 包含展开行存在或者为树形表格时有效 | boolean | — | false |
expand-row-keys | 可以通过该属性设置 Table 目前的展开行,需要设置 row-key 属性才能使用,该属性为展开行的 keys 数组。 | array | — | — |
default-sort | 默认的排序列的 prop 和顺序。 它的 prop 属性指定默认的排序的列,order 指定默认排序的顺序 | object | (order: 'ascending' 'descending') | 'descending') |
tooltip-effect | 溢出的 tooltip 的 effect | string | dark / light | dark |
tooltip-options | 溢出 tooltip 的选项,参见下述 tooltip 组件 | object | 请参考 tooltip | object |
show-summary | 是否在表尾显示合计行 | boolean | — | false |
sum-text | 显示摘要行第一列的文本 | string | — | Sum |
summary-method | 自定义的合计计算方法 | function({ columns, data }) | — | — |
span-method | 合并行或列的计算方法 | function({ row, column, rowIndex, columnIndex }) | — | — |
select-on-indeterminate | 在多选表格中,当仅有部分行被选中时,点击表头的多选框时的行为。 若为 true,则选中所有行;若为 false,则取消选择所有行 | boolean | — | true |
indent | 展示树形数据时,树节点的缩进 | number | — | 16 |
lazy | 是否懒加载子节点数据 | boolean | — | — |
load | 加载子节点数据的函数,lazy 为 true 时生效 | function(row, treeNode, resolve) | — | — |
tree-props | 渲染嵌套数据的配置选项 | object | — | { hasChildren: 'hasChildren', children: 'children' } |
table-layout | 设置表格单元、行和列的布局方式 | string | fixed / auto | fixed |
scrollbar-always-on | 总是显示滚动条 | boolean | — | false |
show-overflow-tooltip | 是否隐藏额外内容并在单元格悬停时使用 Tooltip 显示它们。这将影响全部列的展示。 | boolean \ | object | 参考 tooltip-options |
flexible | 确保主轴的最小尺寸,以便不超过内容 | boolean | — | false |
z-crud表格事件
事件名 | 说明 | 回调参数 |
---|---|---|
refresh | 翻页时触发的事件 | pagination |
radio-change | 当用户手动勾选数据行的 Radio 时触发的事件 | row |
select | 当用户手动勾选数据行的 Checkbox 时触发的事件 | selection, row |
select-all | 当用户手动勾选全选 Checkbox 时触发的事件 | selection |
selection-change | 当选择项发生变化时会触发该事件 | selection |
cell-mouse-enter | 当单元格 hover 进入时会触发该事件 | row, column, cell, event |
cell-mouse-leave | 当单元格 hover 退出时会触发该事件 | row, column, cell, event |
cell-click | 当某个单元格被点击时会触发该事件 | row, column, cell, event |
cell-dblclick | 当某个单元格被双击击时会触发该事件 | row, column, cell, event |
cell-contextmenu | 当某个单元格被鼠标右键点击时会触发该事件 | row, column, cell, event |
row-click | 当某一行被点击时会触发该事件 | row, column, event |
row-contextmenu | 当某一行被鼠标右键点击时会触发该事件 | row, column, event |
row-dblclick | 当某一行被双击时会触发该事件 | row, column, event |
header-click | 当某一列的表头被点击时会触发该事件 | column, event |
header-contextmenu | 当某一列的表头被鼠标右键点击时触发该事件 | column, event |
sort-change | 当表格的排序条件发生变化的时候会触发该事件 | { column, prop, order } |
filter-change | column 的 key, 如果需要使用 filter-change 事件,则需要此属性标识是哪个 column 的筛选条件 | filters |
current-change | 当表格的当前行发生变化的时候会触发该事件,如果要高亮当前行,请打开表格的 highlight-current-row 属性 | currentRow, oldCurrentRow |
header-dragend | 当拖动表头改变了列的宽度的时候会触发该事件 | newWidth, oldWidth, column, event |
expand-change | 当用户对某一行展开或者关闭的时候会触发该事件(展开行时,回调的第二个参数为 expandedRows;树形表格时第二参数为 expanded) | row, (expandedRows | expanded) |
z-crud表格方法
方法名 | 说明 | 参数 |
---|---|---|
getTableData | 获取表格数据方法 | — |
clearSelection | 用于多选表格或单选表格,清空用户的选择 | — |
getSelectionRows | 返回当前选中的行 | |
toggleRowSelection | 用于多选表格,切换某一行的选中状态, 如果使用了第二个参数,则可直接设置这一行选中与否 | row, selected |
toggleAllSelection | 用于多选表格,切换全选和全不选 | — |
toggleRowExpansion | 用于可扩展的表格或树表格,如果某行被扩展,则切换。 使用第二个参数,您可以直接设置该行应该被扩展或折叠。 | row, expanded |
setCurrentRow | 用于单选表格,设定某一行为选中行, 如果调用时不加参数,则会取消目前高亮行的选中状态。 | row |
clearSort | 用于清空排序条件,数据会恢复成未排序的状态 | — |
clearFilter | 传入由columnKey 组成的数组以清除指定列的过滤条件。 如果没有参数,清除所有过滤器 | columnKeys |
doLayout | 对 Table 进行重新布局。 当表格可见性变化时,您可能需要调用此方法以获得正确的布局 | — |
sort | 手动排序表格。 参数 prop 属性指定排序列,order 指定排序顺序。 | prop: string, order: string |
scrollTo | 滚动到一组特定坐标 | (options: ScrollToOptions | number, yCoord?: number) |
setScrollTop | 设置垂直滚动位置 | top |
setScrollLeft | 设置水平滚动位置 | left |
z-crud插槽
插槽名 | 说明 | 子标签 |
---|---|---|
append | 插入至表格最后一行之后的内容, 如果需要对表格的内容进行无限滚动操作,可能需要用到这个 slot。 若表格有合计行,该 slot 会位于合计行之上。 | — |
empty | 当数据为空时自定义的内容 | — |
tableTop | 顶部插槽 | — |
tableBottom | 底部插槽 | — |
toolBarTop | 工具栏顶部插槽 | — |
toolBarBottom | 工具栏底部插槽 | — |
toolBarRight | 工具栏右部插槽 | — |
toolBarLeft | 工具栏左侧左部插槽 | — |
tableTitle | 表格标题插槽 | — |
paginationTop | 分页顶部插槽 | — |
paginationBottom | 分页底部插槽 | — |
paginationLeft | 分页左侧插槽 | — |
paginationRight | 分页右侧插槽 | — |
formTop | 表单顶部插槽 | — |
formBottom | 表单底部插槽 | — |
crudMiddle | 中间内容插槽 | — |
columns属性
属性名 | 说明 | 类型 | 可选值 | 默认值 |
---|---|---|---|---|
type | 对应列的类型。 | string | selection / index / expand/ radio / button | — |
component | 列组件型。 | string | input / select / checkbox / radio / 任意局部或全局注册组件 | — |
index | 如果设置了 type=index ,可以通过传递 index 属性来自定义索引 | number / function(index) | — | — |
label | 显示的标题(建议配置) | string / (scope) => VNode | — | — |
form | 表单配置 | object | — | — |
add | 新增表单配置 | object / boolean | — | — |
edit | 编辑表单配置 | object / boolean | — | — |
search | 查询表单配置 | object / boolean | — | — |
detail | 详情表单配置 | object / boolean | — | — |
buttons | 按钮配置 | array | — | — |
options | 选项组件数据源 | array | — | |
tooltip | 列提示 | string / () => VNode | — | — |
column-key | column 的 key, column 的 key, 如果需要使用 filter-change 事件,则需要此属性标识是哪个 column 的筛选条件 | string | — | — |
prop | 字段名称 对应列内容的字段名, 也可以使用 property 属性 | string | — | — |
width | 对应列的宽度 | string / number | — | — |
min-width | 对应列的最小宽度, 对应列的最小宽度, 与 width 的区别是 width 是固定的,min-width 会把剩余宽度按比例分配给设置了 min-width 的列 | string / number | — | — |
fixed | 列是否固定在左侧或者右侧。 true 表示固定在左侧 | string / boolean | true / 'left' / 'right' | — |
render-header | 列标题 Label 区域渲染使用的 Function | function({ column, $index }) | — | — |
sortable | 对应列是否可以排序, 如果设置为 'custom',则代表用户希望远程排序,需要监听 Table 的 sort-change 事件 | boolean / string | custom | false |
sort-method | 指定数据按照哪个属性进行排序,仅当sortable 设置为true 的时候有效。 应该如同 Array.sort 那样返回一个 Number | function(a, b) | — | — |
sort-by | 指定数据按照哪个属性进行排序,仅当 sortable 设置为 true 且没有设置 sort-method 的时候有效。 如果 sort-by 为数组,则先按照第 1 个属性排序,如果第 1 个相等,再按照第 2 个排序,以此类推 | function(row, index) / string / array | — | — |
sort-orders | 数据在排序时所使用排序策略的轮转顺序,仅当 sortable 为 true 时有效。 需传入一个数组,随着用户点击表头,该列依次按照数组中元素的顺序进行排序 | array | 数组中的元素需为以下三者之一:ascending 表示升序,descending 表示降序,null 表示还原为原始顺序 | ['ascending', 'descending', null] |
resizable | 对应列是否可以通过拖动改变宽度(需要在 el-table 上设置 border 属性为真) | boolean | — | true |
formatter | 用来格式化内容 | function(row, column, cellValue, index) | — | — |
show-overflow-tooltip | 当内容过长被隐藏时显示 tooltip | boolean \ | object | 参考表格的 tooltip-options |
align | 对齐方式 | string | left / center / right | left |
header-align | 表头对齐方式, 若不设置该项,则使用表格的对齐方式 | string | left / center / right | — |
class-name | 列的 className | string | — | — |
label-class-name | 当前列标题的自定义类名 | string | — | — |
selectable | 仅对 type=selection 的列有效,类型为 Function,Function 的返回值用来决定这一行的 CheckBox 是否可以勾选 | function(row, index) | — | — |
reserve-selection | 数据刷新后是否保留选项,仅对 type=selection 的列有效, 请注意, 需指定 row-key 来让这个功能生效。 | boolean | — | false |
filters | 数据过滤的选项, 数组格式,数组中的元素需要有 text 和 value 属性。 数组中的每个元素都需要有 text 和 value 属性。 | Array<{text: string, value: string}> | — | — |
filter-placement | 过滤弹出框的定位 | string | 与 Tooltip 的 placement 属性相同 | — |
filter-multiple | 数据过滤的选项是否多选 | boolean | — | true |
filter-method | 数据过滤使用的方法, 如果是多选的筛选项,对每一条数据会执行多次,任意一次返回 true 就会显示。 | function(value, row, column) | — | — |
filtered-value | 选中的数据过滤项,如果需要自定义表头过滤的渲染方式,可能会需要此属性。 | array | — | — |
pagination属性
属性名 | 说明 | 类型 | 默认值 |
---|---|---|---|
type | 分页类型 | front / backbone | backbone |
page | 当前页 | number | — |
pageSize | 每页显示条目个数 | number | — |
small | 是否使用小型分页样式 | boolean | true |
background | 是否为分页按钮添加背景色 | boolean | false |
total | 总条目数 | number | — |
page-count | 总页数, total 和 page-count 设置任意一个就可以达到显示页码的功能;如果要支持 page-sizes 的更改,则需要使用 total 属性 | number | — |
pager-count | 设置最大页码按钮数。 页码按钮的数量,当总页数超过该值时会折叠 | number | 7 |
layout | 组件布局,子组件名用逗号分隔 | string | prev, pager, next, jumper, ->, total |
page-sizes | 每页显示个数选择器的选项设置 | object | [10, 20, 30, 40, 50, 100] |
popper-class | 每页显示个数选择器的下拉框类名 | string | '' |
prev-text | 替代图标显示的上一页文字 | string | '' |
prev-icon | 上一页的图标, 比 prev-text 优先级更高 | string / Component | ArrowLeft |
next-text | 替代图标显示的下一页文字 | string | '' |
next-icon | 下一页的图标, 比 next-text 优先级更低 | string / Component | ArrowRight |
disabled | 是否禁用分页 | boolean | false |
teleported | 是否将下拉菜单teleport至 body | boolean | true |
hide-on-single-page | 只有一页时是否隐藏 | boolean | false |
editable属性
属性名 | 说明 | 类型 | 默认值 |
---|---|---|---|
type | 可编辑表格模式 | single / multiple | single |
maxLength | 最大数量 | number | — |
deleteConfirm | 删除二次确认 | boolean | false |
onEdit | 编辑回调 | ({ row, index, column, formRef }) => void | — |
onCancel | 取消回调 | ({ row, index, column, formRef }) => void | — |
onSave | 保存回调 | ({ row, index, column, formRef }) => void | — |
onDelete | 删除回调 | ({ row, index, column, formRef }) => void | — |
column中buttons属性
属性名 | 说明 | 类型 | 默认值 |
---|---|---|---|
type | 类型 | primary / success '/ warning / danger / info / dropdown | — |
label | 文案 | string | — |
children | type 为dropdown 生效,下拉项 | array | — |
hide | 按钮隐藏 | boolean / () => boolean | — |
onClick | 点击事件 | (row, index, column) => void | — |
plain | 是否为朴素按钮 | boolean | false |
disabled | 按钮是否为禁用状态 | boolean / (row, index, column) => boolean | false |
size | 尺寸 | default / large / small | — |
plain | 是否为朴素按钮 | boolean | false |
text | 是否为文字按钮 | boolean | false |
bg | 是否显示文字按钮背景颜色 | boolean | false |
link | 是否为链接按钮 | boolean | false |
round | 是否为圆角按钮 | boolean | false |
circle | 是否为圆形按钮 | boolean | false |
loading | 是否为加载中状态 | boolean | false |
loading-icon | 自定义加载中状态图标组件 | string / Component | Loading |
icon | 图标组件 | string / Component | — |
autofocus | 原生 autofocus 属性 | boolean | false |
native-type | 原生 type 属性 | button / submit / reset | button |
auto-insert-space | 自动在两个中文字符之间插入空格 | boolean | — |
color | 自定义按钮颜色, 并自动计算 hover 和 active 触发后的颜色 | string | — |
dark | dark 模式, 意味着自动设置 color 为 dark 模式的颜色 | boolean | false |
tag | 自定义元素标签 | string / Component | button |
button类型为dropdown
属性名 | 说明 | 类型 | 可选值 | 默认值 |
---|---|---|---|---|
reference | 关联文案 | string / () => VNode | — | 更多 |
onCommand | 点击菜单项触发的事件回调 | (command) => void | — | — |
type | 菜单按钮类型,同 Button 组件一样,仅在 split-button 为 true 的情况下有效。 | string | — | — |
size | 菜单尺寸,在 split-button 为 true 的情况下也对触发按钮生效。 | string | large / default / small | default |
max-height | 菜单最大高度 | string / number | — | — |
split-button | 下拉触发元素呈现为按钮组 | boolean | — | false |
disabled | 是否禁用 | boolean | — | false |
placement | 菜单弹出位置 | string | top /top-start /top-end /bottom /bottom-start /bottom-end | bottom |
trigger | 触发下拉的行为 | string | hover / click /contextmenu | hover |
hide-on-click | 是否在点击菜单项后隐藏菜单 | boolean | — | true |
show-timeout | 展开下拉菜单的延时,仅在 trigger 为 hover 时有效 | number | — | 250 |
hide-timeout | 收起下拉菜单的延时(仅在 trigger 为 hover 时有效) | number | — | 150 |
role | 下拉菜单的 ARIA 属性。 根据具体场景,您可能想要将此更改为“navigation” | string | — | 'menu' |
tabindex | Dropdown 组件的 tabindex | number | — | 0 |
popper-class | 自定义浮层类名 | string | — | — |
popper-options | popper.js 参数 | Object | 请参考 popper.js 文档 | {modifiers: [{name: 'computeStyles',options: {gpuAcceleration: false}}]} |
teleported | 是否将下拉列表插入至 body 元素 | boolean | — | true |
button类型为dropdown的children下拉项属性
属性名 | 说明 | 类型 | 可选值 | 默认值 |
---|---|---|---|---|
disabled | 是否禁用 | boolean / (row, index, column) => boolean | — | false |
onClick | 下拉项点击 | (row, index, column) => void | — | — |
divided | 是否显示分隔符 | boolean | — | false |
icon | 自定义图标 | string / Component | — | — |
toolBar属性
属性名 | 说明 | 类型 | 可选值 | 默认值 |
---|---|---|---|---|
exclude | 不显示在工具栏的表格项 label 集合 | array | — | — |
unCheck | 默认不选中的 label 集合 | array | — | — |
refresh | 刷新功能是否展示 | boolean | — | true |
density | 密度功能是否展示 | boolean | — | true |
fullScreen | 全屏功能是否展示 | boolean | — | true |
setting | 列配置功能是否展示 | boolean | — | true |