Crud

封装表格组件和表单组件实现通过配置动态生成页面,支持表格和表单组件的全部属性

使用

基础用法

当 columns 绑定的是一个具有响应式的数组时,数组的变动会影响 Crud 变动(及动态 Crud)。如果不需要动态 Crud 推荐绑定一个普通数组

根据 add edit form hide search 自动生成多功能表格

<template>
  <pro-crud
    v-model="form"
    v-model:search="serachForm"
    :columns="columns"
    :menu="{ label: 'Operations' }"
    :data="data"
    :before-open="beforeOpen"
    label-width="100px"
    @search="search"
    @submit="submit"
    @delete="deleteRow"
  />
</template>

<script>
import { defineComponent, ref } from 'vue'

export default defineComponent({
  setup() {
    const form = ref({})
    const serachForm = ref({})
    const columns = [
      {
        label: 'Date',
        prop: 'date',
        component: 'el-input',
        add: true,
        edit: true,
        search: true,
      },
      {
        label: 'Name',
        prop: 'name',
        component: 'el-input',
        add: true,
        search: true,
      },
      {
        label: 'Address',
        prop: 'address',
        component: 'el-input',
        add: true,
        edit: true,
      },
    ]
    const data = ref([
      {
        date: '2016-05-03',
        name: 'Tom',
        address: 'No. 189, Grove St, Los Angeles',
      },
      {
        date: '2016-05-02',
        name: 'Tom',
        address: 'No. 189, Grove St, Los Angeles',
      },
      {
        date: '2016-05-04',
        name: 'Tom',
        address: 'No. 189, Grove St, Los Angeles',
      },
      {
        date: '2016-05-01',
        name: 'Tom',
        address: 'No. 189, Grove St, Los Angeles',
      },
    ])

    const beforeOpen = (done, type, row) => {
      if (type === 'edit') {
        form.value = row || {}
      }
      done()
    }

    const search = (done, isValid, invalidFields) => {
      console.log('search', serachForm.value, isValid, invalidFields)
      setTimeout(() => {
        done()
      }, 1000)
    }

    const submit = (close, done, formType, isValid, invalidFields) => {
      console.log('submit', form.value, formType, isValid, invalidFields)
      setTimeout(() => {
        isValid ? close() : done()
      }, 1000)
    }

    const deleteRow = (row) => {
      console.log('deleteRow', row)
    }

    return {
      form,
      serachForm,
      data,
      columns,
      beforeOpen,
      search,
      submit,
      deleteRow,
    }
  },
})
</script>
显示代码

智能提示

通过辅助函数 defineCrudColumns defineCrudMenuColumns defineCrudBeforeOpen defineCrudBeforeClose defineCrudSearch defineCrudSubmit 提供智能提示

<template>
  <pro-crud
    v-model="form"
    v-model:search="serachForm"
    :columns="columns"
    :menu="{ label: 'Operations' }"
    :data="data"
    :before-open="beforeOpen"
    label-width="100px"
    @search="search"
    @submit="submit"
    @delete="deleteRow"
  />
</template>

<script>
import { defineComponent, ref } from 'vue'
import {
  defineCrudColumns,
  defineCrudSubmit,
  defineCrudSearch,
  defineCrudBeforeOpen,
} from 'element-pro-components'

export default defineComponent({
  setup() {
    const form = ref({})
    const serachForm = ref({})
    const columns = defineCrudColumns([
      {
        label: 'Date',
        prop: 'date',
        component: 'el-input',
        add: true,
        edit: true,
        search: true,
      },
      {
        label: 'Name',
        prop: 'name',
        component: 'el-input',
        add: true,
        search: true,
      },
      {
        label: 'Address',
        prop: 'address',
        component: 'el-input',
        add: true,
        edit: true,
      },
    ])
    const data = ref([
      {
        date: '2016-05-03',
        name: 'Tom',
        address: 'No. 189, Grove St, Los Angeles',
      },
      {
        date: '2016-05-02',
        name: 'Tom',
        address: 'No. 189, Grove St, Los Angeles',
      },
      {
        date: '2016-05-04',
        name: 'Tom',
        address: 'No. 189, Grove St, Los Angeles',
      },
      {
        date: '2016-05-01',
        name: 'Tom',
        address: 'No. 189, Grove St, Los Angeles',
      },
    ])

    const beforeOpen = defineCrudBeforeOpen((done, type, row) => {
      if (type === 'edit') {
        form.value = row || {}
      }
      done()
    })

    const search = defineCrudSearch((done, isValid, invalidFields) => {
      console.log('search', serachForm.value, isValid, invalidFields)
      setTimeout(() => {
        done()
      }, 1000)
    })

    const submit = defineCrudSubmit(
      (close, done, formType, isValid, invalidFields) => {
        console.log('submit', form.value, formType, isValid, invalidFields)
        setTimeout(() => {
          isValid ? close() : done()
        }, 1000)
      }
    )

    const deleteRow = (row) => {
      console.log('deleteRow', row)
    }

    return {
      form,
      serachForm,
      data,
      columns,
      beforeOpen,
      search,
      submit,
      deleteRow,
    }
  },
})
</script>
显示代码

嵌套键值

<template>
  <pro-crud
    v-model="form"
    v-model:search="serachForm"
    :columns="columns"
    :menu="{ label: 'Operations' }"
    :data="data"
    :before-open="beforeOpen"
    label-width="100px"
    @search="search"
    @submit="submit"
    @delete="deleteRow"
  />
</template>

<script>
import { defineComponent, ref } from 'vue'
import {
  defineCrudColumns,
  defineCrudBeforeOpen,
  defineCrudSubmit,
  defineCrudSearch,
} from 'element-pro-components'

export default defineComponent({
  setup() {
    const form = ref({ 'a.b': undefined })
    const serachForm = ref({ 'a.b': undefined })
    const columns = defineCrudColumns([
      {
        label: 'Break',
        prop: 'a.b',
        component: 'el-input',
        form: true,
        search: true,
      },
      {
        label: 'Object',
        prop: 'a.b.c',
        component: 'el-input',
        form: true,
        search: true,
      },
      {
        label: 'Array',
        prop: 'b[0]',
        component: 'el-input',
        form: true,
        search: true,
      },
    ])
    const data = [
      {
        'a.b': 'break nested value',
        a: { b: { c: 'nested value c' } },
        b: ['nested value in array'],
      },
    ]

    const beforeOpen = defineCrudBeforeOpen((done, type, row) => {
      if (type === 'edit') {
        form.value = row || {}
      } else {
        form.value = { 'a.b': undefined }
      }
      done()
    })

    const search = defineCrudSearch((done, isValid, invalidFields) => {
      console.log('search', serachForm.value, isValid, invalidFields)
      setTimeout(() => {
        done()
      }, 1000)
    })

    const submit = defineCrudSubmit(
      (close, done, formType, isValid, invalidFields) => {
        console.log('submit', form.value, formType, isValid, invalidFields)
        setTimeout(() => {
          isValid ? close() : done()
        }, 1000)
      }
    )

    const deleteRow = (row) => {
      console.log('deleteRow', row)
    }

    return {
      form,
      serachForm,
      data,
      columns,
      beforeOpen,
      search,
      submit,
      deleteRow,
    }
  },
})
</script>
显示代码

配置按钮

默认不显示新增、编辑、删除按钮,需要配置 menu 或者启用 menu 插槽时才会显示

按钮也可以通过 全局配置 或者 国际化 来配置

<template>
  <pro-crud
    v-model="form"
    v-model:search="serachForm"
    :columns="columns"
    :menu="menu"
    :data="data"
    :before-open="beforeOpen"
    label-width="100px"
    @search="search"
    @searchReset="reset"
    @submit="submit"
    @reset="reset"
    @delete="deleteRow"
  />
</template>

<script>
import { defineComponent, ref } from 'vue'
import {
  defineCrudColumns,
  defineCrudMenuColumns,
  defineCrudSubmit,
  defineCrudSearch,
  defineCrudBeforeOpen,
} from 'element-pro-components'

export default defineComponent({
  setup() {
    const menu = defineCrudMenuColumns({
      label: 'Operations',
      addText: 'New',
      editText: 'Edit Row',
      delText: 'Clean',
      searchText: 'Search',
      searchResetText: 'Reset Search',
      submitText: 'Create',
      resetText: 'Reset Form',
      edit: (row) => row.date !== '2016-05-02',
      del: (row) => row.date !== '2016-05-04',
      searchReset: false,
      editProps: { type: 'default', plain: true },
      delProps: { type: 'danger', plain: true },
    })
    const form = ref({})
    const serachForm = ref({})
    const columns = defineCrudColumns([
      {
        label: 'Date',
        prop: 'date',
        component: 'el-input',
        form: true,
      },
      {
        label: 'Name',
        prop: 'name',
        component: 'el-input',
        form: true,
        search: true,
      },
      {
        label: 'Address',
        prop: 'address',
        component: 'el-input',
        form: true,
      },
    ])
    const data = ref([
      {
        date: '2016-05-03',
        name: 'Tom',
        address: 'No. 189, Grove St, Los Angeles',
      },
      {
        date: '2016-05-02',
        name: 'Tom',
        address: 'No. 189, Grove St, Los Angeles',
      },
      {
        date: '2016-05-04',
        name: 'Tom',
        address: 'No. 189, Grove St, Los Angeles',
      },
      {
        date: '2016-05-01',
        name: 'Tom',
        address: 'No. 189, Grove St, Los Angeles',
      },
    ])

    const beforeOpen = defineCrudBeforeOpen((done, type, row) => {
      if (type === 'edit') {
        form.value = row || {}
      }
      done()
    })

    const search = defineCrudSearch((done, isValid, invalidFields) => {
      console.log('search', serachForm.value, isValid, invalidFields)
      setTimeout(() => {
        done()
      }, 1000)
    })

    const submit = defineCrudSubmit(
      (close, done, formType, isValid, invalidFields) => {
        console.log('submit', form.value, formType, isValid, invalidFields)
        setTimeout(() => {
          isValid ? close() : done()
        }, 1000)
      }
    )

    const reset = () => {
      console.log('reset')
    }

    const deleteRow = (row) => {
      console.log('deleteRow', row)
    }

    return {
      form,
      serachForm,
      columns,
      menu,
      data,
      beforeOpen,
      search,
      submit,
      reset,
      deleteRow,
    }
  },
})
</script>
显示代码

指定搜索表单

通过 search-columns 传入的配置直接作用于搜索表单,类型同 Form columns

暂无数据
<template>
  <pro-crud
    v-model:search="serachForm"
    :columns="columns"
    :search-columns="searchColumns"
    @search="search"
    @searchReset="reset"
  />
</template>

<script>
import { defineComponent, ref } from 'vue'
import {
  defineCrudColumns,
  defineCrudSearch,
  defineFormColumns,
} from 'element-pro-components'

export default defineComponent({
  setup() {
    const serachForm = ref({})
    const columns = defineCrudColumns([
      {
        label: 'Date',
        prop: 'date',
      },
      {
        label: 'Name',
        prop: 'name',
      },
      {
        label: 'Address',
        prop: 'address',
      },
    ])
    const searchColumns = defineFormColumns([
      {
        label: 'Name',
        prop: 'name',
        component: 'el-input',
      },
      {
        label: 'Date',
        prop: 'date',
        component: 'el-date-picker',
        props: {
          type: 'datetimerange',
          rangeSeparator: '-',
          startPlaceholder: 'start',
          endPlaceholder: 'end',
        },
      },
    ])

    const search = defineCrudSearch((done, isValid, invalidFields) => {
      console.log('search', serachForm.value, isValid, invalidFields)
      setTimeout(() => {
        done()
      }, 1000)
    })

    const reset = () => {
      console.log('reset search')
    }

    return {
      serachForm,
      columns,
      searchColumns,
      search,
      reset,
    }
  },
})
</script>
显示代码

指定新增表单

通过 add-columns 传入的配置直接作用于新增表单,类型同 Form columns

暂无数据
<template>
  <pro-crud
    v-model="form"
    :columns="columns"
    :add-columns="addColumns"
    :menu="true"
    label-width="100px"
    @submit="submit"
    @reset="reset"
  />
</template>

<script>
import { defineComponent, ref } from 'vue'
import {
  defineCrudColumns,
  defineCrudSubmit,
  defineFormColumns,
} from 'element-pro-components'

export default defineComponent({
  setup() {
    const form = ref({})
    const columns = defineCrudColumns([
      {
        label: 'Date',
        prop: 'date',
      },
      {
        label: 'Name',
        prop: 'name',
      },
      {
        label: 'Address',
        prop: 'address',
      },
    ])
    const addColumns = defineFormColumns([
      {
        label: 'Name',
        prop: 'name',
        component: 'el-input',
      },
      {
        label: 'Date',
        prop: 'date',
        component: 'el-date-picker',
        props: {
          type: 'datetimerange',
          rangeSeparator: '-',
          startPlaceholder: 'start',
          endPlaceholder: 'end',
        },
      },
    ])

    const submit = defineCrudSubmit(
      (close, done, formType, isValid, invalidFields) => {
        console.log('submit', form.value, formType, isValid, invalidFields)
        setTimeout(() => {
          isValid ? close() : done()
        }, 1000)
      }
    )

    const reset = () => {
      console.log('reset')
    }

    return {
      form,
      columns,
      addColumns,
      submit,
      reset,
    }
  },
})
</script>
显示代码

指定编辑表单

通过 edit-columns 传入的配置直接作用于新增表单,类型同 Form columns

<template>
  <pro-crud
    v-model="form"
    :columns="columns"
    :edit-columns="editColumns"
    :menu="true"
    :data="data"
    label-width="100px"
    @submit="submit"
    @reset="reset"
    @delete="deleteRow"
  />
</template>

<script>
import { defineComponent, ref } from 'vue'
import {
  defineCrudColumns,
  defineCrudSubmit,
  defineFormColumns,
} from 'element-pro-components'

export default defineComponent({
  setup() {
    const form = ref({})
    const columns = defineCrudColumns([
      {
        label: 'Date',
        prop: 'date',
        component: 'el-input',
        add: true,
      },
      {
        label: 'Name',
        prop: 'name',
      },
      {
        label: 'Address',
        prop: 'address',
      },
    ])
    const editColumns = defineFormColumns([
      {
        label: 'Name',
        prop: 'name',
        component: 'el-input',
      },
      {
        label: 'Date',
        prop: 'date',
        component: 'el-date-picker',
        props: {
          type: 'datetimerange',
          rangeSeparator: '-',
          startPlaceholder: 'start',
          endPlaceholder: 'end',
        },
      },
    ])
    const data = ref([
      {
        date: '2016-05-03',
        name: 'Tom',
        address: 'No. 189, Grove St, Los Angeles',
      },
      {
        date: '2016-05-02',
        name: 'Tom',
        address: 'No. 189, Grove St, Los Angeles',
      },
      {
        date: '2016-05-04',
        name: 'Tom',
        address: 'No. 189, Grove St, Los Angeles',
      },
      {
        date: '2016-05-01',
        name: 'Tom',
        address: 'No. 189, Grove St, Los Angeles',
      },
    ])

    const submit = defineCrudSubmit(
      (close, done, formType, isValid, invalidFields) => {
        console.log('submit', form.value, formType, isValid, invalidFields)
        setTimeout(() => {
          isValid ? close() : done()
        }, 1000)
      }
    )

    const reset = () => {
      console.log('reset')
    }

    const deleteRow = (row) => {
      console.log('deleteRow', row)
    }

    return {
      form,
      columns,
      editColumns,
      data,
      submit,
      reset,
      deleteRow,
    }
  },
})
</script>
显示代码

指定表单

通过 form-columns 传入的配置直接作用于新增和编辑表单,类型同 Form columns

<template>
  <pro-crud
    v-model="form"
    :columns="columns"
    :form-columns="formColumns"
    :menu="true"
    :data="data"
    label-width="100px"
    @submit="submit"
    @reset="reset"
    @delete="deleteRow"
  />
</template>

<script>
import { defineComponent, ref } from 'vue'
import {
  defineCrudColumns,
  defineCrudSubmit,
  defineFormColumns,
} from 'element-pro-components'

export default defineComponent({
  setup() {
    const form = ref({})
    const columns = defineCrudColumns([
      {
        label: 'Date',
        prop: 'date',
      },
      {
        label: 'Name',
        prop: 'name',
      },
      {
        label: 'Address',
        prop: 'address',
      },
    ])
    const formColumns = defineFormColumns([
      {
        label: 'Name',
        prop: 'name',
        component: 'el-input',
      },
      {
        label: 'Date',
        prop: 'date',
        component: 'el-date-picker',
        props: {
          type: 'datetimerange',
          rangeSeparator: '-',
          startPlaceholder: 'start',
          endPlaceholder: 'end',
        },
      },
    ])
    const data = ref([
      {
        date: '2016-05-03',
        name: 'Tom',
        address: 'No. 189, Grove St, Los Angeles',
      },
      {
        date: '2016-05-02',
        name: 'Tom',
        address: 'No. 189, Grove St, Los Angeles',
      },
      {
        date: '2016-05-04',
        name: 'Tom',
        address: 'No. 189, Grove St, Los Angeles',
      },
      {
        date: '2016-05-01',
        name: 'Tom',
        address: 'No. 189, Grove St, Los Angeles',
      },
    ])

    const submit = defineCrudSubmit(
      (close, done, formType, isValid, invalidFields) => {
        console.log('submit', form.value, formType, isValid, invalidFields)
        setTimeout(() => {
          isValid ? close() : done()
        }, 1000)
      }
    )

    const reset = () => {
      console.log('reset')
    }

    const deleteRow = (row) => {
      console.log('deleteRow', row)
    }

    return {
      form,
      columns,
      formColumns,
      data,
      submit,
      reset,
      deleteRow,
    }
  },
})
</script>
显示代码

指定表格

通过 table-columns 传入的配置直接作用于表格,类型同 Table columns

<template>
  <pro-crud
    v-model="form"
    v-model:search="serachForm"
    :columns="columns"
    :table-columns="tableColumns"
    :menu="{ label: 'Operations' }"
    :data="data"
    label-width="100px"
    @submit="submit"
    @reset="reset"
    @delete="deleteRow"
  />
</template>

<script>
import { defineComponent, ref } from 'vue'
import {
  defineCrudColumns,
  defineCrudSubmit,
  defineTableColumns,
} from 'element-pro-components'

export default defineComponent({
  setup() {
    const form = ref({})
    const serachForm = ref({})
    const columns = defineCrudColumns([
      {
        label: 'Date',
        prop: 'date',
        component: 'el-input',
        form: true,
      },
      {
        label: 'Name',
        prop: 'name',
        component: 'el-input',
        form: true,
        search: true,
      },
      {
        label: 'Address',
        prop: 'address',
        component: 'el-input',
      },
    ])
    const tableColumns = defineTableColumns([
      {
        label: 'Date',
        prop: 'date',
      },
      {
        label: 'User',
        children: [
          {
            label: 'Name',
            prop: 'name',
          },
          {
            label: 'Address',
            prop: 'address',
          },
        ],
      },
    ])
    const data = ref([
      {
        date: '2016-05-03',
        name: 'Tom',
        address: 'No. 189, Grove St, Los Angeles',
      },
      {
        date: '2016-05-02',
        name: 'Tom',
        address: 'No. 189, Grove St, Los Angeles',
      },
      {
        date: '2016-05-04',
        name: 'Tom',
        address: 'No. 189, Grove St, Los Angeles',
      },
      {
        date: '2016-05-01',
        name: 'Tom',
        address: 'No. 189, Grove St, Los Angeles',
      },
    ])

    const submit = defineCrudSubmit(
      (close, done, formType, isValid, invalidFields) => {
        console.log('submit', form.value, formType, isValid, invalidFields)
        setTimeout(() => {
          isValid ? close() : done()
        }, 1000)
      }
    )

    const reset = () => {
      console.log('reset')
    }

    const deleteRow = (row) => {
      console.log('deleteRow', row)
    }

    return {
      form,
      serachForm,
      columns,
      tableColumns,
      data,
      submit,
      reset,
      deleteRow,
    }
  },
})
</script>
显示代码

弹窗前后

通过 before-open before-close 指定弹窗开启前与弹窗关闭前执行的操作

<template>
  <pro-crud
    v-model="form"
    :columns="columns"
    :menu="{ label: 'Operations' }"
    :data="data"
    :before-open="beforeOpen"
    :before-close="beforeClose"
    label-width="100px"
  />
</template>

<script>
import { defineComponent, ref } from 'vue'
import {
  defineCrudColumns,
  defineCrudBeforeOpen,
  defineCrudBeforeClose,
} from 'element-pro-components'

export default defineComponent({
  setup() {
    const form = ref({})
    const columns = defineCrudColumns([
      {
        label: 'Date',
        prop: 'date',
        component: 'el-input',
        form: true,
      },
      {
        label: 'Name',
        prop: 'name',
      },
      {
        label: 'Address',
        prop: 'address',
      },
    ])
    const data = ref([
      {
        date: '2016-05-03',
        name: 'Tom',
        address: 'No. 189, Grove St, Los Angeles',
      },
      {
        date: '2016-05-02',
        name: 'Tom',
        address: 'No. 189, Grove St, Los Angeles',
      },
      {
        date: '2016-05-04',
        name: 'Tom',
        address: 'No. 189, Grove St, Los Angeles',
      },
      {
        date: '2016-05-01',
        name: 'Tom',
        address: 'No. 189, Grove St, Los Angeles',
      },
    ])
    const beforeOpen = defineCrudBeforeOpen((done, type, row) => {
      console.log('beforeOpen', type, row)
      setTimeout(() => {
        done()
      }, 1000)
    })
    const beforeClose = defineCrudBeforeClose((done) => {
      console.log('beforeClose')
      setTimeout(() => {
        done()
      }, 1000)
    })

    return {
      form,
      columns,
      data,
      beforeOpen,
      beforeClose,
    }
  },
})
</script>
显示代码

插槽

columns 中配置 render 可以使用简单的 渲染函数。或者直接在模版中增加带 [prop] 相关的插槽

<template>
  <pro-crud
    v-model="form"
    v-model:search="serachForm"
    :columns="columns"
    :menu="{ label: 'Operations' }"
    :data="data"
    selection
    label-width="100px"
    @search="search"
    @submit="submit"
    @delete="deleteRow"
  >
    <template #menu-right="{ size }">
      <el-button
        :size="size"
        type="danger"
      >
        Remove
      </el-button>
    </template>
    <template #menu="{ size }">
      <el-button
        :size="size"
        type="text"
      >
        Detail
      </el-button>
    </template>
    <template #form-name>
      <span>form slot</span>
    </template>
    <template #table-name="{ row, size }">
      <el-tag :size="size">
        {{ row?.name }}
      </el-tag>
    </template>
    <template #name-header="{ column }">
      <s>{{ column.label }}</s>
    </template>
    <template #action>
      <el-button
        :icon="Refresh"
        circle
        style="margin-right: 8px"
      />
      <pro-column-setting v-model="columns" />
    </template>
  </pro-crud>
</template>

<script>
import { defineComponent, h, ref } from 'vue'
import { Clock, Refresh } from '@element-plus/icons-vue'
import {
  defineCrudColumns,
  defineCrudSubmit,
  defineCrudSearch,
} from 'element-pro-components'

export default defineComponent({
  setup() {
    const form = ref({})
    const serachForm = ref({})
    const columns = ref(
      defineCrudColumns([
        {
          label: 'Date',
          prop: 'date',
          component: 'el-input',
          add: true,
          edit: true,
          search: true,
          render: '--',
          props: {
            slots: {
              suffix: () =>
                h('span', { className: 'el-input__icon' }, h(Clock)),
            },
          },
        },
        {
          label: 'Name',
          prop: 'name',
          component: 'el-input',
          add: true,
          search: true,
          slot: true,
        },
        {
          label: 'Address',
          prop: 'address',
          component: 'el-input',
          add: true,
          edit: true,
          render: (row) => h('em', null, row.address),
        },
      ])
    )
    const data = ref([
      {
        date: '2016-05-03',
        name: 'Tom',
        address: 'No. 189, Grove St, Los Angeles',
      },
      {
        date: '2016-05-02',
        name: 'Tom',
        address: 'No. 189, Grove St, Los Angeles',
      },
      {
        date: '2016-05-04',
        name: 'Tom',
        address: 'No. 189, Grove St, Los Angeles',
      },
      {
        date: '2016-05-01',
        name: 'Tom',
        address: 'No. 189, Grove St, Los Angeles',
      },
    ])

    const search = defineCrudSearch((done, isValid, invalidFields) => {
      console.log('search', serachForm.value, isValid, invalidFields)
      setTimeout(() => {
        done()
      }, 1000)
    })

    const submit = defineCrudSubmit(
      (close, done, formType, isValid, invalidFields) => {
        console.log('submit', form.value, formType, isValid, invalidFields)
        setTimeout(() => {
          isValid ? close() : done()
        }, 1000)
      }
    )

    const deleteRow = (row) => {
      console.log('deleteRow', row)
    }

    return {
      Refresh,
      form,
      serachForm,
      data,
      columns,
      search,
      submit,
      deleteRow,
    }
  },
})
</script>

<style>
.el-input__icon {
  width: 14px;
}
</style>
显示代码

TypeScript

defineCrudColumns 支持传入一个泛型用来推断 prop

<template>
  <pro-crud
    v-model="form"
    v-model:search="serachForm"
    :columns="columns"
    :menu="menu"
    :data="data"
    :before-open="beforeOpen"
    label-width="100px"
    @search="search"
    @submit="submit"
    @delete="deleteRow"
  />
</template>

<script setup lang="ts">
import { ref } from 'vue'
import {
  defineCrudColumns,
  defineCrudMenuColumns,
  defineCrudSubmit,
  defineCrudSearch,
  defineCrudBeforeOpen,
} from 'element-pro-components'

interface DataItem {
  date: string
  name: string
  address: string
}

const form = ref({})
const serachForm = ref({})
const menu = defineCrudMenuColumns<DataItem>({
  label: 'Operations',
  edit: (row) => row.date !== '2016-05-02',
  del: (row) => row.date !== '2016-05-04',
  searchReset: false,
})
const columns = defineCrudColumns<DataItem>([
  {
    label: 'Date',
    prop: 'date',
    component: 'el-input',
    add: true,
    edit: true,
    search: true,
  },
  {
    label: 'Name',
    prop: 'name',
    component: 'el-input',
    add: true,
    search: true,
  },
  {
    label: 'Address',
    prop: 'address',
    component: 'el-input',
    add: true,
    edit: true,
  },
])
const data = ref<DataItem[]>([
  {
    date: '2016-05-03',
    name: 'Tom',
    address: 'No. 189, Grove St, Los Angeles',
  },
  {
    date: '2016-05-02',
    name: 'Tom',
    address: 'No. 189, Grove St, Los Angeles',
  },
  {
    date: '2016-05-04',
    name: 'Tom',
    address: 'No. 189, Grove St, Los Angeles',
  },
  {
    date: '2016-05-01',
    name: 'Tom',
    address: 'No. 189, Grove St, Los Angeles',
  },
])

const beforeOpen = defineCrudBeforeOpen<DataItem>((done, type, row) => {
  if (type === 'edit') {
    form.value = row || {}
  }
  done()
})

const search = defineCrudSearch((done, isValid, invalidFields) => {
  console.log('search', serachForm.value, isValid, invalidFields)
  setTimeout(() => {
    done()
  }, 1000)
})

const submit = defineCrudSubmit(
  (close, done, formType, isValid, invalidFields) => {
    console.log('submit', form.value, formType, isValid, invalidFields)
    setTimeout(() => {
      isValid ? close() : done()
    }, 1000)
  }
)

const deleteRow = (row: DataItem) => {
  console.log('deleteRow', row)
}
</script>
显示代码

配置

参数说明类型可选值默认值
v-model表单绑定值object--
v-model:search搜索表单绑定值object--
columns自动生成 Crud 的参数,参考下面 columnsarray--
add-columns自动生成新增表单的参数,参考下面 columnsarray-columns 中获取
edit-columns自动生成编辑表单的参数,参考下面 columnsarray-columns 中获取
form-columns自动生成表单的参数,参考下面 columnsarray-columns 中获取
search-columns自动生成搜索表单的参数,参考下面 columnsarray-columns 中获取
table-columns自动生成表格的参数,参考下面 columnsarray-columns 中获取
menu按钮配置参考下面 menuobject--
search-rules搜索表单验证规则object--
data显示的数据array--
selection显示多选框,支持 columns 的配置boolean / object-false
index显示索引,支持 columns 的配置boolean / object-false
expand开启展开插槽,支持 columns 的配置boolean / object-false
menu开启操作按钮插槽,支持 columns 的配置boolean / object-false
show-overflow-tooltip当内容过长被隐藏时显示 tooltipboolean-false
align对齐方式stringleft / center / rightleft
header-align表头对齐方式stringleft / center / right同 align
total总条目数number--
current-page当前页数,可以通过 v-model:current-page 绑定值number--
page-size每页显示条目个数,可以通过 v-model:page-size 绑定值number--
paginationpagination 的配置,同 el-paginationobject-从全局配置中获取
heightTable 的高度string / number-自动高度
max-heightTable 的最大高度string / number--
stripe是否为斑马纹 tableboolean-false
border是否带有纵向边框boolean-false
sizeTable 的尺寸stringlarge / default /small-
fit列的宽度是否自撑开boolean-true
show-header是否显示表头boolean-true
highlight-current-row是否要高亮当前行boolean-false
current-row-key当前行的 key,只写属性string / number--
row-class-name为行增加 classNameFunction({row, rowIndex}) / string--
row-style为行增加 styleFunction({row, rowIndex}) / object--
cell-class-name为单元格增加 classNameFunction({row, column, rowIndex, columnIndex}) / string--
cell-style为单元格增加 styleFunction({row, column, rowIndex, columnIndex}) / object--
header-row-class-name为表头行增加 classNameFunction({row, rowIndex}) / string--
header-row-style为表头行增加 styleFunction({row, rowIndex}) / object--
header-cell-class-name为表头单元格增加 classNameFunction({row, column, rowIndex, columnIndex}) / string--
header-cell-style为表头单元格增加 styleFunction({row, column, rowIndex, columnIndex}) / object--
row-key行数据的 Key,使用 reserveSelection 功能时必填Function(row) / string--
empty-text空数据时显示的文本内容string-暂无数据
default-expand-all是否默认展开所有行boolean-false
expand-row-keysTable 目前的展开行,与 row-key 配合使用array--
default-sort默认的排序列的 prop 和顺序Objectorder: ascending, descendingascending
tooltip-effecttooltip effect 属性Stringdark / light-
show-summary是否在表尾显示合计行Boolean-false
sum-text合计行第一列的文本String-合计
summary-method自定义的合计计算方法Function({ columns, data })--
span-method合并行或列的计算方法Function({ row, column, rowIndex, columnIndex })--
select-on-indeterminate当仅有部分行被选中时,点击表头的多选框时的行为,配合 selection 使用boolean-true
indent展示树形数据时,树节点的缩进number-16
lazy是否懒加载子节点数据boolean--
load加载子节点数据的函数,lazy 为 true 时生效Function(row, treeNode, resolve)--
tree-props渲染嵌套数据的配置选项Object-{ hasChildren: ‘hasChildren’, children: ‘children’ }
rules表单验证规则object--
inline行内表单模式boolean-false
label-position表单域标签的位置,如果值为 left 或者 right 时,则需要设置 label-widthstringright / left / topright
label-width表单域标签的宽度,例如 ‘50px’ 或 ‘auto’string--
label-suffix表单域标签的后缀string--
hide-required-asterisk是否显示必填字段的标签旁边的红色星号boolean-false
show-message是否显示校验错误信息boolean-true
inline-message是否以行内形式展示校验信息boolean-false
status-icon是否在输入框中显示校验结果反馈图标boolean-false
validate-on-rule-change是否在 rules 属性改变后立即触发一次验证boolean-true
size用于控制该表单内组件的尺寸stringlarge / default /small-
disabled是否禁用该表单内的所有组件boolean-false
gutter栅格间隔number-0
justifyflex 布局下的水平排列方式stringstart / end / center / space-around / space-betweenstart
title弹窗的标题string同 menu addText / editText
width弹窗的宽度string / number50%
fullscreen是否为全屏弹窗booleanfalse
top弹窗 CSS 中的 margin-top 值string15vh
modal是否需要遮罩层booleantrue
append-to-body弹窗自身是否插入至 body 元素上booleanfalse
lock-scroll是否在 弹窗出现时将 body 滚动锁定booleantrue
custom-class弹窗的自定义类名stringpro-crud-dialog
open-delay弹窗打开的延时时间,单位毫秒number0
close-delay弹窗关闭的延时时间,单位毫秒number0
close-on-click-modal是否可以通过点击 modal 关闭弹窗booleantrue
close-on-press-escape是否可以通过按下 ESC 关闭弹窗booleantrue
show-close是否显示关闭按钮booleantrue
before-open弹窗开启前的回调,会暂停弹窗的开启Function(done, formType, row)--
before-close关闭前的回调,会暂停弹窗的关闭Function(done),done 用于关闭弹窗
center是否对头部和底部采用居中布局booleanfalse
destroy-on-close关闭时销毁弹窗中的元素booleanfalse

columns 的参数

参数说明类型可选值默认值
add是否在新增表单中显示boolean-false
edit是否在编辑表单中显示boolean-false
form是否在表单中显示boolean-false
search是否在搜索表单中显示boolean-false
hide是否在表格中隐藏boolean-false
prop对应 data 的字段名 (必填,需要是唯一值)string--
label显示的标题string--
slot是否开启自定义插槽功能boolean-false
render通过渲染函数对表格实现简单的插槽功能string / function(row)--
children实现多级表头array--
columnKey当前项的 key,使用 filter-change 事件时需要string--
width对应列的宽度string--
minWidth对应列的最小宽度string--
fixed列是否固定,true 表示固定在左侧string / booleantrue / left / right-
renderHeader列标题 Label 区域渲染使用的 FunctionFunction(h, { column, $index })--
sortable对应列是否可以排序boolean / stringtrue / false / ‘custom’false
sortMethod对数据进行排序的时候使用的方法Function(a, b)--
sortBy指定数据按照哪个属性进行排序string / array / Function(row, index)--
sortOrders数据在排序时所使用排序策略的轮转顺序arrayascending 表示升序,descending 表示降序,null 表示还原为原始顺序[‘ascending’, ‘descending’, null]
resizable对应列是否可以通过拖动改变宽度,配合 border 使用boolean-true
formatter用来格式化内容Function(row, column, cellValue, index)--
showOverflowTooltip当内容过长被隐藏时显示 tooltipBoolean-false
align对齐方式stringleft / center / rightleft
headerAlign表头对齐方式stringleft / center / right同 align
className列的 classNamestring--
labelClassName当前列标题的自定义类名string--
filters数据过滤的选项Array[{ text, value }]--
filterPlacement过滤弹出框的定位stringtop / top-start / top-end / bottom / bottom-start / bottom-end / left / left-start / left-end / right / right-start / right-end-
filterMultiple数据过滤的选项是否多选boolean-true
filterMethod数据过滤使用的方法Function(value, row, column)--
filteredValue选中的数据过滤项array--
index自定义索引,只能够在 index 中配置Function(index) / number--
selectable这一行的 CheckBox 是否可以勾选,只能够在 selection 中配置Function(row, index)--
reserveSelection是否保留之前选中的数据(需指定 row-key),只能够在 selection 中配置boolean-false
max与 children 一起使用,限制子表单的最大数量number--
labelWidth表单域标签的宽度,例如 ‘50px’ 或 ‘auto’string--
required是否必填,如不设置,则会根据校验规则自动生成boolean-false
rules表单验证规则object / array--
error表单域验证错误信息, 设置该值会使表单验证状态变为error,并显示该错误信息string--
showMessage是否显示校验错误信息boolean-true
inlineMessage以行内形式展示校验信息boolean-false
size用于控制该表单域下组件的尺寸stringlarge / default /small-
span栅格占据的列数number-24
offset栅格左侧的间隔格数number-0
push栅格向右移动格数number-0
pull栅格向左移动格数number-0
xs<768px 响应式栅格数或者栅格属性对象number / object--
sm≥768px 响应式栅格数或者栅格属性对象number / object--
md≥992px 响应式栅格数或者栅格属性对象number / object--
lg≥1200px 响应式栅格数或者栅格属性对象number / object--
xl≥1920px 响应式栅格数或者栅格属性对象number / object--
参数说明类型可选值默认值
add是否显示 add 按钮boolean-true
addTextadd 按钮显示的文字string-Add
addPropsadd 按钮的配置,参考 el-buttonobject-{ type: ‘primary’ }
edit是否显示 edit 按钮boolean / Function(row)-true
editTextedit 按钮显示的文字string-Edit
editPropsedit 按钮的配置,参考 el-buttonobject-{ type: ‘text’ }
del是否显示 del 按钮boolean / Function(row)-true
delTextdel 按钮显示的文字string-Delete
delPropsdel 按钮的配置,参考 el-buttonobject-{ type: ‘text’ }
submit是否显示 submit 按钮boolean-true
submitTextsubmit 按钮显示的文字string-Submit
submitPropssubmit 按钮的配置,参考 el-buttonobject-{ type: ‘primary’ }
reset是否显示 reset 按钮boolean-true
resetText是否显示 reset 按钮显示的文字string-Reset
resetPropsreset 按钮的配置,参考 el-buttonobject--
search是否显示 search 按钮boolean-true
searchTextsearch 按钮显示的文字string-Search
searchPropssearch 按钮的配置,参考 el-buttonobject-{ type: ‘primary’ }
searchReset是否显示 reset 按钮boolean-true
searchResetText是否显示 reset 按钮显示的文字string-Reset
searchResetPropsreset 按钮的配置,参考 el-buttonobject--

提示

其它属性同 Table columns

事件

事件名说明参数
submitsubmit 被点击后触发close, done, ‘add’/‘edit’, isValid, invalidFields
resetreset 按钮被点击后触发-
deletedelete 按钮被点击后触发row
searchsearch 按钮被点击后触发done, isValid, invalidFields
searchResetsearch reset 按钮被点击后触发-
select当用户手动勾选数据行的 Checkbox 时触发的事件selection, row
select-all当用户手动勾选全选 Checkbox 时触发的事件selection
selection-change当选择项发生变化时会触发该事件selection
cell-mouse-enter当单元格 hover 进入时会触发该事件row, column, cell, event
cell-mouse-leave当单元格 hover 退出时会触发该事件row, column, cell, event
cell-click当某个单元格被点击时会触发该事件row, column, cell, event
cell-dblclick当某个单元格被双击击时会触发该事件row, column, cell, event
row-click当某一行被点击时会触发该事件row, column, event
row-contextmenu当某一行被鼠标右键点击时会触发该事件row, column, event
row-dblclick当某一行被双击时会触发该事件row, column, event
header-click当某一列的表头被点击时会触发该事件column, event
header-contextmenu当某一列的表头被鼠标右键点击时触发该事件column, event
sort-change当表格的排序条件发生变化的时候会触发该事件{ column, prop, order }
filter-change当表格的筛选条件发生变化的时候会触发该事件,参数的值是一个对象,对象的 key 是 column 的 columnKey,对应的 value 为用户选择的筛选条件的数组。filters
current-change当表格的当前行发生变化的时候会触发该事件,如果要高亮当前行,请打开表格的 highlight-current-row 属性currentRow, oldCurrentRow
header-dragend当拖动表头改变了列的宽度的时候会触发该事件newWidth, oldWidth, column, event
expand-change当用户对某一行展开或者关闭的时候会触发该事件(展开行时,回调的第二个参数为 expandedRows;树形表格时第二参数为 expanded)row, (expandedRows | expanded)
size-changepageSize 改变时会触发每页条数
current-changecurrentPage 改变时会触发当前页
prev-click用户点击上一页按钮改变当前页后触发当前页
next-click用户点击下一页按钮改变当前页后触发当前页
submitsubmit 被点击后触发done, isValid, invalidFields
resetreset 按钮被点击后触发-
validate任一表单项被校验后触发被校验的表单项 prop 值, isValid, invalidFields

方法

方法名说明参数
clearSelection用于多选表格,清空用户的选择-
toggleRowSelection用于多选表格,切换某一行的选中状态,如果使用了第二个参数,则是设置这一行选中与否(selected 为 true 则选中)row, selected
toggleAllSelection用于多选表格,切换全选和全不选-
toggleRowExpansion用于可展开表格与树形表格,切换某一行的展开状态,如果使用了第二个参数,则是设置这一行展开与否(expanded 为 truerow, expanded
setCurrentRow用于单选表格,设定某一行为选中行,如果调用时不加参数,则会取消目前高亮行的选中状态。row
clearSort用于清空排序条件,数据会恢复成未排序的状态-
clearFilter不传入参数时用于清空所有过滤条件,数据会恢复成未过滤的状态,也可传入由 columnKey 组成的数组以清除指定列的过滤条件columnKey
doLayout对 Table 进行重新布局。当 Table 或其祖先元素由隐藏切换为显示时,可能需要调用此方法-
sort手动对 Table 进行排序。参数prop属性指定排序列,order指定排序顺序。prop: string, order: string
validate对整个表单进行校验的方法,参数为一个回调函数。该回调函数会在校验结束后被调用,并传入两个参数:是否校验成功和未通过校验的字段。若不传入回调函数,则会返回一个 promiseFunction(callback: Function(boolean, object))
validateField对部分表单字段进行校验的方法Function(props: array | string, callback: Function(errorMessage: string))
resetFields对整个表单进行重置,将所有字段值重置为初始值并移除校验结果-
clearValidate移除表单项的校验结果。传入待移除的表单项的 prop 属性或者 prop 组成的数组,如不传则移除整个表单的校验结果Function(props: array | string)

插槽

name说明
menu-left新增按钮左侧,参数为 { size }
menu-right新增按钮右侧,参数为 { size }
action头部右侧操作栏,参数为 { size }
menu表格右侧自定义按钮,参数为 { size, row, column, $index }
expand当 expand 为 true 时,配置展开显示的内容,参数为 { row, column, $index }
append插入至表格最后一行之后的内容
table在表格右侧菜单前插入的任意内容
table-[prop]当前这列的内容,参数为 { row, column, $index }
[prop]-header当前这列表头的内容,参数为 { column, $index }
form在表单底部按钮前插入的任意内容
form-menu-left表单底部按钮左侧
form-menu-right表单底部按钮右侧
form-[prop]当前这项的 Form Item 的内容,参数为 { item, value, setValue }
[prop]-label当前这项的标签文本的内容,参数为 { item }
[prop]-error当前这项的自定义表单校验信息的显示方式,参数为 { error, item }
search在搜索按钮菜单前插入的任意内容
search-menu-left搜索表单按钮左侧,参数为 { loading }
search-menu-right搜索表单按钮右侧,参数为 { loading }
search-[prop]当前这项的 Form Item 的内容,参数为 { item, value, setValue }
search-[prop]-label当前这项的标签文本的内容,参数为 { item }
search-[prop]-error当前这项的自定义表单校验信息的显示方式,参数为 { error, item }

提示

[prop] 为 columns 中定义的 prop