Skip to content

增删改查 Crud

增删改查组件,或许它真的能躲得过那碗胡辣汤

基础用法

Show Code
vue
<script lang="ts" setup>
import { ref } from 'vue'
import { ElMessage } from 'element-plus'
import type { ICrudOption } from 'm-eleplus-crud'

const crudOption = ref<ICrudOption>({
  border: true,
  column: [
    {
      label: '名字',
      prop: 'name',
      search: true,
      formRules: [
        {
          required: true,
          message: '请输入名字',
          trigger: 'blur',
        },
      ],
    },
    {
      label: '性别',
      prop: 'sex',
      type: 'select',
      dicData: [
        {
          label: '男',
          value: 1,
        },
        {
          label: '女',
          value: 2,
        },
      ],
    },
  ],
})

const tableData = ref<any>([])

const tableTotal = ref(0)

const tableLoading = ref(false)

const modelForm = ref<any>({})

const query = ref<any>({
  page: 1,
  limit: 10,
})

const rowSave = (form: any, done: () => void, loading: () => void) => {
  new Promise((resolve) => {
    ElMessage.success(
      `模拟异步请求,3s后关闭,表单内容:${JSON.stringify(form)}`
    )
    setTimeout(() => {
      resolve(null)
    }, 3000)
  })
    .then(() => {
      done()
    })
    .finally(() => {
      setTimeout(() => {
        loading()
      }, 500)
    })
}

const rowEdit = (form: any, done: () => void, loading: () => void) => {
  new Promise((resolve) => {
    ElMessage.success(
      `模拟异步请求,3s后关闭,表单内容:${JSON.stringify(form)}`
    )
    setTimeout(() => {
      resolve(null)
    }, 3000)
  })
    .then(() => {
      done()
    })
    .finally(() => {
      setTimeout(() => {
        loading()
      }, 500)
    })
}

const rowDel = (row: any, index: number) => {
  ElMessage.success(`删除内容:${JSON.stringify(row)},索引:${index}`)
}

const getList = () => {
  ElMessage.success(
    `模拟异步请求,3s后拿到数据,查询条件:${JSON.stringify(query.value)}`
  )
  tableLoading.value = true
  setTimeout(() => {
    tableData.value = [
      ...tableData.value,
      ...[
        {
          name: `ZhangSan${Math.random()}`,
          sex: 1,
        },
        {
          name: `LiSi${Math.random()}`,
          sex: 2,
        },
      ],
    ]
    tableTotal.value += 2
    tableLoading.value = false
  }, 3000)
}
</script>

<template>
  <div style="width: 100%">
    <MCrud
      v-model="modelForm"
      v-model:search="query"
      :option="crudOption"
      :data="tableData"
      :total="tableTotal"
      :loading="tableLoading"
      @row-save="rowSave"
      @row-edit="rowEdit"
      @row-del="rowDel"
      @search="getList"
      @reset="getList"
    />
  </div>
</template>

自定义一切

Show Code
vue
<script lang="ts" setup>
import { ref } from 'vue'
import { ElMessage } from 'element-plus'
import type { CrudInstance, ICrudOption } from 'm-eleplus-crud'

const crudRef = ref<CrudInstance>()

const crudOption = ref<ICrudOption>({
  border: true,
  column: [
    {
      label: '名字',
      prop: 'name',
      search: true,
      formRules: [
        {
          required: true,
          message: '请输入名字',
          trigger: 'blur',
        },
      ],
    },
    {
      label: '性别',
      prop: 'sex',
      type: 'select',
      dicData: [
        {
          label: '男',
          value: 1,
        },
        {
          label: '女',
          value: 2,
        },
      ],
    },
  ],
})

const tableData = ref<any>([
  {
    name: `ZhangSan`,
    sex: 1,
  },
  {
    name: `LiSi`,
    sex: 2,
  },
])

const tableTotal = ref(2)

const tableLoading = ref(false)

const modelForm = ref<any>({})

const query = ref<any>({
  page: 1,
  limit: 10,
})

const rowSave = (form: any, done: () => void, loading: () => void) => {
  new Promise((resolve) => {
    ElMessage.success(
      `模拟异步请求,3s后关闭,表单内容:${JSON.stringify(form)}`
    )
    setTimeout(() => {
      resolve(null)
    }, 3000)
  })
    .then(() => {
      done()
    })
    .finally(() => {
      setTimeout(() => {
        loading()
      }, 500)
    })
}

const rowEdit = (form: any, done: () => void, loading: () => void) => {
  new Promise((resolve) => {
    ElMessage.success(
      `模拟异步请求,3s后关闭,表单内容:${JSON.stringify(form)}`
    )
    setTimeout(() => {
      resolve(null)
    }, 3000)
  })
    .then(() => {
      done()
    })
    .finally(() => {
      setTimeout(() => {
        loading()
      }, 500)
    })
}

const rowDel = (row: any, index: number) => {
  ElMessage.success(`删除内容:${JSON.stringify(row)},索引:${index}`)
}

const openAdd = () => {
  crudRef.value?.rowAdd()
}

const openEdit = (row: any, index: number) => {
  // 这里也可以调用详情接口啥的,那下面传的就不是row而是接口获取的数据
  crudRef.value?.rowEdit(row, index)
}

const openDel = (row: any, index: number) => {
  crudRef.value?.rowDel(row, index)
}
</script>

<template>
  <div style="width: 100%">
    <MCrud
      ref="crudRef"
      v-model="modelForm"
      v-model:search="query"
      :option="crudOption"
      :data="tableData"
      :total="tableTotal"
      :loading="tableLoading"
      @row-save="rowSave"
      @row-edit="rowEdit"
      @row-del="rowDel"
    >
      <template #addBtn="{ size }">
        <el-button :size="size" type="primary" icon="Plus" @click="openAdd">
          自定义新增按钮
        </el-button>
      </template>
      <template #topLeft="{ size }">
        <el-button :size="size" type="default" icon="Download">
          导出1
        </el-button>
        <el-button :size="size" type="default" icon="Download">
          导出2
        </el-button>
      </template>
      <template #topRight="{ size }"> 合计:2 </template>
      <template #nameSearch="{ size, loading }">
        <span>谁规定这里不能放文本的</span>
      </template>
      <template #name="{ row, $index }">
        <span>{{ row.name }}-{{ $index }}</span>
      </template>
      <template #menu="{ row, $index }">
        <el-link style="margin-right: 6px" @click="openEdit(row, $index)"
          >自定义编辑</el-link
        >
        <el-link @click="openDel(row, $index)">自定义删除</el-link>
      </template>
      <template #allTop="{ size, loading }">
        <span>顶部自定义</span>
      </template>
      <template #allBottom="{ size, loading }">
        <span>底部自定义</span>
      </template>
      <template #nameForm="{ size, loading }">
        <el-button :size="size" :loading="loading">其实也可以是按钮</el-button>
      </template>
    </MCrud>
  </div>
</template>

Crud API

Crud Attributes

属性名说明类型默认值
v-model:search查询表单绑定数据object{}
v-model/v-model:modelValue表单绑定数据object{}
data表格数据array[]
size组件尺寸default | small | large--
loading加载状态booleanfalse
total列表数据总条数number0
permission权限对象object{}
v-model:select表格选择数据array[]
beforeEnter表单提交前是否通过函数Promise<boolean>--
option配置ICrudOption--

Crud 事件

名称说明类型
rowSave新增模式点击保存按钮,表单校验通过后触发(form:表单数据,done:处理新增逻辑后结束函数,loading:关闭表单的 loading 状态)(form: any, done: () => void, loading: () => void) => void
rowEdit编辑模式点击保存按钮,表单校验通过后触发(form:表单数据,done:处理编辑逻辑后结束函数,loading:关闭表单的 loading 状态)(form: any, done: () => void, loading: () => void) => void
rowCancel点击取消按钮触发(form:表单数据,index:当前列表数据的对应索引,type:弹窗模式)(form: any, index: number, type: 'add' | 'edit' | 'view') => void
rowDel点击删除并确认后触发事件(row:当前操作数据,index:当前列表数据的对应索引)(row: any, index: number) => void
search查询触发事件(form: any) => void
reset重置触发事件() => void

Crud 插槽

名称说明
prop 值列表插槽{row, $index}
addBtn自定义新增按钮{size}
editBtn自定义编辑按钮{row, $index}
delBtn自定义删除按钮{row, $index}
menu自定义整个操作列{row, $index}
topLeft表格顶部左边区域(不包括新增按钮){size}
topRight表格顶部右边区域{size}
prop 值+Search自定义查询区域某个字段,例如 prop=name,则 nameSearch{size, loading}
allTop表单顶部自定义(包括新增/编辑/查看){size, loading}
formTop新增/编辑顶部自定义{size, loading}
addTop新增顶部自定义{size, loading}
editTop编辑顶部自定义{size, loading}
viewTop查看顶部自定义{size, loading}
prop 值+Form自定义表单某个字段,例如 prop=name,则 nameForm{size, loading}
allBottom表单底部自定义(包括新增/编辑/查看){size, loading}
formBottom新增/编辑顶部自定义{size, loading}
addBottom新增顶部自定义{size, loading}
editBottom编辑顶部自定义{size, loading}
viewBottom查看顶部自定义{size, loading}

Crud Exposes

名称说明类型
rowAdd打开新增弹窗() => void
rowEdit打开编辑弹窗(row:表单数据,index:列表索引)(row:any,index:number) => void
rowView打开详情弹窗(row:表单数据,index:列表索引)(row:any,index:number) => void
rowDel打开删除确认框(row:表单数据,index:列表索引)(row:any,index:number) => void

额外类型

ICrudOption

属性名说明类型默认值
searchBtnText搜索按钮文字string搜 索
resetBtnText清空按钮文字string清 空
searchBtnIcon搜索按钮图标stringSearch
resetBtnIcon清空按钮文字stringDelete
colIndex收缩展示个数number3
col是否开启收缩booleanfalse
menu是否显示操作列booleanfalse
stripe是否显示斑马纹booleanfalse
border是否显示纵向边框booleanfalse
menuWidth操作栏宽度number220
menuFixed操作栏列冻结列 ,true 表示固定在左侧true | 'left' | 'right''right'
menuAlign操作栏按钮的对齐方式'left' | 'center' | 'right''center'
menuTitle操作栏标题名称string'操作'
addBtn新增按钮是否需要booleantrue
editBtn编辑按钮是否需要booleantrue
delBtn删除按钮是否需要booleantrue
addBtnText新增按钮图标string'新 增'
addBtnIcon新增按钮图标string'Plus'
searchLabelWidth搜索 label 宽度string'80px'
formLabelWidth表单 label 宽度string'80px'
addDialogTitle新增弹窗标题string'新增'
editDialogTitle编辑弹窗标题string'编辑'
viewDialogTitle查看弹窗标题string'查看'
dialogWidth弹窗宽度string'800px'
height表格高度string--
maxHeight表格最大高度string--
calcHeight表格高度调节(px)number--
column配置项ICrudColumn[][]

ICrudColumn

属性名说明类型默认值
label标题string--
prop字段名string--
dicData数据字典值{label: string, value: any}[][]
dicUrl数据字典接口 url 地址string--
dicQuery数据字典接口请求参数Record<string, any>--
dicHeaders数据字典接口请求头参数Record<string, any>--
dicFormatter数据字典接口返回数据格式化方法(res: any) => { list: any[]; label: string; value: string }--
multipletype=select 时是否多选booleanfalse
clearabletype=select 或时间类型 时是否可清空booleanfalse
filterabletype=select 时是否可搜索booleanfalse
filterMethodtype=select 时自定义搜索方法(keyword: string) => void--
remotetype=select 时是否可远程搜索boolean--
remoteMethodtype=select 时远程搜索方法(keyword: string) => void--
loadingtype=select 时且开启 remote 远程搜索时候的加载状态boolean--
imgWidthtype=picture 时图片宽度string'70px'
imgHeighttype=picture 时图片高度string'70px'
imgPrefixtype=picture 时图片 url 前缀string--
imgSuffixtype=picture 时图片 url 字符串间隔string';'
startPlaceholder时间范围选择器中开始时间的占位符string--
endPlaceholder时间范围选择器中结束时间的占位符string--
format时间类型选择器输入框显示时间的格式stringYYYY-MM-DD/YYYY-MM-DD HH:mm:ss
valueFormat时间类型选择器绑定值时间的格式stringYYYY-MM-DD/YYYY-MM-DD HH:mm:ss
searchLabelWidth单个搜索标签文字宽度string'80px'
formLabelWidth单个表单标签文字宽度string'80px'
searchOrder搜索排序字段number--
formOrder表单排序字段number--
searchRules单个搜索校验FormItemRule[]--
formRules单个表单校验FormItemRule[]--
searchSpan单个搜索占据的栅栏宽度number6
formSpan所有模式下单个表单占据的栅栏宽度number6
addSpan新增模式下单个表单占据的栅栏宽度number6
viewSpan查看模式下单个表单占据的栅栏宽度number6
editSpan编辑模式下单个表单占据的栅栏宽度number6
maxlength输入框最大输入长度number--
searchValue单个搜索属性的默认值any--
formValue单个表单属性的默认值any--
searchPlaceholder搜索占位文本string--
formPlaceholder表单占位文本string--
type类型string--

Column Type

名称说明
index索引列
single单选
selection多选
input输入框
number数字输入框
textarea文本域输入框
password密码输入框
year年选择器
month月选择器
date日期选择器
datetime日期时间选择器
week周选择器
datetimerange日期时间范围选择器
daterange日期范围选择器
monthrange月份范围选择器
yearrange年范围选择器
time时间选择器
timerange时间范围选择器
select下拉选择
checkbox多选框
radio单选框
switch切换框
picture图片展示
qrcode二维码展示
barcode一维码展示