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 |