Crud 增删改查
z-crud
组件新增编辑表单部分功能介绍。
基础用法
配置column
的add
或edit
字段,可以实现新增或编辑表单的配置。
<!-- eslint-disable no-console -->
<script lang="ts" setup>
import { ref } from 'vue'
import type { EditRequestApiParams } from 'ideaz-element'
interface RowData {
id: number
name: string
gender: string
age: number
date: string
time: string[]
}
interface FormData {
name: string
gender: string
age: string
}
const loading = ref(false)
const formData = ref({
name: '',
gender: '',
age: '',
})
const tableData = ref([])
const columns = ref([
{
prop: 'name',
label: '姓名',
add: {
component: 'input',
field: 'name',
label: '姓名',
required: true,
},
edit: {
component: 'input',
field: 'name',
label: '姓名',
required: true,
},
},
{
prop: 'gender',
label: '性别',
add: {
component: 'select',
field: 'gender',
label: '性别',
},
edit: {
component: 'select',
field: 'gender',
label: '性别',
},
},
{
prop: 'age',
label: '年龄',
add: {
component: 'el-date-picker',
field: 'time',
label: '出生日期',
fieldProps: {
type: 'daterange',
startPlaceholder: '开始日期',
endPlaceholder: '结束日期',
},
},
edit: {
component: 'el-date-picker',
field: 'time',
label: '出生日期',
fieldProps: {
type: 'daterange',
startPlaceholder: '开始日期',
endPlaceholder: '结束日期',
},
},
},
{
prop: 'date',
label: '出生日期',
},
])
const searchFormConfig = ref({
labelWith: '80px',
columns: [
{
component: 'input',
label: '姓名',
field: 'name',
},
{
component: 'select',
label: '性别',
field: 'gender',
},
{
component: 'input',
label: '年龄',
field: 'age',
},
],
})
const options = {
gender: [{ label: 'male', value: 'male' }, { label: 'female', value: 'female' }],
}
const pagination = ref({
page: 1,
pageSize: 2,
total: 4,
})
const request = ref({
searchApi: mockApi,
addApi: commonApi,
editApi: commonApi,
})
function mockApi() {
return new Promise((resolve) => {
setTimeout(() => {
const data = [
{
id: 1,
name: 'Steven',
gender: 'male',
age: 22,
date: '2020-01-01',
time: ['2020-01-01', '2020-01-02'],
},
{
id: 2,
name: 'Helen',
gender: 'male',
age: 12,
date: '2012-01-01',
time: ['2020-01-01', '2020-01-02'],
},
{
id: 3,
name: 'Nancy',
gender: 'female',
age: 18,
date: '2018-01-01',
time: ['2020-01-01', '2020-01-02'],
},
{
id: 4,
name: 'Jack',
gender: 'male',
age: 28,
date: '2028-01-01',
time: ['2020-01-01', '2020-01-02'],
},
]
resolve({
data: {
page: 1,
pageSize: 10,
total: 4,
list: data.slice((pagination.value.page - 1) * pagination.value.pageSize, pagination.value.page * pagination.value.pageSize),
},
})
}, 100)
})
}
function commonApi(params: EditRequestApiParams<FormData, RowData>) {
console.log(JSON.stringify(params), 'commonApi params')
return new Promise((resolve) => {
setTimeout(() => {
resolve({
msg: 'success',
code: 200,
})
}, 100)
})
}
</script>
<template>
<z-crud
v-model:pagination="pagination"
v-model:data="tableData"
v-model:formData="formData"
v-model:loading="loading"
:columns="columns"
:options="options"
:detail="false"
:search="searchFormConfig"
:request="request"
/>
</template>
配置add
和edit
的columns
字段,可以实现新增和编辑表单的配置。
<!-- eslint-disable no-console -->
<script lang="ts" setup>
import { ref } from 'vue'
import type { EditRequestApiParams } from 'ideaz-element'
interface RowData {
id: number
name: string
gender: string
age: number
date: string
time: string[]
}
interface FormData {
name: string
gender: string
age: string
}
const loading = ref(false)
const formData = ref({
name: '',
gender: '',
age: '',
})
const tableData = ref([])
const columns = ref([
{
prop: 'name',
label: '姓名',
},
{
prop: 'gender',
label: '性别',
},
{
prop: 'age',
label: '年龄',
},
{
prop: 'date',
label: '出生日期',
},
])
const searchFormConfig = ref({
labelWith: '80px',
columns: [
{
component: 'input',
label: '姓名',
field: 'name',
},
{
component: 'select',
label: '性别',
field: 'gender',
},
{
component: 'input',
label: '年龄',
field: 'age',
},
],
})
const addFormConfig = ref({
columns: [
{
component: 'input',
label: '姓名新增',
field: 'name',
},
{
component: 'select',
label: '性别',
field: 'gender',
},
{
component: 'input',
label: '年龄',
field: 'age',
},
],
})
const editFormConfig = ref({
columns: [
{
component: 'input',
label: '姓名编辑',
field: 'name',
},
{
component: 'select',
label: '性别',
field: 'gender',
},
{
component: 'input',
label: '年龄',
field: 'age',
},
],
})
const options = {
gender: [{ label: 'male', value: 'male' }, { label: 'female', value: 'female' }],
}
const pagination = ref({
page: 1,
pageSize: 2,
total: 4,
})
const request = ref({
searchApi: mockApi,
addApi: commonApi,
editApi: commonApi,
})
function mockApi() {
return new Promise((resolve) => {
setTimeout(() => {
const data = [
{
id: 1,
name: 'Steven',
gender: 'male',
age: 22,
date: '2020-01-01',
time: ['2020-01-01', '2020-01-02'],
},
{
id: 2,
name: 'Helen',
gender: 'male',
age: 12,
date: '2012-01-01',
time: ['2020-01-01', '2020-01-02'],
},
{
id: 3,
name: 'Nancy',
gender: 'female',
age: 18,
date: '2018-01-01',
time: ['2020-01-01', '2020-01-02'],
},
{
id: 4,
name: 'Jack',
gender: 'male',
age: 28,
date: '2028-01-01',
time: ['2020-01-01', '2020-01-02'],
},
]
resolve({
data: {
page: 1,
pageSize: 10,
total: 4,
list: data.slice((pagination.value.page - 1) * pagination.value.pageSize, pagination.value.page * pagination.value.pageSize),
},
})
}, 100)
})
}
function commonApi(params: EditRequestApiParams<FormData, RowData>) {
console.log(JSON.stringify(params), 'commonApi params')
return new Promise((resolve) => {
setTimeout(() => {
resolve({
msg: 'success',
code: 200,
})
}, 100)
})
}
</script>
<template>
<z-crud
v-model:pagination="pagination"
v-model:data="tableData"
v-model:formData="formData"
v-model:loading="loading"
:columns="columns"
:options="options"
:search="searchFormConfig"
:request="request"
:detail="false"
:add="addFormConfig"
:edit="editFormConfig"
/>
</template>
配置form
的columns
字段,可以同时实现新增和编辑表单的配置,但也会同时配置查询和详情信息,可以配置search
和detail
为false
来关闭。
<!-- eslint-disable no-console -->
<script lang="ts" setup>
import { ref } from 'vue'
import type { EditRequestApiParams } from 'ideaz-element'
interface RowData {
id: number
name: string
gender: string
age: number
date: string
time: string[]
}
interface FormData {
name: string
gender: string
age: string
}
const loading = ref(false)
const formData = ref({
name: '',
gender: '',
age: '',
})
const tableData = ref([])
const columns = ref([
{
prop: 'name',
label: '姓名',
},
{
prop: 'gender',
label: '性别',
},
{
prop: 'age',
label: '年龄',
},
{
prop: 'date',
label: '出生日期',
},
])
const searchFormConfig = ref({
labelWith: '80px',
columns: [
{
component: 'input',
label: '姓名',
field: 'name',
},
{
component: 'select',
label: '性别',
field: 'gender',
},
{
component: 'input',
label: '年龄',
field: 'age',
},
],
})
const options = {
gender: [{ label: 'male', value: 'male' }, { label: 'female', value: 'female' }],
}
const pagination = ref({
page: 1,
pageSize: 2,
total: 4,
})
const request = ref({
searchApi: mockApi,
addApi: commonApi,
editApi: commonApi,
})
const formConfig = ref({
columns: [
{
component: 'input',
field: 'name',
label: '姓名',
required: true,
},
{
component: 'select',
field: 'gender',
label: '性别',
},
{
component: 'el-date-picker',
field: 'time',
label: '出生日期',
fieldProps: {
type: 'daterange',
startPlaceholder: '开始日期',
endPlaceholder: '结束日期',
},
},
],
})
function mockApi() {
return new Promise((resolve) => {
setTimeout(() => {
const data = [
{
id: 1,
name: 'Steven',
gender: 'male',
age: 22,
date: '2020-01-01',
time: ['2020-01-01', '2020-01-02'],
},
{
id: 2,
name: 'Helen',
gender: 'male',
age: 12,
date: '2012-01-01',
time: ['2020-01-01', '2020-01-02'],
},
{
id: 3,
name: 'Nancy',
gender: 'female',
age: 18,
date: '2018-01-01',
time: ['2020-01-01', '2020-01-02'],
},
{
id: 4,
name: 'Jack',
gender: 'male',
age: 28,
date: '2028-01-01',
time: ['2020-01-01', '2020-01-02'],
},
]
resolve({
data: {
page: 1,
pageSize: 10,
total: 4,
list: data.slice((pagination.value.page - 1) * pagination.value.pageSize, pagination.value.page * pagination.value.pageSize),
},
})
}, 100)
})
}
function commonApi(params: EditRequestApiParams<FormData, RowData>) {
console.log(JSON.stringify(params), 'commonApi params')
return new Promise((resolve) => {
setTimeout(() => {
resolve({
msg: 'success',
code: 200,
})
}, 100)
})
}
</script>
<template>
<z-crud
v-model:pagination="pagination"
v-model:data="tableData"
v-model:formData="formData"
v-model:loading="loading"
:columns="columns"
:options="options"
:search="searchFormConfig"
:form="formConfig"
:request="request"
:detail="false"
/>
</template>
配置column
项的form
字段,可以实现新增、编辑表单的配置,但会同时配置查询表单,可以设置search
为false
关闭。
<!-- eslint-disable no-console -->
<script lang="ts" setup>
import { ref } from 'vue'
import type { EditRequestApiParams } from 'ideaz-element'
interface RowData {
id: number
name: string
gender: string
age: number
date: string
time: string[]
}
interface FormData {
name: string
gender: string
age: string
}
const loading = ref(false)
const formData = ref({
name: '',
gender: '',
age: '',
})
const tableData = ref([])
const columns = ref([
{
prop: 'name',
label: '姓名',
form: {
component: 'input',
field: 'name',
label: '姓名',
required: true,
},
},
{
prop: 'gender',
label: '性别',
form: {
component: 'select',
field: 'gender',
label: '性别',
},
},
{
prop: 'age',
label: '年龄',
form: {
component: 'el-date-picker',
field: 'time',
label: '出生日期',
fieldProps: {
type: 'daterange',
startPlaceholder: '开始日期',
endPlaceholder: '结束日期',
},
},
search: false,
},
{
prop: 'date',
label: '出生日期',
},
])
const options = {
gender: [{ label: 'male', value: 'male' }, { label: 'female', value: 'female' }],
}
const pagination = ref({
page: 1,
pageSize: 2,
total: 4,
})
const request = ref({
searchApi: mockApi,
addApi: commonApi,
editApi: commonApi,
})
function mockApi() {
return new Promise((resolve) => {
setTimeout(() => {
const data = [
{
id: 1,
name: 'Steven',
gender: 'male',
age: 22,
date: '2020-01-01',
time: ['2020-01-01', '2020-01-02'],
},
{
id: 2,
name: 'Helen',
gender: 'male',
age: 12,
date: '2012-01-01',
time: ['2020-01-01', '2020-01-02'],
},
{
id: 3,
name: 'Nancy',
gender: 'female',
age: 18,
date: '2018-01-01',
time: ['2020-01-01', '2020-01-02'],
},
{
id: 4,
name: 'Jack',
gender: 'male',
age: 28,
date: '2028-01-01',
time: ['2020-01-01', '2020-01-02'],
},
]
resolve({
data: {
page: 1,
pageSize: 10,
total: 4,
list: data.slice((pagination.value.page - 1) * pagination.value.pageSize, pagination.value.page * pagination.value.pageSize),
},
})
}, 100)
})
}
function commonApi(params: EditRequestApiParams<FormData, RowData>) {
console.log(JSON.stringify(params), 'commonApi params')
return new Promise((resolve) => {
setTimeout(() => {
resolve({
msg: 'success',
code: 200,
})
}, 100)
})
}
</script>
<template>
<z-crud
v-model:pagination="pagination"
v-model:data="tableData"
v-model:formData="formData"
v-model:loading="loading"
:columns="columns"
:options="options"
:detail="false"
:request="request"
/>
</template>
确认接口
配置request
的addApi
和editApi
。
editApi
会多传一个rowKey
参数,默认为id
。
<!-- eslint-disable no-console -->
<script lang="ts" setup>
import { ref } from 'vue'
import type { EditRequestApiParams } from 'ideaz-element'
interface RowData {
id: number
name: string
gender: string
age: number
date: string
time: string[]
}
interface FormData {
name: string
gender: string
age: string
}
const loading = ref(false)
const formData = ref({
name: '',
gender: '',
age: '',
})
const tableData = ref([])
const columns = ref([
{
prop: 'name',
label: '姓名',
form: {
component: 'input',
field: 'name',
label: '姓名',
required: true,
},
},
{
prop: 'gender',
label: '性别',
form: {
component: 'select',
field: 'gender',
label: '性别',
},
},
{
prop: 'age',
label: '年龄',
form: {
component: 'el-date-picker',
field: 'time',
label: '出生日期',
fieldProps: {
type: 'daterange',
startPlaceholder: '开始日期',
endPlaceholder: '结束日期',
},
},
search: false,
},
{
prop: 'date',
label: '出生日期',
},
])
const options = {
gender: [{ label: 'male', value: 'male' }, { label: 'female', value: 'female' }],
}
const pagination = ref({
page: 1,
pageSize: 2,
total: 4,
})
const request = ref({
searchApi: mockApi,
addApi: commonApi,
editApi: commonApi,
})
function mockApi() {
return new Promise((resolve) => {
setTimeout(() => {
const data = [
{
id: 1,
name: 'Steven',
gender: 'male',
age: 22,
date: '2020-01-01',
time: ['2020-01-01', '2020-01-02'],
},
{
id: 2,
name: 'Helen',
gender: 'male',
age: 12,
date: '2012-01-01',
time: ['2020-01-01', '2020-01-02'],
},
{
id: 3,
name: 'Nancy',
gender: 'female',
age: 18,
date: '2018-01-01',
time: ['2020-01-01', '2020-01-02'],
},
{
id: 4,
name: 'Jack',
gender: 'male',
age: 28,
date: '2028-01-01',
time: ['2020-01-01', '2020-01-02'],
},
]
resolve({
data: {
page: 1,
pageSize: 10,
total: 4,
list: data.slice((pagination.value.page - 1) * pagination.value.pageSize, pagination.value.page * pagination.value.pageSize),
},
})
}, 100)
})
}
function commonApi(params: EditRequestApiParams<FormData, RowData>) {
console.log(JSON.stringify(params), 'commonApi params')
return new Promise((resolve) => {
setTimeout(() => {
resolve({
msg: 'success',
code: 200,
})
}, 100)
})
}
</script>
<template>
<z-crud
v-model:pagination="pagination"
v-model:data="tableData"
v-model:formData="formData"
v-model:loading="loading"
:columns="columns"
:options="options"
:detail="false"
:request="request"
/>
</template>
如果新增和编辑接口相同,可以配置submitApi
,编辑的时候也会带上rowKey
。
<!-- eslint-disable no-console -->
<script lang="ts" setup>
import { ref } from 'vue'
import type { DialogFormSubmitParams } from 'ideaz-element'
interface FormData {
name?: string
gender?: string
age?: string
}
interface RowData {
id: number
name: string
gender: string
age: number
date: string
time: string[]
}
const loading = ref(false)
const formData = ref({
name: '',
gender: '',
age: '',
})
const tableData = ref([])
const columns = ref([
{
prop: 'name',
label: '姓名',
form: {
component: 'input',
field: 'name',
label: '姓名',
required: true,
},
},
{
prop: 'gender',
label: '性别',
form: {
component: 'select',
field: 'gender',
label: '性别',
},
},
{
prop: 'age',
label: '年龄',
form: {
component: 'el-date-picker',
field: 'time',
label: '出生日期',
fieldProps: {
type: 'daterange',
startPlaceholder: '开始日期',
endPlaceholder: '结束日期',
},
},
search: false,
},
{
prop: 'date',
label: '出生日期',
},
])
const options = {
gender: [{ label: 'male', value: 'male' }, { label: 'female', value: 'female' }],
}
const pagination = ref({
page: 1,
pageSize: 2,
total: 4,
})
const request = ref({
searchApi: mockApi,
submitApi: commonApi,
})
function mockApi() {
return new Promise((resolve) => {
setTimeout(() => {
const data = [
{
id: 1,
name: 'Steven',
gender: 'male',
age: 22,
date: '2020-01-01',
time: ['2020-01-01', '2020-01-02'],
},
{
id: 2,
name: 'Helen',
gender: 'male',
age: 12,
date: '2012-01-01',
time: ['2020-01-01', '2020-01-02'],
},
{
id: 3,
name: 'Nancy',
gender: 'female',
age: 18,
date: '2018-01-01',
time: ['2020-01-01', '2020-01-02'],
},
{
id: 4,
name: 'Jack',
gender: 'male',
age: 28,
date: '2028-01-01',
time: ['2020-01-01', '2020-01-02'],
},
]
resolve({
data: {
page: 1,
pageSize: 10,
total: 4,
list: data.slice((pagination.value.page - 1) * pagination.value.pageSize, pagination.value.page * pagination.value.pageSize),
},
})
}, 100)
})
}
function commonApi(params: DialogFormSubmitParams<FormData, RowData>) {
console.log(JSON.stringify(params), 'commonApi params')
return new Promise((resolve) => {
setTimeout(() => {
resolve({
msg: 'success',
code: 200,
})
}, 100)
})
}
</script>
<template>
<z-crud
v-model:pagination="pagination"
v-model:data="tableData"
v-model:formData="formData"
v-model:loading="loading"
:columns="columns"
:options="options"
:detail="false"
:request="request"
/>
</template>
编辑详情数据
配置request
的detailApi
可以实现编辑弹窗默认数据从接口中获取。
<!-- eslint-disable no-console -->
<script lang="ts" setup>
import { ref } from 'vue'
import type { EditRequestApiParams } from 'ideaz-element'
interface RowData {
id: number
name: string
gender: string
age: number
date: string
time: string[]
}
interface FormData {
name: string
gender: string
age: string
}
const loading = ref(false)
const formData = ref({
name: '',
gender: '',
age: '',
})
const tableData = ref([])
const columns = ref([
{
prop: 'name',
label: '姓名',
form: {
component: 'input',
field: 'name',
label: '姓名',
required: true,
},
},
{
prop: 'gender',
label: '性别',
form: {
component: 'select',
field: 'gender',
label: '性别',
},
},
{
prop: 'age',
label: '年龄',
form: {
component: 'el-date-picker',
field: 'time',
label: '出生日期',
fieldProps: {
type: 'daterange',
startPlaceholder: '开始日期',
endPlaceholder: '结束日期',
},
},
search: false,
},
{
prop: 'date',
label: '出生日期',
},
])
const options = {
gender: [{ label: 'male', value: 'male' }, { label: 'female', value: 'female' }],
}
const pagination = ref({
page: 1,
pageSize: 2,
total: 4,
})
const request = ref({
searchApi: mockApi,
addApi: commonApi,
editApi: commonApi,
detailApi,
})
function mockApi() {
return new Promise((resolve) => {
setTimeout(() => {
const data = [
{
id: 1,
name: 'Steven',
gender: 'male',
age: 22,
date: '2020-01-01',
time: ['2020-01-01', '2020-01-02'],
},
{
id: 2,
name: 'Helen',
gender: 'male',
age: 12,
date: '2012-01-01',
time: ['2020-01-01', '2020-01-02'],
},
{
id: 3,
name: 'Nancy',
gender: 'female',
age: 18,
date: '2018-01-01',
time: ['2020-01-01', '2020-01-02'],
},
{
id: 4,
name: 'Jack',
gender: 'male',
age: 28,
date: '2028-01-01',
time: ['2020-01-01', '2020-01-02'],
},
]
resolve({
data: {
page: 1,
pageSize: 10,
total: 4,
list: data.slice((pagination.value.page - 1) * pagination.value.pageSize, pagination.value.page * pagination.value.pageSize),
},
})
}, 100)
})
}
function commonApi(params: EditRequestApiParams<FormData, RowData>) {
console.log(JSON.stringify(params), 'commonApi params')
return new Promise((resolve) => {
setTimeout(() => {
resolve({
msg: 'success',
code: 200,
})
}, 100)
})
}
function detailApi(params: { id: number }) {
console.log(JSON.stringify(params), 'detailApi params')
return new Promise((resolve) => {
setTimeout(() => {
resolve({
data: {
id: 1,
name: 'Steven',
gender: 'male',
age: 22,
time: ['2020-01-01', '2020-01-03'],
},
})
}, 100)
})
}
</script>
<template>
<z-crud
v-model:pagination="pagination"
v-model:data="tableData"
v-model:formData="formData"
v-model:loading="loading"
:columns="columns"
:options="options"
:detail="false"
:request="request"
/>
</template>
详情数据二次处理
如果需要对接口返回的详情数据二次梳理,可以配置request.alias.detail
。传入函数支持自定义详情数据,传入字符串支持自定义数据路径。
<!-- eslint-disable no-console -->
<script lang="ts" setup>
import { ref } from 'vue'
import type { EditRequestApiParams } from 'ideaz-element'
interface RowData {
id: number
name: string
gender: string
age: number
time: string[]
date: string
}
interface FormData {
name: string
gender: string
age: string
}
interface GetTableDataRes { data: { page: number, pageSize: number, list: RowData[], total: number } }
const loading = ref(false)
const formData = ref({
name: '',
gender: '',
age: '',
})
const tableData = ref<RowData[]>([])
const columns = ref([
{
prop: 'name',
label: '姓名',
form: {
component: 'input',
field: 'name',
label: '姓名',
required: true,
},
},
{
prop: 'gender',
label: '性别',
form: {
component: 'select',
field: 'gender',
label: '性别',
},
},
{
prop: 'age',
label: '年龄',
form: {
component: 'el-date-picker',
field: 'time',
label: '出生日期',
fieldProps: {
type: 'daterange',
startPlaceholder: '开始日期',
endPlaceholder: '结束日期',
},
},
search: false,
},
{
prop: 'date',
label: '出生日期',
},
])
const options = {
gender: [{ label: 'male', value: 'male' }, { label: 'female', value: 'female' }],
}
const pagination = ref({
page: 1,
pageSize: 2,
total: 4,
})
const request = ref({
searchApi: mockApi,
addApi: commonApi,
editApi: commonApi,
detailApi,
alias: {
detail: (res: GetTableDataRes) => {
console.log(res, 'res')
return {
...res.data,
time: [],
}
},
},
})
function mockApi(): Promise<GetTableDataRes> {
return new Promise((resolve) => {
setTimeout(() => {
const data = [
{
id: 1,
name: 'Steven',
gender: 'male',
age: 22,
date: '2020-01-01',
time: ['2020-01-01', '2020-01-02'],
},
{
id: 2,
name: 'Helen',
gender: 'male',
age: 12,
date: '2012-01-01',
time: ['2020-01-01', '2020-01-02'],
},
{
id: 3,
name: 'Nancy',
gender: 'female',
age: 18,
date: '2018-01-01',
time: ['2020-01-01', '2020-01-02'],
},
{
id: 4,
name: 'Jack',
gender: 'male',
age: 28,
date: '2028-01-01',
time: ['2020-01-01', '2020-01-02'],
},
]
resolve({
data: {
page: 1,
pageSize: 10,
total: 4,
list: data.slice((pagination.value.page - 1) * pagination.value.pageSize, pagination.value.page * pagination.value.pageSize),
},
})
}, 100)
})
}
function commonApi(params: EditRequestApiParams<FormData, RowData>) {
console.log(JSON.stringify(params), 'commonApi params')
return new Promise((resolve) => {
setTimeout(() => {
resolve({
msg: 'success',
code: 200,
})
}, 100)
})
}
function detailApi(params: { id: number }) {
console.log(JSON.stringify(params), 'detailApi params')
return new Promise((resolve) => {
setTimeout(() => {
resolve({
data: {
id: 1,
name: 'Steven',
gender: 'male',
age: 22,
time: ['2020-01-01', '2020-01-03'],
},
})
}, 100)
})
}
</script>
<template>
<z-crud
v-model:pagination="pagination"
v-model:data="tableData"
v-model:formData="formData"
v-model:loading="loading"
:columns="columns"
:options="options"
:detail="false"
:request="request"
/>
</template>
自定义确认
request
不配置submitApi
、addApi
和editApi
,此时会有operate-submit
事件。
<!-- eslint-disable no-console -->
<script lang="ts" setup>
import { ref } from 'vue'
import type { DialogFormSubmitParams } from 'ideaz-element'
interface FormData {
name?: string
gender?: string
age?: string
}
interface RowData {
id: number
name: string
gender: string
age: number
date: string
time: string[]
}
const loading = ref(false)
const formData = ref({
name: '',
gender: '',
age: '',
})
const tableData = ref([])
const columns = ref([
{
prop: 'name',
label: '姓名',
form: {
component: 'input',
field: 'name',
label: '姓名',
required: true,
},
},
{
prop: 'gender',
label: '性别',
form: {
component: 'select',
field: 'gender',
label: '性别',
},
},
{
prop: 'age',
label: '年龄',
form: {
component: 'el-date-picker',
field: 'time',
label: '出生日期',
fieldProps: {
type: 'daterange',
startPlaceholder: '开始日期',
endPlaceholder: '结束日期',
},
},
search: false,
},
{
prop: 'date',
label: '出生日期',
},
])
const options = {
gender: [{ label: 'male', value: 'male' }, { label: 'female', value: 'female' }],
}
const pagination = ref({
page: 1,
pageSize: 2,
total: 4,
})
const request = ref({
searchApi: mockApi,
})
function mockApi() {
return new Promise((resolve) => {
setTimeout(() => {
const data = [
{
id: 1,
name: 'Steven',
gender: 'male',
age: 22,
date: '2020-01-01',
time: ['2020-01-01', '2020-01-02'],
},
{
id: 2,
name: 'Helen',
gender: 'male',
age: 12,
date: '2012-01-01',
time: ['2020-01-01', '2020-01-02'],
},
{
id: 3,
name: 'Nancy',
gender: 'female',
age: 18,
date: '2018-01-01',
time: ['2020-01-01', '2020-01-02'],
},
{
id: 4,
name: 'Jack',
gender: 'male',
age: 28,
date: '2028-01-01',
time: ['2020-01-01', '2020-01-02'],
},
]
resolve({
data: {
page: 1,
pageSize: 10,
total: 4,
list: data.slice((pagination.value.page - 1) * pagination.value.pageSize, pagination.value.page * pagination.value.pageSize),
},
})
}, 100)
})
}
function handleSubmit({ done, formRef, formData, type, confirmButtonLoading, row, invalidFields }: DialogFormSubmitParams<FormData, RowData>) {
confirmButtonLoading.value = true
console.log(formRef, formData, type, invalidFields, row)
done()
confirmButtonLoading.value = false
}
</script>
<template>
<z-crud
v-model:pagination="pagination"
v-model:data="tableData"
v-model:formData="formData"
v-model:loading="loading"
:columns="columns"
:options="options"
:detail="false"
:request="request"
@operate-submit="handleSubmit"
/>
</template>
自定义取消
operate-cancel
自定义取消事件,如果组件不配置,点击取消默认关闭。
<!-- eslint-disable no-console -->
<script lang="ts" setup>
import { ref } from 'vue'
import type { DialogFormSubmitParams } from 'ideaz-element'
interface FormData {
name?: string
gender?: string
age?: string
}
interface RowData {
id: number
name: string
gender: string
age: number
date: string
time: string[]
}
const loading = ref(false)
const formData = ref({
name: '',
gender: '',
age: '',
})
const tableData = ref([])
const columns = ref([
{
prop: 'name',
label: '姓名',
form: {
component: 'input',
field: 'name',
label: '姓名',
required: true,
},
},
{
prop: 'gender',
label: '性别',
form: {
component: 'select',
field: 'gender',
label: '性别',
},
},
{
prop: 'age',
label: '年龄',
form: {
component: 'el-date-picker',
field: 'time',
label: '出生日期',
fieldProps: {
type: 'daterange',
startPlaceholder: '开始日期',
endPlaceholder: '结束日期',
},
},
search: false,
},
{
prop: 'date',
label: '出生日期',
},
])
const options = {
gender: [{ label: 'male', value: 'male' }, { label: 'female', value: 'female' }],
}
const pagination = ref({
page: 1,
pageSize: 2,
total: 4,
})
const request = ref({
searchApi: mockApi,
})
function mockApi() {
return new Promise((resolve) => {
setTimeout(() => {
const data = [
{
id: 1,
name: 'Steven',
gender: 'male',
age: 22,
date: '2020-01-01',
time: ['2020-01-01', '2020-01-02'],
},
{
id: 2,
name: 'Helen',
gender: 'male',
age: 12,
date: '2012-01-01',
time: ['2020-01-01', '2020-01-02'],
},
{
id: 3,
name: 'Nancy',
gender: 'female',
age: 18,
date: '2018-01-01',
time: ['2020-01-01', '2020-01-02'],
},
{
id: 4,
name: 'Jack',
gender: 'male',
age: 28,
date: '2028-01-01',
time: ['2020-01-01', '2020-01-02'],
},
]
resolve({
data: {
page: 1,
pageSize: 10,
total: 4,
list: data.slice((pagination.value.page - 1) * pagination.value.pageSize, pagination.value.page * pagination.value.pageSize),
},
})
}, 100)
})
}
function handleSubmit({ done, formRef, formData, type, confirmButtonLoading, row, invalidFields }: DialogFormSubmitParams<FormData, RowData>) {
confirmButtonLoading.value = true
console.log(formRef, formData, type, invalidFields, row)
done()
confirmButtonLoading.value = false
}
</script>
<template>
<z-crud
v-model:pagination="pagination"
v-model:data="tableData"
v-model:formData="formData"
v-model:loading="loading"
:columns="columns"
:options="options"
:detail="false"
:request="request"
@operate-submit="handleSubmit"
/>
</template>
表单属性
使用add
和edit
对象配置新增和编辑表单属性。form
属性可以统一配置新增和编辑。
<!-- eslint-disable no-console -->
<script lang="ts" setup>
import { ref } from 'vue'
import type { EditRequestApiParams } from 'ideaz-element'
interface RowData {
id: number
name: string
gender: string
age: number
date: string
time: string[]
}
interface FormData {
name: string
gender: string
age: string
}
const loading = ref(false)
const formData = ref({
name: '',
gender: '',
age: '',
})
const tableData = ref([])
const columns = ref([
{
prop: 'name',
label: '姓名',
add: {
component: 'input',
field: 'name',
label: '姓名',
required: true,
},
edit: {
component: 'input',
field: 'name',
label: '姓名',
required: true,
},
},
{
prop: 'gender',
label: '性别',
add: {
component: 'select',
field: 'gender',
label: '性别',
},
edit: {
component: 'select',
field: 'gender',
label: '性别',
},
},
{
prop: 'age',
label: '年龄',
add: {
component: 'el-date-picker',
field: 'time',
label: '出生日期',
fieldProps: {
type: 'daterange',
startPlaceholder: '开始日期',
endPlaceholder: '结束日期',
},
},
edit: {
component: 'el-date-picker',
field: 'time',
label: '出生日期',
fieldProps: {
type: 'daterange',
startPlaceholder: '开始日期',
endPlaceholder: '结束日期',
},
},
},
{
prop: 'date',
label: '出生日期',
},
])
const searchFormConfig = ref({
labelWith: '80px',
columns: [
{
component: 'input',
label: '姓名',
field: 'name',
},
{
component: 'select',
label: '性别',
field: 'gender',
},
{
component: 'input',
label: '年龄',
field: 'age',
},
],
})
const addFormConfig = ref({
labelWidth: '120px',
labelPosition: 'top',
})
const editFormConfig = ref({
labelWidth: '80px',
labelPosition: 'left',
})
const options = {
gender: [{ label: 'male', value: 'male' }, { label: 'female', value: 'female' }],
}
const pagination = ref({
page: 1,
pageSize: 2,
total: 4,
})
const request = ref({
searchApi: mockApi,
addApi: commonApi,
editApi: commonApi,
})
function mockApi() {
return new Promise((resolve) => {
setTimeout(() => {
const data = [
{
id: 1,
name: 'Steven',
gender: 'male',
age: 22,
date: '2020-01-01',
time: ['2020-01-01', '2020-01-02'],
},
{
id: 2,
name: 'Helen',
gender: 'male',
age: 12,
date: '2012-01-01',
time: ['2020-01-01', '2020-01-02'],
},
{
id: 3,
name: 'Nancy',
gender: 'female',
age: 18,
date: '2018-01-01',
time: ['2020-01-01', '2020-01-02'],
},
{
id: 4,
name: 'Jack',
gender: 'male',
age: 28,
date: '2028-01-01',
time: ['2020-01-01', '2020-01-02'],
},
]
resolve({
data: {
page: 1,
pageSize: 10,
total: 4,
list: data.slice((pagination.value.page - 1) * pagination.value.pageSize, pagination.value.page * pagination.value.pageSize),
},
})
}, 100)
})
}
function commonApi(params: EditRequestApiParams<FormData, RowData>) {
console.log(JSON.stringify(params), 'commonApi params')
return new Promise((resolve) => {
setTimeout(() => {
resolve({
msg: 'success',
code: 200,
})
}, 100)
})
}
</script>
<template>
<z-crud
v-model:pagination="pagination"
v-model:data="tableData"
v-model:formData="formData"
v-model:loading="loading"
:columns="columns"
:options="options"
:search="searchFormConfig"
:add="addFormConfig"
:edit="editFormConfig"
:detail="false"
:request="request"
/>
</template>
弹窗属性
可以使用dialog
对象统一配置新增和编辑弹窗属性,也可以使用add.dialog
和edit.dialog
分别配置弹窗属性。
<!-- eslint-disable no-console -->
<script lang="ts" setup>
import { ref } from 'vue'
import type { EditRequestApiParams } from 'ideaz-element'
interface RowData {
id: number
name: string
gender: string
age: number
date: string
time: string[]
}
interface FormData {
name: string
gender: string
age: string
}
const loading = ref(false)
const formData = ref({
name: '',
gender: '',
age: '',
})
const tableData = ref([])
const columns = ref([
{
prop: 'name',
label: '姓名',
add: {
component: 'input',
field: 'name',
label: '姓名',
required: true,
},
edit: {
component: 'input',
field: 'name',
label: '姓名',
required: true,
},
},
{
prop: 'gender',
label: '性别',
add: {
component: 'select',
field: 'gender',
label: '性别',
},
edit: {
component: 'select',
field: 'gender',
label: '性别',
},
},
{
prop: 'age',
label: '年龄',
add: {
component: 'el-date-picker',
field: 'time',
label: '出生日期',
fieldProps: {
type: 'daterange',
startPlaceholder: '开始日期',
endPlaceholder: '结束日期',
},
},
edit: {
component: 'el-date-picker',
field: 'time',
label: '出生日期',
fieldProps: {
type: 'daterange',
startPlaceholder: '开始日期',
endPlaceholder: '结束日期',
},
},
},
{
prop: 'date',
label: '出生日期',
},
])
const searchFormConfig = ref({
labelWith: '80px',
columns: [
{
component: 'input',
label: '姓名',
field: 'name',
},
{
component: 'select',
label: '性别',
field: 'gender',
},
{
component: 'input',
label: '年龄',
field: 'age',
},
],
})
const addFormConfig = ref({
labelWidth: '120px',
labelPosition: 'top',
dialog: {
title: '新增弹窗',
},
})
const editFormConfig = ref({
labelWidth: '80px',
labelPosition: 'left',
dialog: {
title: '编辑弹窗',
},
})
const options = {
gender: [{ label: 'male', value: 'male' }, { label: 'female', value: 'female' }],
}
const pagination = ref({
page: 1,
pageSize: 2,
total: 4,
})
const request = ref({
searchApi: mockApi,
addApi: commonApi,
editApi: commonApi,
})
function mockApi() {
return new Promise((resolve) => {
setTimeout(() => {
const data = [
{
id: 1,
name: 'Steven',
gender: 'male',
age: 22,
date: '2020-01-01',
time: ['2020-01-01', '2020-01-02'],
},
{
id: 2,
name: 'Helen',
gender: 'male',
age: 12,
date: '2012-01-01',
time: ['2020-01-01', '2020-01-02'],
},
{
id: 3,
name: 'Nancy',
gender: 'female',
age: 18,
date: '2018-01-01',
time: ['2020-01-01', '2020-01-02'],
},
{
id: 4,
name: 'Jack',
gender: 'male',
age: 28,
date: '2028-01-01',
time: ['2020-01-01', '2020-01-02'],
},
]
resolve({
data: {
page: 1,
pageSize: 10,
total: 4,
list: data.slice((pagination.value.page - 1) * pagination.value.pageSize, pagination.value.page * pagination.value.pageSize),
},
})
}, 100)
})
}
function commonApi(params: EditRequestApiParams<FormData, RowData>) {
console.log(JSON.stringify(params), 'commonApi params')
return new Promise((resolve) => {
setTimeout(() => {
resolve({
msg: 'success',
code: 200,
})
}, 100)
})
}
</script>
<template>
<z-crud
v-model:pagination="pagination"
v-model:data="tableData"
v-model:formData="formData"
v-model:loading="loading"
:columns="columns"
:options="options"
:search="searchFormConfig"
:add="addFormConfig"
:edit="editFormConfig"
:detail="false"
:request="request"
/>
</template>
z-crud详情相关属性
属性名 | 说明 | 类型 | 默认值 |
---|---|---|---|
detail | 详情配置 | boolean / object / ({ row, tableRef }) => void | true |
form | 查询、新增、编辑和查看表单属性配置 | object | — |
action | 操作项是否展示(内置的删除、编辑等按钮) | boolean | true |
edit | 编辑配置 | boolean / object | true |
add | 新增配置 | boolean / object | true |
delete | 删除配置 | boolean / ({ row, tableRef, getTableData }) => void / object | |
search | 查询配置 | boolean / object | true |
request | 接口配置 | object | — |
add和edit属性
属性名 | 说明 | 类型 | 默认值 |
---|---|---|---|
dialog | el-dialog 组件属性 | object | — |
rules | 表单验证规则 | object | — |
columns | 表单项 | array | — |
options | 表单选择项数据源 | object | — |
colon | 表单项冒号 | boolean | false |
align | flex 布局下的垂直排列方式 | top / middle /bottom | — |
label-position | 表单域标签的位置, 当设置为 left 或 right 时,则也需要设置 label-width 属性 | enum | right |
label-width | 标签的长度,例如 '50px' 。 作为 Form 直接子元素的 form-item 会继承该值。 可以使用 auto 。 | string / number | '' |
label-suffix | 表单域标签的后缀 | string | '' |
hide-required-asterisk | 是否隐藏必填字段标签旁边的红色星号。 | boolean | false |
require-asterisk-position | 星号的位置。 | left / right | left |
show-message | 是否显示校验错误信息 | boolean | true |
inline-message | 是否以行内形式展示校验信息 | boolean | false |
status-icon | 是否在输入框中显示校验结果反馈图标 | boolean | false |
validate-on-rule-change | 是否在 rules 属性改变后立即触发一次验证 | boolean | true |
size | 用于控制该表单内组件的尺寸 | large / default / small | — |
disabled | 是否禁用该表单内的所有组件。 如果设置为 true , 它将覆盖内部组件的 disabled 属性 | boolean | false |
scroll-to-error | 当校验失败时,滚动到第一个错误表单项 | boolean | false |
scroll-into-view-options | 当校验有失败结果时,滚动到第一个失败的表单项目 | object / boolean | — |
form属性
属性名 | 说明 | 类型 | 默认值 |
---|---|---|---|
rules | 表单验证规则 | object | — |
columns | 表单项 | array | — |
options | 表单选择项数据源 | object | — |
colon | 表单项冒号 | boolean | false |
align | flex 布局下的垂直排列方式 | top / middle /bottom | — |
label-position | 表单域标签的位置, 当设置为 left 或 right 时,则也需要设置 label-width 属性 | enum | right |
label-width | 标签的长度,例如 '50px' 。 作为 Form 直接子元素的 form-item 会继承该值。 可以使用 auto 。 | string / number | '' |
label-suffix | 表单域标签的后缀 | string | '' |
hide-required-asterisk | 是否隐藏必填字段标签旁边的红色星号。 | boolean | false |
require-asterisk-position | 星号的位置。 | left / right | left |
show-message | 是否显示校验错误信息 | boolean | true |
inline-message | 是否以行内形式展示校验信息 | boolean | false |
status-icon | 是否在输入框中显示校验结果反馈图标 | boolean | false |
validate-on-rule-change | 是否在 rules 属性改变后立即触发一次验证 | boolean | true |
size | 用于控制该表单内组件的尺寸 | large / default / small | — |
disabled | 是否禁用该表单内的所有组件。 如果设置为 true , 它将覆盖内部组件的 disabled 属性 | boolean | false |
scroll-to-error | 当校验失败时,滚动到第一个错误表单项 | boolean | false |
scroll-into-view-options | 当校验有失败结果时,滚动到第一个失败的表单项目 | object / boolean | — |
request属性
属性名 | 说明 | 类型 | 默认值 |
---|---|---|---|
searchApi | 查询接口 | (params: any) => promise | — |
submitApi | 编辑新增确认 | ({ [key: string]: any, row: any, type: 'add' / 'edit' / 'view', formData: any }) => promise | — |
deleteApi | 删除接口 | ({ [key: string]?: any, row?: any, selectionData?: any }) => promise | — |
addApi | 新增接口 | ({ type: 'add' / 'edit' / 'view', formData: any }) => promise | — |
editApi | 编辑接口 | ({ [key: string]: any, row: any, type: 'add' / 'edit' / 'view', formData: any }) => promise | — |
detailApi | 详情接口 | ({ [key: string]: any, row: any }) => promise | — |
alias | 数据路径自定义 | object | — |
beforeData | 表格数据接口调用前的回调 | Function | — |
afterData | 表格数据接口调用后的回调 | (res) => void | — |
searchFunc | 查询方法重写 | ({ params }) => any | — |
tableData | 表格数据自定义返回 | (res) => any | — |
z-crud新增编辑相关事件
事件名 | 说明 | 类型 |
---|---|---|
operate-submit | 弹窗确认 | ({ done, formRef, formData, type, confirmButtonLoading, row, invalidFields }) => void |
operate-cancel | 弹窗取消 | ({ done, formRef, formData, type, confirmButtonLoading, row }) => void |