Skip to content

Crud CRUD

z-crud component delete functionality introduction.

Basic Usage

Configure deleteApi field in request to call API for deletion. Parameter defaults to id, can also be configured through rowKey.

<!-- eslint-disable no-console -->
<script lang="ts" setup>
import { ref } from 'vue'
import type { DeleteRequestApiParams } from 'ideaz-element'

interface RowData {
  id: number
  name: string
  gender: string
  age: number
  time: string
}

const loading = ref(false)
const formData = ref({
  name: '',
  gender: '',
  age: '',
})
const tableData = ref([])

const columns = ref([
  {
    prop: 'name',
    label: 'Name',
    search: {
      component: 'input',
      label: 'Name',
      field: 'name',
    },
    add: {
      component: 'input',
      label: 'Name',
      field: 'name',
    },
  },
  {
    prop: 'gender',
    label: 'Gender',
    search: {
      component: 'select',
      label: 'Gender',
      field: 'gender',
    },
  },
  {
    prop: 'age',
    label: 'Age',
    search: {
      component: 'input',
      label: 'Age',
      field: 'age',
    },
  },
  {
    prop: 'time',
    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,
  deleteApi: deleteMockApi,
})

function mockApi() {
  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: 10,
          total: 4,
          list: data.slice((pagination.value.page - 1) * pagination.value.pageSize, pagination.value.page * pagination.value.pageSize),
        },
      })
    }, 100)
  })
}

function deleteMockApi(params: DeleteRequestApiParams<RowData>) {
  console.log(JSON.stringify(params), 'deleteMockApi params')
  return new Promise((resolve) => {
    setTimeout(() => {
      resolve({
        message: '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"
    :request="request"
    :detail="false"
    :add="false"
    :edit="false"
  />
</template>

Custom Delete

Configure operate-delete event to customize delete logic.

<!-- eslint-disable no-console -->
<script lang="ts" setup>
import { ref } from 'vue'
import type { CrudDeleteDialogConfirmParams, DeleteRequestApiParams } from 'ideaz-element'

interface RowData {
  id: number
  name: string
  gender: string
  age: number
  time: string
}

const loading = ref(false)
const formData = ref({
  name: '',
  gender: '',
  age: '',
})
const tableData = ref([])

const columns = ref([
  {
    prop: 'name',
    label: 'Name',
    search: {
      component: 'input',
      label: 'Name',
      field: 'name',
    },
    add: {
      component: 'input',
      label: 'Name',
      field: 'name',
    },
  },
  {
    prop: 'gender',
    label: 'Gender',
    search: {
      component: 'select',
      label: 'Gender',
      field: 'gender',
    },
  },
  {
    prop: 'age',
    label: 'Age',
    search: {
      component: 'input',
      label: 'Age',
      field: 'age',
    },
  },
  {
    prop: 'time',
    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,
          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: 10,
          total: 4,
          list: data.slice((pagination.value.page - 1) * pagination.value.pageSize, pagination.value.page * pagination.value.pageSize),
        },
      })
    }, 100)
  })
}

function deleteMockApi(params: DeleteRequestApiParams<RowData>) {
  console.log(params, 'params')
  return new Promise((resolve) => {
    setTimeout(() => {
      resolve({
        message: 'success',
        code: 200,
      })
    }, 100)
  })
}

function handleDelete({ row }: { row: RowData }) {
  window.ZDialogTip({
    type: 'warning',
    title: 'Notice',
    message: 'Are you sure you want to delete this record?',
    onConfirm: async ({ confirmButtonLoading, done }: CrudDeleteDialogConfirmParams<RowData>) => {
      confirmButtonLoading.value = true
      try {
        await deleteMockApi({ id: row.id })
        confirmButtonLoading.value = false
        done()
      }
      catch {}
      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"
    :request="request"
    :detail="false"
    :add="false"
    :edit="false"
    @operate-delete="handleDelete"
  />
</template>

Pass function to delete attribute to directly override built-in logic after delete click.

<!-- eslint-disable no-console -->
<script lang="ts" setup>
import { ref } from 'vue'
import type { CrudDeleteDialogConfirmParams } from 'ideaz-element'

interface RowData {
  id: number
  name: string
  gender: string
  age: number
  time: string
}

const loading = ref(false)
const formData = ref({
  name: '',
  gender: '',
  age: '',
})
const tableData = ref([])

const columns = ref([
  {
    prop: 'name',
    label: 'Name',
    search: {
      component: 'input',
      label: 'Name',
      field: 'name',
    },
    add: {
      component: 'input',
      label: 'Name',
      field: 'name',
    },
  },
  {
    prop: 'gender',
    label: 'Gender',
    search: {
      component: 'select',
      label: 'Gender',
      field: 'gender',
    },
  },
  {
    prop: 'age',
    label: 'Age',
    search: {
      component: 'input',
      label: 'Age',
      field: 'age',
    },
  },
  {
    prop: 'time',
    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,
          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: 10,
          total: 4,
          list: data.slice((pagination.value.page - 1) * pagination.value.pageSize, pagination.value.page * pagination.value.pageSize),
        },
      })
    }, 100)
  })
}

function deleteMockApi(params: { id: number }) {
  console.log(params, 'params')
  return new Promise((resolve) => {
    setTimeout(() => {
      resolve({
        message: 'success',
        code: 200,
      })
    }, 100)
  })
}

function handleDelete({ row, getTableData }: { row: RowData, getTableData: () => void }) {
  window.ZDialogTip({
    type: 'warning',
    title: 'Notice',
    message: 'Are you sure you want to delete this record?',
    onConfirm: async ({ confirmButtonLoading, done }: CrudDeleteDialogConfirmParams<RowData>) => {
      confirmButtonLoading.value = true
      try {
        await deleteMockApi({ id: row.id })
        confirmButtonLoading.value = false
        done()
        getTableData()
      }
      catch {}
      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"
    :request="request"
    :detail="false"
    :add="false"
    :edit="false"
    :delete="handleDelete"
  />
</template>

Pass object to delete attribute to directly customize delete dialog properties (see dialog documentation for property details).

<!-- eslint-disable unused-imports/no-unused-vars -->
<!-- eslint-disable no-console -->
<script lang="ts" setup>
import { h, reactive, ref } from 'vue'
import { ElMessage } from 'element-plus'
import type { CrudDeleteDialogConfirmParams, DeleteRequestApiParams } from 'ideaz-element'

interface RowData {
  id: number
  name: string
  gender: string
  age: number
  time: string
}

const loading = ref(false)
const formData = ref({
  name: '',
  gender: '',
  age: '',
})
const tableData = ref([])

const columns = ref([
  {
    prop: 'name',
    label: 'Name',
    search: {
      component: 'input',
      label: 'Name',
      field: 'name',
    },
    add: {
      component: 'input',
      label: 'Name',
      field: 'name',
    },
  },
  {
    prop: 'gender',
    label: 'Gender',
    search: {
      component: 'select',
      label: 'Gender',
      field: 'gender',
    },
  },
  {
    prop: 'age',
    label: 'Age',
    search: {
      component: 'input',
      label: 'Age',
      field: 'age',
    },
  },
  {
    prop: 'time',
    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,
  deleteApi: deleteMockApi,
})
const deleteConfig = reactive({
  message: ({ row }: { row: RowData }) => h('span', {}, `Delete ${row.name}?`),
  onConfirm: async ({ done, confirmButtonLoading, row, tableRef, getTableData }: CrudDeleteDialogConfirmParams<RowData>) => {
    confirmButtonLoading.value = true
    try {
      await deleteMockApi({ id: row?.id })
      ElMessage.success('Deleted successfully')
      confirmButtonLoading.value = false
      done()
      getTableData()
    }
    catch (error) {

    }
    confirmButtonLoading.value = false
  },
})

function mockApi() {
  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: 10,
          total: 4,
          list: data.slice((pagination.value.page - 1) * pagination.value.pageSize, pagination.value.page * pagination.value.pageSize),
        },
      })
    }, 100)
  })
}

function deleteMockApi(params: DeleteRequestApiParams<RowData>) {
  console.log(params, 'params')
  return new Promise((resolve) => {
    setTimeout(() => {
      resolve({
        message: '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"
    :request="request"
    :delete="deleteConfig"
    :detail="false"
    :add="false"
    :edit="false"
  />
</template>

Multi-select Delete

Combining checkbox and delete functionality, the component will have built-in features like el-alert and batch delete.

<!-- eslint-disable no-console -->
<script lang="ts" setup>
import { ref } from 'vue'
import type { DeleteRequestApiParams } from 'ideaz-element'

interface RowData {
  id: number
  name: string
  gender: string
  age: number
  time: string
}

const loading = ref(false)
const formData = ref({
  name: '',
  gender: '',
  age: '',
})
const tableData = ref([])

const columns = ref([
  {
    type: 'selection',
    reserveSelection: true,
  },
  {
    prop: 'name',
    label: 'Name',
    search: {
      component: 'input',
      label: 'Name',
      field: 'name',
    },
    add: {
      component: 'input',
      label: 'Name',
      field: 'name',
    },
  },
  {
    prop: 'gender',
    label: 'Gender',
    search: {
      component: 'select',
      label: 'Gender',
      field: 'gender',
    },
  },
  {
    prop: 'age',
    label: 'Age',
    search: {
      component: 'input',
      label: 'Age',
      field: 'age',
    },
  },
  {
    prop: 'time',
    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,
  deleteApi: deleteMockApi,
})

function mockApi() {
  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: 10,
          total: 4,
          list: data.slice((pagination.value.page - 1) * pagination.value.pageSize, pagination.value.page * pagination.value.pageSize),
        },
      })
    }, 100)
  })
}

function deleteMockApi(params: DeleteRequestApiParams<RowData>) {
  console.log(JSON.stringify(params), 'deleteMockApi params')
  return new Promise((resolve) => {
    setTimeout(() => {
      resolve({
        message: '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"
    :request="request"
    :detail="false"
    :add="false"
    :edit="false"
    row-key="id"
  />
</template>

Customize multi-select delete dialog content.

<!-- eslint-disable unused-imports/no-unused-vars -->
<!-- eslint-disable no-console -->
<script lang="ts" setup>
import { h, reactive, ref } from 'vue'
import { ElMessage } from 'element-plus'
import type { CrudDeleteDialogConfirmParams, DeleteRequestApiParams } from 'ideaz-element'

interface RowData {
  id: number
  name: string
  gender: string
  age: number
  time: string
}

const loading = ref(false)
const formData = ref({
  name: '',
  gender: '',
  age: '',
})
const tableData = ref([])

const columns = ref([
  {
    type: 'selection',
    reserveSelection: true,
  },
  {
    prop: 'name',
    label: 'Name',
    search: {
      component: 'input',
      label: 'Name',
      field: 'name',
    },
    add: {
      component: 'input',
      label: 'Name',
      field: 'name',
    },
  },
  {
    prop: 'gender',
    label: 'Gender',
    search: {
      component: 'select',
      label: 'Gender',
      field: 'gender',
    },
  },
  {
    prop: 'age',
    label: 'Age',
    search: {
      component: 'input',
      label: 'Age',
      field: 'age',
    },
  },
  {
    prop: 'time',
    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,
  deleteApi: deleteMockApi,
})
const deleteConfig = reactive({
  message: ({ selectionData }: { selectionData: RowData[] }) => h('span', {}, `Delete these ${selectionData.length} records?`),
  onConfirm: async ({ done, confirmButtonLoading, selectionData, tableRef, getTableData }: CrudDeleteDialogConfirmParams<RowData>) => {
    confirmButtonLoading.value = true
    try {
      await deleteMockApi({ id: selectionData?.map(item => item.id) })
      ElMessage.success('Deleted successfully')
      confirmButtonLoading.value = false
      tableRef.clearSelection()
      done()
      getTableData()
    }
    catch (error) {

    }
    confirmButtonLoading.value = false
  },
})

function mockApi() {
  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: 10,
          total: 4,
          list: data.slice((pagination.value.page - 1) * pagination.value.pageSize, pagination.value.page * pagination.value.pageSize),
        },
      })
    }, 100)
  })
}

function deleteMockApi(params: DeleteRequestApiParams<RowData>) {
  console.log(params, 'params')
  return new Promise((resolve) => {
    setTimeout(() => {
      resolve({
        message: '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"
    :request="request"
    :delete="deleteConfig"
    :detail="false"
    :add="false"
    :edit="false"
    row-key="id"
  />
</template>

Alert Configuration

Pass alert object to configure el-alert component attributes.

<!-- eslint-disable no-console -->
<script lang="ts" setup>
import { ref } from 'vue'
import type { DeleteRequestApiParams } from 'ideaz-element'

interface RowData {
  id: number
  name: string
  gender: string
  age: number
  time: string
}

const loading = ref(false)
const formData = ref({
  name: '',
  gender: '',
  age: '',
})
const tableData = ref([])

const columns = ref([
  {
    type: 'selection',
    reserveSelection: true,
  },
  {
    prop: 'name',
    label: 'Name',
    search: {
      component: 'input',
      label: 'Name',
      field: 'name',
    },
    add: {
      component: 'input',
      label: 'Name',
      field: 'name',
    },
  },
  {
    prop: 'gender',
    label: 'Gender',
    search: {
      component: 'select',
      label: 'Gender',
      field: 'gender',
    },
  },
  {
    prop: 'age',
    label: 'Age',
    search: {
      component: 'input',
      label: 'Age',
      field: 'age',
    },
  },
  {
    prop: 'time',
    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,
  deleteApi: deleteMockApi,
})

function mockApi() {
  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: 10,
          total: 4,
          list: data.slice((pagination.value.page - 1) * pagination.value.pageSize, pagination.value.page * pagination.value.pageSize),
        },
      })
    }, 100)
  })
}

function deleteMockApi(params: DeleteRequestApiParams<RowData>) {
  console.log(JSON.stringify(params), 'deleteMockApi params')
  return new Promise((resolve) => {
    setTimeout(() => {
      resolve({
        message: '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"
    :request="request"
    :detail="false"
    :add="false"
    :edit="false"
    :alert="{ type: 'warning', description: 'description' }"
    row-key="id"
  />
</template>

Custom Alert

If you need to customize alert content, alert can directly pass render function. If no alert is needed, you can pass false.

<!-- eslint-disable no-console -->
<script lang="ts" setup>
import { h, ref } from 'vue'
import type { DeleteRequestApiParams } from 'ideaz-element'

interface RowData {
  id: number
  name: string
  gender: string
  age: number
  time: string
}

const loading = ref(false)
const formData = ref({
  name: '',
  gender: '',
  age: '',
})
const tableData = ref([])

const columns = ref([
  {
    type: 'selection',
    reserveSelection: true,
  },
  {
    prop: 'name',
    label: 'Name',
    search: {
      component: 'input',
      label: 'Name',
      field: 'name',
    },
    add: {
      component: 'input',
      label: 'Name',
      field: 'name',
    },
  },
  {
    prop: 'gender',
    label: 'Gender',
    search: {
      component: 'select',
      label: 'Gender',
      field: 'gender',
    },
  },
  {
    prop: 'age',
    label: 'Age',
    search: {
      component: 'input',
      label: 'Age',
      field: 'age',
    },
  },
  {
    prop: 'time',
    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,
  deleteApi: deleteMockApi,
})

function mockApi() {
  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: 10,
          total: 4,
          list: data.slice((pagination.value.page - 1) * pagination.value.pageSize, pagination.value.page * pagination.value.pageSize),
        },
      })
    }, 100)
  })
}

function deleteMockApi(params: DeleteRequestApiParams<RowData>) {
  console.log(JSON.stringify(params), 'deleteMockApi params')
  return new Promise((resolve) => {
    setTimeout(() => {
      resolve({
        message: 'success',
        code: 200,
      })
    }, 100)
  })
}

function renderAlert(selectionData: RowData[]) {
  return h('span', `Selected ${selectionData.length} items`)
}
</script>

<template>
  <z-crud
    v-model:pagination="pagination"
    v-model:data="tableData"
    v-model:formData="formData"
    v-model:loading="loading"
    :columns="columns"
    :options="options"
    :request="request"
    :detail="false"
    :add="false"
    :edit="false"
    :alert="renderAlert"
    row-key="id"
  />
</template>

Custom alert content can also use alert slot.

<!-- eslint-disable no-console -->
<script lang="ts" setup>
import { ref } from 'vue'
import type { DeleteRequestApiParams } from 'ideaz-element'

interface RowData {
  id: number
  name: string
  gender: string
  age: number
  time: string
}

const loading = ref(false)
const formData = ref({
  name: '',
  gender: '',
  age: '',
})
const tableData = ref([])

const columns = ref([
  {
    type: 'selection',
    reserveSelection: true,
  },
  {
    prop: 'name',
    label: 'Name',
    search: {
      component: 'input',
      label: 'Name',
      field: 'name',
    },
    add: {
      component: 'input',
      label: 'Name',
      field: 'name',
    },
  },
  {
    prop: 'gender',
    label: 'Gender',
    search: {
      component: 'select',
      label: 'Gender',
      field: 'gender',
    },
  },
  {
    prop: 'age',
    label: 'Age',
    search: {
      component: 'input',
      label: 'Age',
      field: 'age',
    },
  },
  {
    prop: 'time',
    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,
  deleteApi: deleteMockApi,
})

function mockApi() {
  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: 10,
          total: 4,
          list: data.slice((pagination.value.page - 1) * pagination.value.pageSize, pagination.value.page * pagination.value.pageSize),
        },
      })
    }, 100)
  })
}

function deleteMockApi(params: DeleteRequestApiParams<RowData>) {
  console.log(JSON.stringify(params), 'deleteMockApi params')
  return new Promise((resolve) => {
    setTimeout(() => {
      resolve({
        message: '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"
    :request="request"
    :detail="false"
    :add="false"
    :edit="false"
    row-key="id"
  >
    <template #alert="{ selectionData }">
      Selected {{ selectionData.length }} items
    </template>
  </z-crud>
</template>

alert.title and alert.description support passing render functions for customization.

<!-- eslint-disable no-console -->
<script lang="ts" setup>
import { h, ref } from 'vue'
import type { DeleteRequestApiParams } from 'ideaz-element'

interface RowData {
  id: number
  name: string
  gender: string
  age: number
  time: string
}

const loading = ref(false)
const formData = ref({
  name: '',
  gender: '',
  age: '',
})
const tableData = ref([])

const columns = ref([
  {
    type: 'selection',
    reserveSelection: true,
  },
  {
    prop: 'name',
    label: 'Name',
    search: {
      component: 'input',
      label: 'Name',
      field: 'name',
    },
    add: {
      component: 'input',
      label: 'Name',
      field: 'name',
    },
  },
  {
    prop: 'gender',
    label: 'Gender',
    search: {
      component: 'select',
      label: 'Gender',
      field: 'gender',
    },
  },
  {
    prop: 'age',
    label: 'Age',
    search: {
      component: 'input',
      label: 'Age',
      field: 'age',
    },
  },
  {
    prop: 'time',
    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,
  deleteApi: deleteMockApi,
})
const alertConfig = ref({
  title: (selectionData: RowData[]) => h('span', `Selected ${selectionData.length} items`),
  description: () => h('span', 'description'),
})

function mockApi() {
  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: 10,
          total: 4,
          list: data.slice((pagination.value.page - 1) * pagination.value.pageSize, pagination.value.page * pagination.value.pageSize),
        },
      })
    }, 100)
  })
}

function deleteMockApi(params: DeleteRequestApiParams<RowData>) {
  console.log(JSON.stringify(params), 'commonApi params')
  return new Promise((resolve) => {
    setTimeout(() => {
      resolve({
        message: '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"
    :request="request"
    :detail="false"
    :add="false"
    :edit="false"
    :alert="alertConfig"
    row-key="id"
  />
</template>
AttributeDescriptionTypeDefault
deleteDelete configurationboolean / ({ row, tableRef, getTableData }) => void / objecttrue
actionWhether to show action items (built-in delete, edit buttons)booleantrue
editEdit configurationboolean / objecttrue
addAdd configurationboolean / objecttrue
detailDetail configurationboolean / object / ({ row, tableRef }) => voidtrue
searchSearch configurationboolean / object
alertFixed selected data alertobject / booleantrue
requestAPI configurationobject

request Attributes

AttributeDescriptionTypeDefault
searchApiSearch API(params: any) => promise
submitApiEdit and create confirmation({ [key: string]: any, row: any, type: 'add' / 'edit' / 'view', formData: any }) => promise
deleteApiDelete API({ [key: string]?: any, row?: any, selectionData?: any }) => promise
addApiCreate API({ type: 'add' / 'edit' / 'view', formData: any }) => promise
editApiEdit API({ [key: string]: any, row: any, type: 'add' / 'edit' / 'view', formData: any }) => promise
detailApiDetail API({ [key: string]: any, row: any }) => promise
aliasCustom data pathobject
beforeDataCallback before table data API callFunction
afterDataCallback after table data API call(res) => void
searchFuncSearch method override({ params }) => any
tableDataCustom table data return(res) => any

alert Attributes

NameDescriptionTypeDefaultRequired
titleAlert title.string / (selectionData, tableRef) => VNodeNo
typeAlert type.success / warning / info / errorinfoNo
descriptionDescriptive textstring / () => VNodeNo
closableWhether closablebooleantrueNo
centerWhether text is centeredbooleanfalseNo
close-textCustom close button textstringNo
effectTheme stylelight / dark'light'No
onCloseClose Alert eventFunctionNo
Event NameDescriptionType
operate-deleteDelete table data({ selectionData, row, table, getTableData }) => void
Slot NameDescription
alertFixed alert content at the top of table when data is selected

Released under the MIT License.