Crud API
Integrates z-form and z-table components to implement CRUD functionality.
Table API
Configure searchApi, deleteApi, addApi, editApi in request to directly implement table data retrieval, data deletion, data creation and editing operations.
<!-- eslint-disable no-console -->
<script lang="ts" setup>
import { ref } from 'vue'
const columns = ref([
{
prop: 'name',
label: 'Name',
form: {
component: 'input',
label: 'Name',
field: 'name',
},
},
{
prop: 'gender',
label: 'Gender',
form: {
component: 'select',
label: 'Gender',
field: 'gender',
},
},
{
prop: 'age',
label: 'Age',
form: {
component: 'input',
label: 'Age',
field: 'age',
},
},
{
prop: 'time',
label: 'Date',
},
])
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(JSON.stringify(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>Table Data API Configuration
Configure the alias field in request to customize data paths, defaults to data.list and data.total.
<!-- 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([
{
prop: 'name',
label: 'Name',
form: {
component: 'input',
label: 'Name',
field: 'name',
},
},
{
prop: 'gender',
label: 'Gender',
form: {
component: 'select',
label: 'Gender',
field: 'gender',
},
},
{
prop: 'age',
label: 'Age',
form: {
component: 'input',
label: 'Age',
field: 'age',
},
},
{
prop: 'time',
label: 'Date',
},
])
const request = ref({
searchApi: getTableData,
deleteApi: commonApi,
submitApi: commonApi,
detailApi,
alias: {
list: 'result.data',
total: 'result.all',
},
})
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({
result: {
page: 1,
pageSize: 2,
all: 4,
data: data.slice((pagination.value.page - 1) * pagination.value.pageSize, pagination.value.page * pagination.value.pageSize),
},
})
}, 100)
})
}
function commonApi(params: any) {
console.log(JSON.stringify(params), 'commonApi params')
return new Promise((resolve) => {
setTimeout(() => {
resolve({
msg: 'success',
code: 200,
})
}, 100)
})
}
function detailApi({ id, row }: { id: number, row: RowData }) {
console.log(id, row, 'detailApi params')
return new Promise((resolve) => {
setTimeout(() => {
resolve({
data: {
id: 3,
name: 'Nancy',
gender: 'female',
age: 18,
time: '2018-01-01',
},
})
}, 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>Supports passing functions for custom returns.
<!-- eslint-disable no-console -->
<script lang="ts" setup>
import { ref } from 'vue'
interface RowData {
id: number
name: string
gender: string
age: number
time: string
}
interface GetTableDataRes { result: { page: number, pageSize: number, data: RowData[], all: number } }
const columns = ref([
{
prop: 'name',
label: 'Name',
form: {
component: 'input',
label: 'Name',
field: 'name',
},
},
{
prop: 'gender',
label: 'Gender',
form: {
component: 'select',
label: 'Gender',
field: 'gender',
},
},
{
prop: 'age',
label: 'Age',
form: {
component: 'input',
label: 'Age',
field: 'age',
},
},
{
prop: 'time',
label: 'Date',
},
])
const request = ref({
searchApi: getTableData,
deleteApi: commonApi,
submitApi: commonApi,
alias: {
list: (res: GetTableDataRes) => res.result.data,
total: (res: GetTableDataRes) => res.result.all,
},
})
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): 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({
result: {
page: 1,
pageSize: 2,
all: 4,
data: data.slice((pagination.value.page - 1) * pagination.value.pageSize, pagination.value.page * pagination.value.pageSize),
},
})
}, 100)
})
}
function commonApi(params: any) {
console.log(JSON.stringify(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>Custom Table Data Method
Supports customizing table data method through request.searchFunc.
<!-- eslint-disable no-console -->
<script lang="ts" setup>
import { ref } from 'vue'
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([
{
prop: 'name',
label: 'Name',
form: {
component: 'input',
label: 'Name',
field: 'name',
},
},
{
prop: 'gender',
label: 'Gender',
form: {
component: 'select',
label: 'Gender',
field: 'gender',
},
},
{
prop: 'age',
label: 'Age',
form: {
component: 'input',
label: 'Age',
field: 'age',
},
},
{
prop: 'time',
label: 'Date',
},
])
const tableData = ref<RowData[]>([])
const pagination = ref({
page: 1,
pageSize: 2,
total: 0,
})
const loading = ref(false)
const formData = ref({})
const request = ref({
deleteApi: commonApi,
submitApi: commonApi,
searchFunc: async ({ params }: any) => {
loading.value = true
try {
console.log(params, 'searchFunc params')
const res = await getData(params)
tableData.value = res.data.list
pagination.value.total = res.data.total
}
catch {
}
loading.value = false
},
})
const options = {
gender: [{ label: 'male', value: 'male' }, { label: 'female', value: 'female' }],
}
function getData(params: any): Promise<GetTableDataRes> {
console.log(params, '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(JSON.stringify(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>Table Data Processing
Supports secondary processing of table data through request.tableData.
<!-- 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([
{
prop: 'name',
label: 'Name',
form: {
component: 'input',
label: 'Name',
field: 'name',
},
},
{
prop: 'gender',
label: 'Gender',
form: {
component: 'select',
label: 'Gender',
field: 'gender',
},
},
{
prop: 'age',
label: 'Age',
form: {
component: 'input',
label: 'Age',
field: 'age',
},
},
{
prop: 'time',
label: 'Date',
},
])
const tableData = ref([])
const pagination = ref({
page: 1,
pageSize: 2,
total: 0,
})
const loading = ref(false)
const formData = ref({})
const request = ref({
searchApi: getData,
deleteApi: commonApi,
submitApi: commonApi,
tableData: (data: RowData[]) => {
return data.map((item, index) => ({
...item,
name: item.name + index,
}))
},
})
const options = {
gender: [{ label: 'male', value: 'male' }, { label: 'female', value: 'female' }],
}
function getData() {
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(JSON.stringify(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>Callbacks
Supports doing things before and after getting table data through request.beforeData and request.afterData.
<!-- eslint-disable no-console -->
<script lang="ts" setup>
import { ref } from 'vue'
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([
{
prop: 'name',
label: 'Name',
form: {
component: 'input',
label: 'Name',
field: 'name',
},
},
{
prop: 'gender',
label: 'Gender',
form: {
component: 'select',
label: 'Gender',
field: 'gender',
},
},
{
prop: 'age',
label: 'Age',
form: {
component: 'input',
label: 'Age',
field: 'age',
},
},
{
prop: 'time',
label: 'Date',
},
])
const tableData = ref([])
const pagination = ref({
page: 1,
pageSize: 2,
total: 0,
})
const loading = ref(false)
const formData = ref({})
const request = ref({
searchApi: getData,
deleteApi: commonApi,
submitApi: commonApi,
beforeData: async () => {
await delay(100)
console.log('beforeData')
},
afterData: (res: GetTableDataRes) => {
console.log(res, 'afterData')
},
})
const options = {
gender: [{ label: 'male', value: 'male' }, { label: 'female', value: 'female' }],
}
function delay(time: number) {
return new Promise((resolve) => {
setTimeout(resolve, time)
})
}
function getData(): Promise<GetTableDataRes> {
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(JSON.stringify(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>Internal Methods
Supports calling the getTableData method again from outside the table.
<!-- eslint-disable no-console -->
<script lang="ts" setup>
import { ref } from 'vue'
const columns = ref([
{
prop: 'name',
label: 'Name',
form: {
component: 'input',
label: 'Name',
field: 'name',
},
},
{
prop: 'gender',
label: 'Gender',
form: {
component: 'select',
label: 'Gender',
field: 'gender',
},
},
{
prop: 'age',
label: 'Age',
form: {
component: 'input',
label: 'Age',
field: 'age',
},
},
{
prop: 'time',
label: 'Date',
},
])
const tableData = ref([])
const pagination = ref({
page: 1,
pageSize: 2,
total: 0,
})
const loading = ref(false)
const formData = ref({})
const request = ref({
searchApi: getData,
deleteApi: commonApi,
submitApi: commonApi,
})
const crud = ref()
const options = {
gender: [{ label: 'male', value: 'male' }, { label: 'female', value: 'female' }],
}
function getData() {
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(JSON.stringify(params), 'commonApi params')
return new Promise((resolve) => {
setTimeout(() => {
resolve({
msg: 'success',
code: 200,
})
}, 100)
})
}
function handleClick() {
crud.value.getTableData()
}
</script>
<template>
<el-button @click="handleClick">
click
</el-button>
<z-crud
ref="crud"
v-model:formData="formData"
v-model:data="tableData"
v-model:pagination="pagination"
v-model:loading="loading"
:options="options"
:columns="columns"
:request="request"
/>
</template>Custom Operations
If you need custom operations, you can use events like refresh, search, reset, submit, delete to implement refresh, query, reset and delete operations.
<!-- eslint-disable no-console -->
<script lang="ts" setup>
import { ref } from 'vue'
import type { CrudDeleteDialogConfirmParams, Pagination } 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([
{
prop: 'name',
label: 'Name',
form: {
component: 'input',
label: 'Name',
field: 'name',
required: true,
},
},
{
prop: 'gender',
label: 'Gender',
form: {
component: 'select',
label: 'Gender',
field: 'gender',
},
},
{
prop: 'age',
label: 'Age',
form: {
component: 'input',
label: 'Age',
field: 'age',
},
},
{
prop: 'time',
label: 'Date',
},
])
const tableData = ref<RowData[]>([])
const pagination = ref({
page: 1,
pageSize: 2,
total: 0,
})
const loading = ref(false)
const formData = ref({})
const dialog = ref({
confirmButtonLoading: false,
})
const options = {
gender: [{ label: 'male', value: 'male' }, { label: 'female', value: 'female' }],
}
function getData(params: any): Promise<GetTableDataRes> {
console.log(params, '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(JSON.stringify(params), 'commonApi params')
return new Promise((resolve) => {
setTimeout(() => {
resolve({
msg: 'success',
code: 200,
})
}, 100)
})
}
async function getTableData() {
loading.value = true
try {
const params = {
...pagination.value,
...formData.value,
}
const res = await getData(params)
tableData.value = res.data.list
pagination.value.total = res.data.total
}
catch (error) {
console.log(error)
}
loading.value = false
}
function handleRefresh(val: Pagination) {
pagination.value.page = val.page!
pagination.value.pageSize = val.pageSize!
getTableData()
}
function handleSearch() {
pagination.value.page = 1
getTableData()
}
function handleDelete() {
window.ZDialogTip({
type: 'warning',
message: 'Are you sure you want to delete this record?',
title: 'Warning',
onConfirm: ({ done, confirmButtonLoading }: CrudDeleteDialogConfirmParams<RowData>) => {
confirmButtonLoading.value = true
done()
confirmButtonLoading.value = false
},
})
}
async function handleSubmit({ formData, type, rowData, formRef, done, isValid }: { formData: any, type: 'add' | 'edit', rowData: RowData, formRef: any, done: () => void, isValid: boolean }) {
if (isValid) {
dialog.value.confirmButtonLoading = true
try {
const params = {
...formData,
}
console.log(params, rowData, formRef, 'params')
if (type === 'edit')
await commonApi({ ...params, id: rowData.id })
else
await commonApi(params)
dialog.value.confirmButtonLoading = false
done()
getTableData()
}
catch {
}
dialog.value.confirmButtonLoading = false
}
}
getTableData()
</script>
<template>
<z-crud
v-model:formData="formData"
v-model:data="tableData"
v-model:pagination="pagination"
v-model:loading="loading"
:options="options"
:columns="columns"
:dialog="dialog"
@refresh="handleRefresh"
@reset="handleSearch"
@search="handleSearch"
@submit="handleSubmit"
@delete="handleDelete"
/>
</template>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 | — |
alias Attributes
| Attribute | Description | Type | Default |
|---|---|---|---|
| list | Table data path | string / (res) => array | data.list |
| total | Table data total path | string / (res) => number | data.total |