1.1.2 • Published 6 months ago

easy-element-components-ui v1.1.2

Weekly downloads
-
License
ISC
Repository
-
Last release
6 months ago

Easy Element

基于 vue2x, Element UI 的增强型组件库,提供了更强大的表单、表格、列表等组件,帮助你快速构建后台管理系统。

特性

  • 🚀 基于 Element UI,提供更强大的组件
  • 📦 开箱即用,快速构建后台管理系统
  • 🎨 支持自定义主题,继承 Element UI 的样式系统
  • 🔧 高度可配置,满足各种业务场景
  • 📝 详细的文档和示例
  • 🔥 支持表单联动、动态渲染、自定义校验等高级特性

目录

安装

NPM

npm install easy-element element-ui --save

YARN

yarn add easy-element element-ui

快速开始

完整引入

import Vue from "vue";
import ElementUI from "element-ui";
import EasyElement from "easy-element";
import "element-ui/lib/theme-chalk/index.css";
import "easy-element/lib/theme-chalk/index.css";

Vue.use(ElementUI);
Vue.use(EasyElement);

按需引入

首先,安装 babel-plugin-component:

npm install babel-plugin-component -D

然后,修改 .babelrc:

{
  "plugins": [
    [
      "component",
      {
        "libraryName": "easy-element",
        "styleLibraryName": "theme-chalk"
      }
    ]
  ]
}

接下来,你可以按需引入组件:

import Vue from "vue";
import { EasyElementForm, EasyElementTable } from "easy-element";

Vue.use(EasyElementForm);
Vue.use(EasyElementTable);

组件

Form 表单

表单组件提供了快速创建表单的能力,支持多种输入类型、表单验证、条件渲染等功能。

基础用法

<template>
  <easy-element-form
    v-model="formData"
    :form-item-list="formItemList"
  />
</template>

<script>
export default {
  data() {
    return {
      formData: {},
      formItemList: [
        {
          label: '用户名',
          fromDataKey: 'username',
          cellType: 'input',
          isRequired: true,
          cellAttriBute: {
            props: {
              placeholder: '请输入用户名'
            }
          }
        },
        {
          label: '性别',
          fromDataKey: 'gender',
          cellType: 'select',
          dataSource: {
            labelKey: 'label',
            valueKey: 'value',
            list: [
              { label: '男', value: 1 },
              { label: '女', value: 2 }
            ]
          }
        }
      ]
    }
  }
}
</script>

自定义渲染

使用 format 函数可以完全自定义表单项的渲染内容:

{
  label: '自定义',
  fromDataKey: 'custom',
  format(formData, item, h, value) {
    return h('div', [
      h('el-input', {
        props: {
          value: value
        },
        on: {
          input: (val) => {
            formData[item.fromDataKey] = val
          }
        }
      }),
      h('el-button', {
        on: {
          click: () => {
            // 处理点击事件
          }
        }
      }, '点击')
    ])
  }
}

动态属性配置

cellAttriBute 支持函数形式,可以根据表单数据动态配置组件属性:

{
  label: '动态配置',
  fromDataKey: 'dynamic',
  cellType: 'select',
  cellAttriBute(formData, item) {
    return {
      props: {
        disabled: !formData.isEnabled,
        placeholder: formData.type === 1 ? '请选择' : '暂不可选'
      }
    }
  }
}

API

Props
参数说明类型默认值
v-model / formDataObj表单数据对象Object{}
form-item-list表单项配置列表Array[]
form-attribute表单属性配置,继承 el-form 的属性Object{}
cell-rander-before单元格渲染前的处理函数,返回 false 时不渲染该项Function(item, formData)-
cell-item-format表单项格式化函数,可以在渲染前修改配置Function(item, formData)-
read-only是否只读模式Booleanfalse
disabled是否禁用Booleanfalse
FormItem 配置
参数说明类型默认值
label表单项标签String-
fromDataKey表单数据的键名String-
cellType单元格类型,可选值:input/select/dateTime/numberInput/floatButton/redioGroup/checkBoxGroupString-
isRequired是否必填Booleanfalse
cellAttriBute单元格组件的属性配置,支持对象或函数形式Object/Function(formData, item){}
fromItemAttribute表单项属性配置,继承 el-form-item 的属性Object{}
dataSource数据源配置(用于 select/redioGroup/checkBoxGroup)Object{}
format自定义渲染函数Function(formData, item, h, value)-
dataSource 配置
参数说明类型默认值
labelKey选项标签的键名String-
valueKey选项值的键名String-
list选项数据列表Array[]
Methods
方法名说明参数
validate表单验证-
getFormData获取表单数据,支持验证(isValidate = true, isPromise = true)

表单校验

<template>
  <easy-element-form
    ref="form"
    v-model="formData"
    :form-item-list="formItemList"
  >
    <template #btns>
      <el-button type="primary" @click="handleSubmit">提交</el-button>
      <el-button @click="handleReset">重置</el-button>
    </template>
  </easy-element-form>
</template>

<script>
export default {
  data() {
    return {
      formData: {},
      formItemList: [
        {
          label: '用户名',
          fromDataKey: 'username',
          cellType: 'input',
          fromItemAttribute: {
            props: {
              rules: [
                { required: true, message: '请输入用户名', trigger: 'blur' },
                { min: 3, max: 20, message: '长度在 3 到 20 个字符', trigger: 'blur' }
              ]
            }
          }
        }
      ]
    }
  },
  methods: {
    handleSubmit() {
      this.$refs.form.validate((valid) => {
        if (valid) {
          console.log('表单数据:', this.formData)
        }
      })
    },
    handleReset() {
      this.$refs.form.resetFields()
    }
  }
}
</script>

数据联动

Form 组件提供了多种方式实现表单联动:

  1. 通过 cellAttriBute 函数动态配置组件属性:
{
  label: '城市',
  fromDataKey: 'city',
  cellType: 'select',
  cellAttriBute: (formData) => {
    return {
      props: {
        disabled: !formData.province, // 未选择省份时禁用
        placeholder: formData.province ? '请选择城市' : '请先选择省份'
      }
    }
  }
}
  1. 通过 cellchildVNode 函数动态渲染选项:
{
  label: '城市',
  fromDataKey: 'city',
  cellType: 'select',
  // 动态渲染选项
  cellchildVNode: (formData, item, h) => {
    // 根据省份显示对应的城市列表
    const cityMap = {
      zj: [
        { label: '杭州', value: 'hz' },
        { label: '宁波', value: 'nb' }
      ],
      js: [
        { label: '南京', value: 'nj' },
        { label: '苏州', value: 'sz' }
      ]
    }
    const cityList = cityMap[formData.province] || []
    return cityList.map(city => {
      return h('el-option', {
        props: {
          key: city.value,
          label: city.label,
          value: city.value
        }
      })
    })
  }
}
  1. 通过 cellRanderBefore 函数控制表单项的显示/隐藏:
{
  label: '其他信息',
  fromDataKey: 'otherInfo',
  cellType: 'input',
  cellRanderBefore: (item, formData) => {
    // 当类型为 "other" 时显示
    return formData.type === 'other'
  }
}
  1. 通过 format 函数实现复杂的自定义联动:
{
  label: '自定义联动',
  fromDataKey: 'custom',
  format: (formData, item, h, value) => {
    // 根据条件返回不同的渲染内容
    if (formData.type === 'text') {
      return h('el-input', {
        props: {
          value: value
        },
        on: {
          input: (val) => {
            formData[item.fromDataKey] = val
          }
        }
      })
    } else if (formData.type === 'select') {
      return h('el-select', {
        props: {
          value: value
        },
        on: {
          input: (val) => {
            formData[item.fromDataKey] = val
          }
        }
      }, [
        h('el-option', {
          props: {
            label: '选项1',
            value: 1
          }
        }),
        h('el-option', {
          props: {
            label: '选项2',
            value: 2
          }
        })
      ])
    }
  }
}

完整的联动示例:

<template>
  <easy-element-form
    ref="form"
    v-model="formData"
    :form-item-list="formItemList"
    :cell-rander-before="cellRanderBefore"
  />
</template>

<script>
export default {
  data() {
    return {
      formData: {},
      formItemList: [
        {
          label: '省份',
          fromDataKey: 'province',
          cellType: 'select',
          dataSource: {
            labelKey: 'label',
            valueKey: 'value',
            list: [
              { label: '浙江', value: 'zj' },
              { label: '江苏', value: 'js' }
            ]
          }
        },
        {
          label: '城市',
          fromDataKey: 'city',
          cellType: 'select',
          // 动态禁用/启用
          cellAttriBute: (formData) => ({
            props: {
              disabled: !formData.province,
              placeholder: formData.province ? '请选择城市' : '请先选择省份'
            }
          }),
          // 基础数据源配置
          dataSource: {
            labelKey: 'label',
            valueKey: 'value',
            list: []
          },
          // 动态渲染选项
          cellchildVNode: (formData, item, h) => {
            const cityMap = {
              zj: [
                { label: '杭州', value: 'hz' },
                { label: '宁波', value: 'nb' }
              ],
              js: [
                { label: '南京', value: 'nj' },
                { label: '苏州', value: 'sz' }
              ]
            }
            const cityList = cityMap[formData.province] || []
            return cityList.map(city => {
              return h('el-option', {
                props: {
                  key: city.value,
                  label: city.label,
                  value: city.value
                }
              })
            })
          }
        },
        {
          label: '类型',
          fromDataKey: 'type',
          cellType: 'select',
          dataSource: {
            labelKey: 'label',
            valueKey: 'value',
            list: [
              { label: '个人', value: 1 },
              { label: '企业', value: 2 }
            ]
          }
        },
        {
          label: '身份证号',
          fromDataKey: 'idCard',
          cellType: 'input'
        },
        {
          label: '营业执照',
          fromDataKey: 'license',
          cellType: 'input'
        }
      ]
    }
  },
  methods: {
    cellRanderBefore(item, formData) {
      // 根据类型控制表单项的显示/隐藏
      if (item.fromDataKey === 'idCard') {
        return formData.type === 1
      }
      if (item.fromDataKey === 'license') {
        return formData.type === 2
      }
      return true
    }
  },
  watch: {
    // 当省份变化时,清空城市选择
    'formData.province'(val) {
      this.formData.city = ''
    }
  }
}
</script>

这个示例展示了:

  1. 省市联动:

    • 城市选择器根据省份动态启用/禁用
    • 城市选项通过 cellchildVNode 动态渲染
    • 切换省份时自动清空城市选择
  2. 条件显示:

    • 根据类型显示不同的证件输入框(个人显示身份证号,企业显示营业执照)
    • 通过 cell-rander-before 控制显示/隐藏
  3. 动态渲染:

    • 根据类型切换不同的表单控件

QueryForm 查询表单

基于 Form 组件封装的查询表单组件,提供了快速配置查询条件、按钮和布局的能力。

基础用法

<template>
  <easy-element-query-form
    ref="queryForm"
    v-model="formData"
    :form-item-list="formItemList"
    :get-query-data-call-back="handleQuery"
  />
</template>

<script>
export default {
  data() {
    return {
      formData: {},
      formItemList: [
        {
          label: '用户名',
          fromDataKey: 'username',
          cellType: 'input',
          cellAttriBute: {
            attrs: {
              placeholder: '请输入用户名',
              clearable: true
            }
          }
        },
        {
          label: '状态',
          fromDataKey: 'status',
          cellType: 'select',
          dataSource: {
            labelKey: 'label',
            valueKey: 'value',
            list: [
              { label: '全部', value: '' },
              { label: '启用', value: 1 },
              { label: '禁用', value: 0 }
            ]
          }
        }
      ]
    }
  },
  methods: {
    handleQuery(queryData) {
      console.log('查询参数:', queryData)
    }
  }
}
</script>

自定义按钮

<template>
  <easy-element-query-form
    ref="queryForm"
    v-model="formData"
    :form-item-list="formItemList"
    :get-query-data-call-back="handleQuery"
    :is-show-default-btn="false"
  >
    <template #btns>
      <el-button type="primary" @click="handleSearch">查询</el-button>
      <el-button @click="handleReset">重置</el-button>
      <el-button type="success" @click="handleExport">导出</el-button>
    </template>
  </easy-element-query-form>
</template>

<script>
export default {
  data() {
    return {
      formData: {},
      formItemList: [
        {
          label: '用户名',
          fromDataKey: 'username',
          cellType: 'input'
        }
      ]
    }
  },
  methods: {
    handleSearch() {
      const queryData = this.$refs.queryForm.getQueryData()
      console.log('查询:', queryData)
    },
    handleReset() {
      this.$refs.queryForm.resetFields()
    },
    handleExport() {
      const queryData = this.$refs.queryForm.getQueryData()
      console.log('导出:', queryData)
    }
  }
}
</script>

API

Props
参数说明类型默认值
form-item-list表单项配置列表Array[]
get-query-data-call-back查询回调函数Function(queryData)-
is-show-default-btn是否显示默认按钮(查询、重置)Booleantrue
query-btn-config查询按钮配置Object{}
reset-btn-config重置按钮配置Object{}
form-attribute表单属性配置,继承 el-form 的属性Object{}
Methods
方法名说明参数
getQueryData获取查询参数-
resetFields重置表单-
validate表单校验-
Events
事件名说明参数
query点击查询按钮时触发(queryData: Object)
reset点击重置按钮时触发-
Slots
插槽名说明
btns自定义按钮区域

DataList 数据列表

基于 QueryForm 和 Table 组件的组合组件,提供了完整的数据列表解决方案,包括查询条件、数据展示和分页功能。

基础用法

<template>
  <easy-element-data-list
    ref="dataList"
    :query-form-attribute="queryFormAttribute"
    :table-attribute="tableAttribute"
    :get-data-callback="getDataCallback"
    :is-enable-query-model="true"
    :is-enable-pagination="true"
  />
</template>

<script>
export default {
  data() {
    return {
      // 查询表单配置
      queryFormAttribute: {
        formItemList: [
          {
            label: '用户名',
            fromDataKey: 'username',
            cellType: 'input'
          },
          {
            label: '状态',
            fromDataKey: 'status',
            cellType: 'select',
            dataSource: {
              labelKey: 'label',
              valueKey: 'value',
              list: [
                { label: '启用', value: 1 },
                { label: '禁用', value: 0 }
              ]
            }
          }
        ]
      },
      // 表格配置
      tableAttribute: {
        columns: [
          {
            props: {
              prop: 'username',
              label: '用户名'
            }
          },
          {
            props: {
              prop: 'status',
              label: '状态'
            },
            defaultComponents: {
              cellType: 'select',
              dataSource: {
                labelKey: 'label',
                valueKey: 'value',
                list: [
                  { label: '启用', value: 1 },
                  { label: '禁用', value: 0 }
                ]
              }
            }
          },
          {
            props: {
              prop: 'operation',
              label: '操作',
              width: '150px',
              fixed: 'right'
            },
            format: (h, scope) => {
              return [
                h('el-button', {
                  props: {
                    type: 'text',
                    size: 'small'
                  },
                  on: {
                    click: () => this.handleEdit(scope.row)
                  }
                }, '编辑'),
                h('el-button', {
                  props: {
                    type: 'text',
                    size: 'small',
                    type: 'danger'
                  },
                  on: {
                    click: () => this.handleDelete(scope.row)
                  }
                }, '删除')
              ]
            }
          }
        ]
      }
    }
  },
  methods: {
    // 获取数据的回调函数
    async getDataCallback(params) {
      try {
        const res = await this.fetchData(params)
        return {
          data: res.data,
          total: res.total
        }
      } catch (error) {
        return {
          data: [],
          total: 0
        }
      }
    },
    // 编辑
    handleEdit(row) {
      console.log('编辑:', row)
    },
    // 删除
    handleDelete(row) {
      console.log('删除:', row)
    },
    // 刷新列表
    refreshList() {
      this.$refs.dataList.refresh()
    }
  }
}
</script>

API

Props
参数说明类型默认值
query-form-attribute查询表单配置Object{}
table-attribute表格配置Object{}
get-data-callback获取数据的回调函数Function(params)-
is-enable-query-model是否启用查询模式Booleantrue
is-enable-pagination是否启用分页Booleantrue
pagination-attribute分页配置Object{}
is-show-default-btn是否显示默认按钮(查询、重置)Booleantrue
query-btn-config查询按钮配置Object{}
reset-btn-config重置按钮配置Object{}
Methods
方法名说明参数
refresh刷新列表数据-
resetFields重置查询表单-
getQueryData获取查询参数-
Events
事件名说明参数
query点击查询按钮时触发(queryData: Object)
reset点击重置按钮时触发-
size-change分页大小改变时触发(size: Number)
current-change当前页改变时触发(current: Number)

Table 表格组件

基于 Element UI 的 Table 组件封装,支持快速配置列、自定义渲染、排序、编辑等功能。

基础用法

<template>
  <easy-element-table
    :data="tableData"
    :columns="columns"
  />
</template>

<script>
export default {
  data() {
    return {
      tableData: [
        {
          id: 1,
          name: '张三',
          age: 25,
          status: 1
        }
      ],
      columns: [
        {
          props: {
            prop: 'name',
            label: '姓名'
          }
        },
        {
          props: {
            prop: 'age',
            label: '年龄'
          },
          defaultComponents: {
            cellType: 'numberInput'
          }
        },
        {
          props: {
            prop: 'status',
            label: '状态'
          },
          defaultComponents: {
            cellType: 'select',
            dataSource: {
              labelKey: 'label',
              valueKey: 'value',
              list: [
                { label: '启用', value: 1 },
                { label: '禁用', value: 0 }
              ]
            }
          }
        }
      ]
    }
  }
}
</script>

可编辑表格

<template>
  <easy-element-table
    :data="tableData"
    :columns="columns"
    :is-enable-edit="true"
    @cell-value-change="handleCellChange"
  />
</template>

<script>
export default {
  data() {
    return {
      tableData: [
        {
          id: 1,
          name: '张三',
          age: 25,
          status: 1
        }
      ],
      columns: [
        {
          props: {
            prop: 'name',
            label: '姓名'
          },
          defaultComponents: {
            cellType: 'input'
          }
        },
        {
          props: {
            prop: 'age',
            label: '年龄'
          },
          defaultComponents: {
            cellType: 'numberInput'
          }
        },
        {
          props: {
            prop: 'status',
            label: '状态'
          },
          defaultComponents: {
            cellType: 'select',
            dataSource: {
              labelKey: 'label',
              valueKey: 'value',
              list: [
                { label: '启用', value: 1 },
                { label: '禁用', value: 0 }
              ]
            }
          }
        }
      ]
    }
  },
  methods: {
    handleCellChange({ row, prop, value }) {
      console.log('单元格值变更:', row, prop, value)
    }
  }
}
</script>

API

Props
参数说明类型默认值
data表格数据Array[]
columns列配置Array[]
is-enable-edit是否启用编辑模式Booleanfalse
is-enable-selection是否启用多选Booleanfalse
table-attribute表格属性配置,继承 el-table 的属性Object{}
Column 配置
参数说明类型默认值
props列属性配置,继承 el-table-column 的属性Object{}
format自定义渲染函数Function(h, scope)-
defaultComponents默认组件配置,用于编辑模式Object{}
Methods
方法名说明参数
getSelectedRows获取选中行数据-
clearSelection清空选中状态-
toggleRowSelection切换某一行的选中状态(row, selected)
Events
事件名说明参数
cell-value-change单元格值变更时触发{ row, prop, value }
selection-change选中项发生变化时触发selection
row-click行点击时触发row, column, event

通用配置

cellType 类型

组件库提供了以下几种单元格类型,每种类型都有其特定的必填参数和可选参数:

类型说明必填参数可选参数备注
input输入框-type: 输入框类型maxlength: 最大长度showWordLimit: 是否显示字数统计type 支持 text、textarea、password 等默认启用 clearable
select下拉选择器dataSource: {  labelKey: 显示字段名  valueKey: 值字段名  list: 选项数组}filterable: 是否可搜索multiple: 是否多选remote: 是否远程搜索remoteMethod: 远程搜索方法支持本地数据和远程搜索默认启用 clearable
dateTime日期时间选择器-type: 选择器类型valueFormat: 值格式dataTimeSetting: {  maxDate: 最大日期  minDate: 最小日期  dateInterval: 日期间隔}type 支持:date/datetime/daterange/datetimerange/monthrange默认值格式:yyyy-MM-dd
numberInput数字输入框-min: 最小值max: 最大值precision: 精度step: 步长支持精度控制和步进设置默认启用 clearable
floatButton浮点数输入框-min: 最小值max: 最大值precision: 精度append: 后缀(如 %)支持百分比等特殊格式当 append="%" 时自动处理百分比转换
radioGroup单选框组dataSource: {  labelKey: 显示字段名  valueKey: 值字段名  list: 选项数组}--
checkBoxGroup复选框组dataSource: {  labelKey: 显示字段名  valueKey: 值字段名  list: 选项数组}min: 最小选中数max: 最大选中数-

示例:

  1. select 类型(必填 dataSource):
{
  cellType: 'select',
  dataSource: {
    labelKey: 'label',
    valueKey: 'value',
    list: [
      { label: '选项1', value: 1 },
      { label: '选项2', value: 2 }
    ]
  }
}
  1. dateTime 类型(带日期限制):
{
  cellType: 'dateTime',
  cellAttriBute: {
    props: {
      type: 'daterange'
    }
  },
  dataTimeSetting: {
    maxDate: new Date('2024-12-31'),
    minDate: new Date('2024-01-01'),
    dateInterval: 30 // 日期范围最大间隔30天
  }
}
  1. numberInput 类型(带精度和范围限制):
{
  cellType: 'numberInput',
  cellAttriBute: {
    props: {
      min: 0,
      max: 100,
      precision: 2,
      step: 0.1
    }
  }
}
  1. floatButton 类型(百分比格式):
{
  cellType: 'floatButton',
  cellAttriBute: {
    props: {
      precision: 2,
      min: 0,
      max: 1
    },
    attrs: {
      append: '%'
    }
  }
}

数据源配置

用于 select、radioGroup、checkBoxGroup 等需要选项数据的组件:

{
  // 显示字段名
  labelKey: 'label',
  // 值字段名
  valueKey: 'value',
  // 数据列表
  list: [
    { label: '选项1', value: 1 },
    { label: '选项2', value: 2 }
  ]
}

表单校验

表单校验规则继承自 Element UI 的表单校验规则,在 fromItemAttribute.props.rules 中配置:

{
  fromItemAttribute: {
    props: {
      rules: [
        { required: true, message: "必填项" },
        { min: 3, max: 20, message: "长度在 3 到 20 个字符" },
        { type: "email", message: "请输入正确的邮箱地址" },
        {
          validator: (rule, value, callback) => {
            if (value === "") {
              callback(new Error("请输入"));
            } else if (value < 0) {
              callback(new Error("不能小于0"));
            } else {
              callback();
            }
          },
          trigger: "blur",
        },
      ];
    }
  }
}

自定义渲染

通过 format 函数可以实现完全自定义的渲染内容,函数接收以下参数:

  • formData/row: 当前行/表单数据
  • item/column: 当前配置项
  • h: 渲染函数
  • value: 当前字段值(可选)
{
  format: (formData, item, h, value) => {
    return h("div", [
      h("el-input", {
        props: {
          value: value,
        },
        on: {
          input: (val) => {
            formData[item.fromDataKey] = val;
          },
        },
      }),
      h(
        "el-button",
        {
          props: {
            type: "text",
          },
          on: {
            click: () => {
              // 处理点击事件
            },
          },
        },
        "按钮"
      ),
    ]);
  };
}

条件渲染

通过 cell-rander-before 属性可以控制表单项的显示/隐藏:

<template>
  <easy-element-form
    ref="form"
    v-model="formData"
    :form-item-list="formItemList"
    :cell-rander-before="cellRanderBefore"
  />
</template>

<script>
export default {
  data() {
    return {
      formData: {},
      formItemList: [
        {
          label: '类型',
          fromDataKey: 'type',
          cellType: 'select',
          dataSource: {
            labelKey: 'label',
            valueKey: 'value',
            list: [
              { label: '个人', value: 1 },
              { label: '企业', value: 2 }
            ]
          }
        },
        {
          label: '身份证号',
          fromDataKey: 'idCard',
          cellType: 'input'
        },
        {
          label: '营业执照',
          fromDataKey: 'license',
          cellType: 'input'
        }
      ]
    }
  },
  methods: {
    cellRanderBefore(item, formData) {
      // 根据类型控制表单项的显示/隐藏
      if (item.fromDataKey === 'idCard') {
        return formData.type === 1
      }
      if (item.fromDataKey === 'license') {
        return formData.type === 2
      }
      return true
    }
  }
}
</script>

在上面的示例中:

  • 当类型选择"个人"时,显示身份证号输入框
  • 当类型选择"企业"时,显示营业执照输入框
  • 类型选择框始终显示

动态属性

cellAttriButefromItemAttribute 支持函数形式,可以根据数据动态返回配置:

{
  cellAttriBute: (formData) => ({
    props: {
      disabled: formData.status === 0,
    },
  });
}

常见问题

如何实现表单联动?

可以通过以下几种方式实现表单联动:

  1. 监听 formData 的变化:
watch: {
  'formData.type'(newType) {
    // 根据类型变化清空或设置其他字段
    this.formData.content = ''
  }
}
  1. 使用 cell-rander-before 控制显示隐藏:
<easy-element-form
  v-model="formData"
  :form-item-list="formItemList"
  :cell-rander-before="cellRanderBefore"
/>

methods: {
  cellRanderBefore(item, formData) {
    // 根据类型控制表单项的显示/隐藏
    if (item.fromDataKey === 'idCard') {
      return formData.type === 1
    }
    if (item.fromDataKey === 'license') {
      return formData.type === 2
    }
    return true
  }
}
  1. 使用动态属性配置:
{
  cellAttriBute: (formData) => ({
    props: {
      disabled: formData.status === 0,
    },
  });
}
  1. 使用 cellchildVNode 动态渲染选项:
{
  label: '城市',
  fromDataKey: 'city',
  cellType: 'select',
  // 基础数据源配置
  dataSource: {
    labelKey: 'label',
    valueKey: 'value',
    list: []
  },
  // 动态渲染选项
  cellchildVNode: (formData, item, h) => {
    const cityMap = {
      zj: [
        { label: '杭州', value: 'hz' },
        { label: '宁波', value: 'nb' }
      ],
      js: [
        { label: '南京', value: 'nj' },
        { label: '苏州', value: 'sz' }
      ]
    }
    const cityList = cityMap[formData.province] || []
    return cityList.map(city => {
      return h('el-option', {
        props: {
          key: city.value,
          label: city.label,
          value: city.value
        }
      })
    })
  }
}

完整的联动示例:

<template>
  <easy-element-form
    ref="form"
    v-model="formData"
    :form-item-list="formItemList"
    :cell-rander-before="cellRanderBefore"
  />
</template>

<script>
export default {
  data() {
    return {
      formData: {},
      formItemList: [
        {
          label: '省份',
          fromDataKey: 'province',
          cellType: 'select',
          dataSource: {
            labelKey: 'label',
            valueKey: 'value',
            list: [
              { label: '浙江', value: 'zj' },
              { label: '江苏', value: 'js' }
            ]
          }
        },
        {
          label: '城市',
          fromDataKey: 'city',
          cellType: 'select',
          // 动态禁用/启用
          cellAttriBute: (formData) => ({
            props: {
              disabled: !formData.province,
              placeholder: formData.province ? '请选择城市' : '请先选择省份'
            }
          }),
          // 基础数据源配置
          dataSource: {
            labelKey: 'label',
            valueKey: 'value',
            list: []
          },
          // 动态渲染选项
          cellchildVNode: (formData, item, h) => {
            const cityMap = {
              zj: [
                { label: '杭州', value: 'hz' },
                { label: '宁波', value: 'nb' }
              ],
              js: [
                { label: '南京', value: 'nj' },
                { label: '苏州', value: 'sz' }
              ]
            }
            const cityList = cityMap[formData.province] || []
            return cityList.map(city => {
              return h('el-option', {
                props: {
                  key: city.value,
                  label: city.label,
                  value: city.value
                }
              })
            })
          }
        },
        {
          label: '类型',
          fromDataKey: 'type',
          cellType: 'select',
          dataSource: {
            labelKey: 'label',
            valueKey: 'value',
            list: [
              { label: '个人', value: 1 },
              { label: '企业', value: 2 }
            ]
          }
        },
        {
          label: '身份证号',
          fromDataKey: 'idCard',
          cellType: 'input'
        },
        {
          label: '营业执照',
          fromDataKey: 'license',
          cellType: 'input'
        }
      ]
    }
  },
  methods: {
    cellRanderBefore(item, formData) {
      // 根据类型控制表单项的显示/隐藏
      if (item.fromDataKey === 'idCard') {
        return formData.type === 1
      }
      if (item.fromDataKey === 'license') {
        return formData.type === 2
      }
      return true
    }
  },
  watch: {
    // 当省份变化时,清空城市选择
    'formData.province'(val) {
      this.formData.city = ''
    }
  }
}
</script>

这个示例展示了:

  1. 省市联动:

    • 城市选择器根据省份动态启用/禁用
    • 城市选项通过 cellchildVNode 动态渲染
    • 切换省份时自动清空城市选择
  2. 条件显示:

    • 根据类型显示不同的证件输入框(个人显示身份证号,企业显示营业执照)
    • 通过 cell-rander-before 控制显示/隐藏
  3. 动态渲染:

    • 根据类型切换不同的表单控件

如何实现远程搜索?

在 select 类型的组件中配置 remote 相关属性:

{
  cellType: 'select',
  cellAttriBute: {
    props: {
      filterable: true,
      remote: true,
      remoteMethod: (query) => {
        // 远程搜索逻辑
        return searchAPI(query).then(res => {
          this.options = res.data
        })
      }
    }
  }
}

如何自定义校验规则?

可以在 rules 中使用 validator 函数实现自定义校验:

{
  fromItemAttribute: {
    props: {
      rules: [
        {
          validator: (rule, value, callback) => {
            if (value === "") {
              callback(new Error("请输入"));
            } else if (!/^[A-Z]/.test(value)) {
              callback(new Error("必须以大写字母开头"));
            } else {
              callback();
            }
          },
          trigger: "blur",
        },
      ];
    }
  }
}

完整的增删改查示例

下面是一个完整的用户管理示例,包含查询、新增、编辑、删除功能:

<template>
  <div class="user-management">
    <!-- 数据列表组件 -->
    <easy-element-data-list
      ref="dataList"
      :query-form-attribute="queryFormAttribute"
      :table-attribute="tableAttribute"
      :get-data-callback="getDataCallback"
      :is-enable-query-model="true"
      :is-enable-pagination="true"
    />

    <!-- 新增/编辑弹窗 -->
    <el-dialog
      :title="dialogTitle"
      :visible.sync="dialogVisible"
      width="500px"
      @close="handleDialogClose"
    >
      <easy-element-form
        ref="form"
        v-model="formData"
        :form-item-list="formItemList"
      />
      <div slot="footer">
        <el-button @click="dialogVisible = false">取消</el-button>
        <el-button type="primary" @click="handleSubmit">确定</el-button>
      </div>
    </el-dialog>
  </div>
</template>

<script>
export default {
  data() {
    return {
      // 查询表单配置
      queryFormAttribute: {
        formItemList: [
          {
            label: '用户名',
            fromDataKey: 'username',
            cellType: 'input',
            cellAttriBute: {
              attrs: {
                placeholder: '请输入用户名',
                clearable: true
              }
            }
          },
          {
            label: '部门',
            fromDataKey: 'department',
            cellType: 'select',
            dataSource: {
              labelKey: 'label',
              valueKey: 'value',
              list: [
                { label: '技术部', value: 'tech' },
                { label: '产品部', value: 'product' },
                { label: '运营部', value: 'operation' }
              ]
            }
          },
          {
            label: '入职日期',
            fromDataKey: 'joinDate',
            cellType: 'dateTime',
            cellAttriBute: {
              props: {
                type: 'daterange',
                startPlaceholder: '开始日期',
                endPlaceholder: '结束日期'
              }
            }
          }
        ]
      },
      // 表格配置
      tableAttribute: {
        columns: [
          {
            props: {
              prop: 'username',
              label: '用户名'
            }
          },
          {
            props: {
              prop: 'department',
              label: '部门'
            },
            format: (h, { row }) => {
              const deptMap = {
                tech: '技术部',
                product: '产品部',
                operation: '运营部'
              }
              return h('span', deptMap[row.department] || '-')
            }
          },
          {
            props: {
              prop: 'email',
              label: '邮箱'
            }
          },
          {
            props: {
              prop: 'joinDate',
              label: '入职日期'
            }
          },
          {
            props: {
              prop: 'status',
              label: '状态'
            },
            format: (h, { row }) => {
              return h('el-tag', {
                props: {
                  type: row.status === 1 ? 'success' : 'info'
                }
              }, row.status === 1 ? '在职' : '离职')
            }
          },
          {
            props: {
              prop: 'operation',
              label: '操作',
              width: '180px',
              fixed: 'right'
            },
            format: (h, { row }) => {
              return [
                h('el-button', {
                  props: {
                    type: 'text',
                    size: 'small'
                  },
                  on: {
                    click: () => this.handleEdit(row)
                  }
                }, '编辑'),
                h('el-button', {
                  props: {
                    type: 'text',
                    size: 'small',
                    type: 'danger'
                  },
                  on: {
                    click: () => this.handleDelete(row)
                  }
                }, '删除')
              ]
            }
          }
        ]
      },
      // 弹窗表单配置
      formItemList: [
        {
          label: '用户名',
          fromDataKey: 'username',
          cellType: 'input',
          isRequired: true,
          fromItemAttribute: {
            props: {
              rules: [
                { required: true, message: '请输入用户名', trigger: 'blur' },
                { min: 2, max: 20, message: '长度在 2 到 20 个字符', trigger: 'blur' }
              ]
            }
          }
        },
        {
          label: '部门',
          fromDataKey: 'department',
          cellType: 'select',
          isRequired: true,
          dataSource: {
            labelKey: 'label',
            valueKey: 'value',
            list: [
              { label: '技术部', value: 'tech' },
              { label: '产品部', value: 'product' },
              { label: '运营部', value: 'operation' }
            ]
          }
        },
        {
          label: '邮箱',
          fromDataKey: 'email',
          cellType: 'input',
          isRequired: true,
          fromItemAttribute: {
            props: {
              rules: [
                { required: true, message: '请输入邮箱', trigger: 'blur' },
                { type: 'email', message: '请输入正确的邮箱地址', trigger: 'blur' }
              ]
            }
          }
        },
        {
          label: '入职日期',
          fromDataKey: 'joinDate',
          cellType: 'dateTime',
          isRequired: true
        },
        {
          label: '状态',
          fromDataKey: 'status',
          cellType: 'radioGroup',
          dataSource: {
            labelKey: 'label',
            valueKey: 'value',
            list: [
              { label: '在职', value: 1 },
              { label: '离职', value: 0 }
            ]
          }
        }
      ],
      // 弹窗数据
      dialogVisible: false,
      dialogTitle: '新增用户',
      formData: {},
      editingId: null
    }
  },
  methods: {
    // 获取列表数据
    async getDataCallback(params) {
      try {
        // 这里调用实际的接口
        const res = await this.fetchUserList({
          ...params,
          ...params.queryData // 合并查询条件
        })
        return {
          data: res.data,
          total: res.total
        }
      } catch (error) {
        this.$message.error('获取数据失败')
        return {
          data: [],
          total: 0
        }
      }
    },

    // 打开新增弹窗
    handleAdd() {
      this.dialogTitle = '新增用户'
      this.dialogVisible = true
      this.editingId = null
      this.formData = {
        status: 1 // 默认在职
      }
    },

    // 打开编辑弹窗
    handleEdit(row) {
      this.dialogTitle = '编辑用户'
      this.dialogVisible = true
      this.editingId = row.id
      // 复制一份数据,避免直接修改表格数据
      this.formData = { ...row }
    },

    // 删除
    handleDelete(row) {
      this.$confirm('确认删除该用户?', '提示', {
        type: 'warning'
      }).then(async () => {
        try {
          // 调用删除接口
          await this.deleteUser(row.id)
          this.$message.success('删除成功')
          // 刷新列表
          this.$refs.dataList.refresh()
        } catch (error) {
          this.$message.error('删除失败')
        }
      }).catch(() => {})
    },

    // 提交表单
    handleSubmit() {
      this.$refs.form.validate(async (valid) => {
        if (valid) {
          try {
            if (this.editingId) {
              // 编辑
              await this.updateUser({
                id: this.editingId,
                ...this.formData
              })
              this.$message.success('更新成功')
            } else {
              // 新增
              await this.createUser(this.formData)
              this.$message.success('创建成功')
            }
            // 关闭弹窗
            this.dialogVisible = false
            // 刷新列表
            this.$refs.dataList.refresh()
          } catch (error) {
            this.$message.error(this.editingId ? '更新失败' : '创建失败')
          }
        }
      })
    },

    // 关闭弹窗
    handleDialogClose() {
      this.$refs.form.resetFields()
      this.formData = {}
      this.editingId = null
    },

    // API 调用方法
    async fetchUserList(params) {
      // 实现查询接口调用
      return await this.$http.get('/api/users', { params })
    },

    async createUser(data) {
      // 实现创建接口调用
      return await this.$http.post('/api/users', data)
    },

    async updateUser(data) {
      // 实现更新接口调用
      return await this.$http.put(`/api/users/${data.id}`, data)
    },

    async deleteUser(id) {
      // 实现删除接口调用
      return await this.$http.delete(`/api/users/${id}`)
    }
  }
}
</script>

<style>
.user-management {
  padding: 20px;
}
</style>

这个示例展示了:

  1. 查询条件配置:

    • 支持输入框(用户名)
    • 下拉选择(部门)
    • 日期范围选择(入职日期)
  2. 表格展示:

    • 自定义列渲染(部门名称映射、状态标签)
    • 操作列(编辑、删除按钮)
  3. 新增/编辑表单:

    • 表单验证
    • 多种输入类型
    • 默认值设置
    • 表单重置
  4. 完整的数据处理流程:

    • 列表数据获取
    • 新增/编辑/删除操作
    • 刷新列表
    • 错误处理
  5. 组件间联动:

    • DataList 和 Form 组件配合使用
    • 弹窗组件集成
    • 确认框交互
1.1.1

6 months ago

1.1.0

6 months ago

1.1.2

6 months ago

1.0.11

1 year ago

1.0.10

2 years ago

1.0.9

2 years ago

1.0.8

3 years ago

1.0.7

3 years ago

1.0.6

3 years ago

1.0.5

3 years ago

1.0.4

3 years ago

1.0.3

3 years ago

1.0.2

3 years ago

1.0.1

3 years ago

1.0.0

3 years ago