Crud Create/Update
z-crud component create and edit form functionality introduction.
Basic Usage
Configure add or edit fields in column to implement create or edit form configuration.
<!-- 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: 'Name',
add: {
component: 'input',
field: 'name',
label: 'Name',
required: true,
},
edit: {
component: 'input',
field: 'name',
label: 'Name',
required: true,
},
},
{
prop: 'gender',
label: 'Gender',
add: {
component: 'select',
field: 'gender',
label: 'Gender',
},
edit: {
component: 'select',
field: 'gender',
label: 'Gender',
},
},
{
prop: 'age',
label: 'Age',
add: {
component: 'el-date-picker',
field: 'time',
label: 'Date',
fieldProps: {
type: 'daterange',
startPlaceholder: 'Start date',
endPlaceholder: 'End date',
},
},
edit: {
component: 'el-date-picker',
field: 'time',
label: 'Date',
fieldProps: {
type: 'daterange',
startPlaceholder: 'Start date',
endPlaceholder: 'End date',
},
},
},
{
prop: 'date',
label: 'Date',
},
])
const searchFormConfig = ref({
labelWith: '80px',
columns: [
{
component: 'input',
label: 'Name',
field: 'name',
},
{
component: 'select',
label: 'Gender',
field: 'gender',
},
{
component: 'input',
label: 'Age',
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>Configure columns field in add and edit to implement create and edit form configuration.
<!-- 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: 'Name',
},
{
prop: 'gender',
label: 'Gender',
},
{
prop: 'age',
label: 'Age',
},
{
prop: 'date',
label: 'Date',
},
])
const searchFormConfig = ref({
labelWith: '80px',
columns: [
{
component: 'input',
label: 'Name',
field: 'name',
},
{
component: 'select',
label: 'Gender',
field: 'gender',
},
{
component: 'input',
label: 'Age',
field: 'age',
},
],
})
const addFormConfig = ref({
columns: [
{
component: 'input',
label: 'Name (create)',
field: 'name',
},
{
component: 'select',
label: 'Gender',
field: 'gender',
},
{
component: 'input',
label: 'Age',
field: 'age',
},
],
})
const editFormConfig = ref({
columns: [
{
component: 'input',
label: 'Name (edit)',
field: 'name',
},
{
component: 'select',
label: 'Gender',
field: 'gender',
},
{
component: 'input',
label: 'Age',
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>Configure columns field in form to implement both create and edit form configuration, but it will also configure query and detail information at the same time. You can configure search and detail as false to disable them.
<!-- 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: 'Name',
},
{
prop: 'gender',
label: 'Gender',
},
{
prop: 'age',
label: 'Age',
},
{
prop: 'date',
label: 'Date',
},
])
const searchFormConfig = ref({
labelWith: '80px',
columns: [
{
component: 'input',
label: 'Name',
field: 'name',
},
{
component: 'select',
label: 'Gender',
field: 'gender',
},
{
component: 'input',
label: 'Age',
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: 'Name',
required: true,
},
{
component: 'select',
field: 'gender',
label: 'Gender',
},
{
component: 'el-date-picker',
field: 'time',
label: 'Date',
fieldProps: {
type: 'daterange',
startPlaceholder: 'Start date',
endPlaceholder: 'End date',
},
},
],
})
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>Configure form field in column items to implement create and edit form configuration, but it will also configure query form at the same time. You can set search as false to disable it.
<!-- 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: 'Name',
form: {
component: 'input',
field: 'name',
label: 'Name',
required: true,
},
},
{
prop: 'gender',
label: 'Gender',
form: {
component: 'select',
field: 'gender',
label: 'Gender',
},
},
{
prop: 'age',
label: 'Age',
form: {
component: 'el-date-picker',
field: 'time',
label: 'Date',
fieldProps: {
type: 'daterange',
startPlaceholder: 'Start date',
endPlaceholder: 'End date',
},
},
search: false,
},
{
prop: 'date',
label: 'Date',
},
])
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>Confirm API
Configure addApi and editApi in request.
editApi will pass an additional rowKey parameter, default is 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: 'Name',
form: {
component: 'input',
field: 'name',
label: 'Name',
required: true,
},
},
{
prop: 'gender',
label: 'Gender',
form: {
component: 'select',
field: 'gender',
label: 'Gender',
},
},
{
prop: 'age',
label: 'Age',
form: {
component: 'el-date-picker',
field: 'time',
label: 'Date',
fieldProps: {
type: 'daterange',
startPlaceholder: 'Start date',
endPlaceholder: 'End date',
},
},
search: false,
},
{
prop: 'date',
label: 'Date',
},
])
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>If create and edit APIs are the same, you can configure submitApi. When editing, it will also include 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: 'Name',
form: {
component: 'input',
field: 'name',
label: 'Name',
required: true,
},
},
{
prop: 'gender',
label: 'Gender',
form: {
component: 'select',
field: 'gender',
label: 'Gender',
},
},
{
prop: 'age',
label: 'Age',
form: {
component: 'el-date-picker',
field: 'time',
label: 'Date',
fieldProps: {
type: 'daterange',
startPlaceholder: 'Start date',
endPlaceholder: 'End date',
},
},
search: false,
},
{
prop: 'date',
label: 'Date',
},
])
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>Edit Detail Data
Configure detailApi in request to get default data for edit dialog from API.
<!-- 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: 'Name',
form: {
component: 'input',
field: 'name',
label: 'Name',
required: true,
},
},
{
prop: 'gender',
label: 'Gender',
form: {
component: 'select',
field: 'gender',
label: 'Gender',
},
},
{
prop: 'age',
label: 'Age',
form: {
component: 'el-date-picker',
field: 'time',
label: 'Date',
fieldProps: {
type: 'daterange',
startPlaceholder: 'Start date',
endPlaceholder: 'End date',
},
},
search: false,
},
{
prop: 'date',
label: 'Date',
},
])
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>Detail Data Processing
If you need to process the detail data returned by the API, you can configure request.alias.detail. Passing a function supports custom detail data, passing a string supports custom data path.
<!-- 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: 'Name',
form: {
component: 'input',
field: 'name',
label: 'Name',
required: true,
},
},
{
prop: 'gender',
label: 'Gender',
form: {
component: 'select',
field: 'gender',
label: 'Gender',
},
},
{
prop: 'age',
label: 'Age',
form: {
component: 'el-date-picker',
field: 'time',
label: 'Date',
fieldProps: {
type: 'daterange',
startPlaceholder: 'Start date',
endPlaceholder: 'End date',
},
},
search: false,
},
{
prop: 'date',
label: 'Date',
},
])
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>Custom Confirmation
When request doesn't configure submitApi, addApi and editApi, there will be operate-submit event.
<!-- 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: 'Name',
form: {
component: 'input',
field: 'name',
label: 'Name',
required: true,
},
},
{
prop: 'gender',
label: 'Gender',
form: {
component: 'select',
field: 'gender',
label: 'Gender',
},
},
{
prop: 'age',
label: 'Age',
form: {
component: 'el-date-picker',
field: 'time',
label: 'Date',
fieldProps: {
type: 'daterange',
startPlaceholder: 'Start date',
endPlaceholder: 'End date',
},
},
search: false,
},
{
prop: 'date',
label: 'Date',
},
])
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>Custom Cancel
operate-cancel custom cancel event. If the component is not configured, clicking cancel will close by default.
<!-- 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: 'Name',
form: {
component: 'input',
field: 'name',
label: 'Name',
required: true,
},
},
{
prop: 'gender',
label: 'Gender',
form: {
component: 'select',
field: 'gender',
label: 'Gender',
},
},
{
prop: 'age',
label: 'Age',
form: {
component: 'el-date-picker',
field: 'time',
label: 'Date',
fieldProps: {
type: 'daterange',
startPlaceholder: 'Start date',
endPlaceholder: 'End date',
},
},
search: false,
},
{
prop: 'date',
label: 'Date',
},
])
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>Form Properties
Use add and edit objects to configure create and edit form properties. The form property can uniformly configure create and 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: 'Name',
add: {
component: 'input',
field: 'name',
label: 'Name',
required: true,
},
edit: {
component: 'input',
field: 'name',
label: 'Name',
required: true,
},
},
{
prop: 'gender',
label: 'Gender',
add: {
component: 'select',
field: 'gender',
label: 'Gender',
},
edit: {
component: 'select',
field: 'gender',
label: 'Gender',
},
},
{
prop: 'age',
label: 'Age',
add: {
component: 'el-date-picker',
field: 'time',
label: 'Date',
fieldProps: {
type: 'daterange',
startPlaceholder: 'Start date',
endPlaceholder: 'End date',
},
},
edit: {
component: 'el-date-picker',
field: 'time',
label: 'Date',
fieldProps: {
type: 'daterange',
startPlaceholder: 'Start date',
endPlaceholder: 'End date',
},
},
},
{
prop: 'date',
label: 'Date',
},
])
const searchFormConfig = ref({
labelWith: '80px',
columns: [
{
component: 'input',
label: 'Name',
field: 'name',
},
{
component: 'select',
label: 'Gender',
field: 'gender',
},
{
component: 'input',
label: 'Age',
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 Properties
You can use the dialog object to uniformly configure create and edit dialog properties, or use add.dialog and edit.dialog to configure dialog properties separately.
<!-- 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: 'Name',
add: {
component: 'input',
field: 'name',
label: 'Name',
required: true,
},
edit: {
component: 'input',
field: 'name',
label: 'Name',
required: true,
},
},
{
prop: 'gender',
label: 'Gender',
add: {
component: 'select',
field: 'gender',
label: 'Gender',
},
edit: {
component: 'select',
field: 'gender',
label: 'Gender',
},
},
{
prop: 'age',
label: 'Age',
add: {
component: 'el-date-picker',
field: 'time',
label: 'Date',
fieldProps: {
type: 'daterange',
startPlaceholder: 'Start date',
endPlaceholder: 'End date',
},
},
edit: {
component: 'el-date-picker',
field: 'time',
label: 'Date',
fieldProps: {
type: 'daterange',
startPlaceholder: 'Start date',
endPlaceholder: 'End date',
},
},
},
{
prop: 'date',
label: 'Date',
},
])
const searchFormConfig = ref({
labelWith: '80px',
columns: [
{
component: 'input',
label: 'Name',
field: 'name',
},
{
component: 'select',
label: 'Gender',
field: 'gender',
},
{
component: 'input',
label: 'Age',
field: 'age',
},
],
})
const addFormConfig = ref({
labelWidth: '120px',
labelPosition: 'top',
dialog: {
title: 'Create Dialog',
},
})
const editFormConfig = ref({
labelWidth: '80px',
labelPosition: 'left',
dialog: {
title: 'Edit Dialog',
},
})
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 Related Attributes
| Attribute | Description | Type | Default |
|---|---|---|---|
| detail | Detail configuration | boolean / object / ({ row, tableRef }) => void | true |
| form | Search, add, edit and view form attribute configuration | object | — |
| action | Whether to show action items (built-in delete, edit buttons) | boolean | true |
| edit | Edit configuration | boolean / object | true |
| add | Add configuration | boolean / object | true |
| delete | Delete configuration | boolean / ({ row, tableRef, getTableData }) => void / object | — |
| search | Search configuration | boolean / object | true |
| request | API configuration | object | — |
add and edit Attributes
| Attribute | Description | Type | Default |
|---|---|---|---|
| dialog | el-dialog component attributes | object | — |
| rules | Form validation rules | object | — |
| columns | Form items | array | — |
| options | Form option data source | object | — |
| colon | Form item colon | boolean | false |
| align | Vertical alignment under flex layout | top / middle /bottom | — |
| label-position | Position of form field labels. When set to left or right, you also need to set the label-width attribute | enum | right |
| label-width | Width of labels, e.g. '50px'. Form items that are direct children of Form will inherit this value. auto can be used. | string / number | '' |
| label-suffix | Suffix for form field labels | string | '' |
| hide-required-asterisk | Whether to hide the red asterisk next to required field labels. | boolean | false |
| require-asterisk-position | Position of asterisk. | left / right | left |
| show-message | Whether to show validation error messages | boolean | true |
| inline-message | Whether to display validation messages inline | boolean | false |
| status-icon | Whether to display validation result feedback icons in input boxes | boolean | false |
| validate-on-rule-change | Whether to trigger validation immediately after the rules attribute changes | boolean | true |
| size | Size for controlling components within this form | large / default / small | — |
| disabled | Whether to disable all components in this form. If set to true, it will override the disabled attribute of internal components | boolean | false |
| scroll-to-error | When validation fails, scroll to the first error form item | boolean | false |
| scroll-into-view-options | When validation has failed results, scroll to the first failed form item | object / boolean | — |
form Attributes
| Attribute | Description | Type | Default |
|---|---|---|---|
| rules | Form validation rules | object | — |
| columns | Form items | array | — |
| options | Form option data source | object | — |
| colon | Form item colon | boolean | false |
| align | Vertical alignment under flex layout | top / middle /bottom | — |
| label-position | Position of form field labels. When set to left or right, you also need to set the label-width attribute | enum | right |
| label-width | Width of labels, e.g. '50px'. Form items that are direct children of Form will inherit this value. auto can be used. | string / number | '' |
| label-suffix | Suffix for form field labels | string | '' |
| hide-required-asterisk | Whether to hide the red asterisk next to required field labels. | boolean | false |
| require-asterisk-position | Position of asterisk. | left / right | left |
| show-message | Whether to show validation error messages | boolean | true |
| inline-message | Whether to display validation messages inline | boolean | false |
| status-icon | Whether to display validation result feedback icons in input boxes | boolean | false |
| validate-on-rule-change | Whether to trigger validation immediately after the rules attribute changes | boolean | true |
| size | Size for controlling components within this form | large / default / small | — |
| disabled | Whether to disable all components in this form. If set to true, it will override the disabled attribute of internal components | boolean | false |
| scroll-to-error | When validation fails, scroll to the first error form item | boolean | false |
| scroll-into-view-options | When validation has failed results, scroll to the first failed form item | object / boolean | — |
request Attributes
| Attribute | Description | Type | Default |
|---|---|---|---|
| searchApi | Search API | (params: any) => promise | — |
| submitApi | Edit and create confirmation | ({ [key: string]: any, row: any, type: 'add' / 'edit' / 'view', formData: any }) => promise | — |
| deleteApi | Delete API | ({ [key: string]?: any, row?: any, selectionData?: any }) => promise | — |
| addApi | Create API | ({ type: 'add' / 'edit' / 'view', formData: any }) => promise | — |
| editApi | Edit API | ({ [key: string]: any, row: any, type: 'add' / 'edit' / 'view', formData: any }) => promise | — |
| detailApi | Detail API | ({ [key: string]: any, row: any }) => promise | — |
| alias | Custom data path | object | — |
| beforeData | Callback before table data API call | Function | — |
| afterData | Callback after table data API call | (res) => void | — |
| searchFunc | Search method override | ({ params }) => any | — |
| tableData | Custom table data return | (res) => any | — |
z-crud Create/Edit Related Events
| Event Name | Description | Type |
|---|---|---|
| operate-submit | Dialog confirm | ({ done, formRef, formData, type, confirmButtonLoading, row, invalidFields }) => void |
| operate-cancel | Dialog cancel | ({ done, formRef, formData, type, confirmButtonLoading, row }) => void |