|
@@ -1,193 +0,0 @@
|
|
|
-<template>
|
|
|
- <div id="custom-form">
|
|
|
- <el-form ref="formRef" :model="form" :rules="rules" :label-width="labelWidth" class="form" @submit.prevent :disabled="disabled">
|
|
|
- <el-col :span="span" v-for="(item, index) in fields" :key="index">
|
|
|
- <el-form-item v-if="display(item)" :key="`form-field-${item.model}`" :label="getField('label', item)" :prop="item.model" :required="item.required">
|
|
|
- <template v-if="item.custom">
|
|
|
- <slot :name="item.model" v-bind="{ item }"></slot>
|
|
|
- </template>
|
|
|
- <template v-else>
|
|
|
- <template v-if="item.type === 'textarea'">
|
|
|
- <el-input
|
|
|
- clearable
|
|
|
- v-model="form[item.model]"
|
|
|
- :type="item.type"
|
|
|
- :placeholder="getField('placeholder', item)"
|
|
|
- v-bind="item.options"
|
|
|
- @change="dataChange(item.model)"
|
|
|
- show-word-limit
|
|
|
- ></el-input>
|
|
|
- </template>
|
|
|
- <template v-else-if="item.type === 'numbers'">
|
|
|
- <el-input-number v-model="form[item.model]" :placeholder="getField('placeholder', item)" @change="dataChange(item.model)" style="width: 100%" />
|
|
|
- </template>
|
|
|
- <template v-else-if="item.type === 'radio'">
|
|
|
- <el-radio-group v-model="form[item.model]" :type="item.type" v-bind="item.options" @change="dataChange(item.model)">
|
|
|
- <slot :name="item.model" v-bind="{ item }"></slot>
|
|
|
- </el-radio-group>
|
|
|
- </template>
|
|
|
- <template v-else-if="item.type === 'checkbox'">
|
|
|
- <el-checkbox-group v-model="form[item.model]" :type="item.type" v-bind="item.options">
|
|
|
- <slot :name="item.model" v-bind="{ item }"></slot>
|
|
|
- </el-checkbox-group>
|
|
|
- </template>
|
|
|
- <template v-else-if="item.type === 'select'">
|
|
|
- <el-select
|
|
|
- clearable
|
|
|
- filterable
|
|
|
- allow-create
|
|
|
- default-first-option
|
|
|
- v-model="form[item.model]"
|
|
|
- :type="item.type"
|
|
|
- :placeholder="getField('selectplaceholder', item)"
|
|
|
- v-bind="item.options"
|
|
|
- @change="dataChange(item.model)"
|
|
|
- style="width: 100%"
|
|
|
- >
|
|
|
- <slot :name="item.model" v-bind="{ item }"></slot>
|
|
|
- </el-select>
|
|
|
- </template>
|
|
|
- <template v-else-if="item.type === 'selectMany'">
|
|
|
- <el-select
|
|
|
- filterable
|
|
|
- clearable
|
|
|
- multiple
|
|
|
- collapse-tags
|
|
|
- v-model="form[item.model]"
|
|
|
- :type="item.type"
|
|
|
- :placeholder="getField('selectplaceholder', item)"
|
|
|
- v-bind="item.options"
|
|
|
- @change="dataChange(item.model)"
|
|
|
- style="width: 100%"
|
|
|
- >
|
|
|
- <slot :name="item.model" v-bind="{ item }"></slot>
|
|
|
- </el-select>
|
|
|
- </template>
|
|
|
- <template v-else-if="item.type === `year` || item.type == 'month' || item.type == 'date' || item.type == 'daterange' || item.type == 'datetime' || item.type == 'datetimerange'">
|
|
|
- <el-date-picker
|
|
|
- v-model="form[item.model]"
|
|
|
- :type="item.type"
|
|
|
- :placeholder="getField('selectplaceholder', item)"
|
|
|
- :format="getDateFormat(item.type)"
|
|
|
- :value-format="getDateFormat(item.type)"
|
|
|
- v-bind="item.options"
|
|
|
- @change="dataChange(item.model)"
|
|
|
- range-separator="至"
|
|
|
- style="width: 100%"
|
|
|
- >
|
|
|
- </el-date-picker>
|
|
|
- </template>
|
|
|
- <template v-else-if="item.type === `time`">
|
|
|
- <el-time-picker
|
|
|
- v-model="form[item.model]"
|
|
|
- :placeholder="getField('selectplaceholder', item)"
|
|
|
- :format="getDateFormat(item.type)"
|
|
|
- :value-format="getDateFormat(item.type)"
|
|
|
- v-bind="item.options"
|
|
|
- @change="dataChange(item.model)"
|
|
|
- style="width: 100%"
|
|
|
- >
|
|
|
- </el-time-picker>
|
|
|
- </template>
|
|
|
- <template v-else-if="item.type === `inputnumber`">
|
|
|
- <el-input-number v-model="form[item.model]" :placeholder="getField('placeholder', item)" v-bind="item.options" @change="dataChange(item.model)" style="width: 100%"></el-input-number>
|
|
|
- </template>
|
|
|
- <template v-else>
|
|
|
- <el-input
|
|
|
- clearable
|
|
|
- v-model="form[item.model]"
|
|
|
- :type="getField('type', item)"
|
|
|
- :placeholder="getField('placeholder', item)"
|
|
|
- :show-password="getField('type', item) === 'password'"
|
|
|
- v-bind="item.options"
|
|
|
- @change="dataChange(item.model)"
|
|
|
- ></el-input>
|
|
|
- </template>
|
|
|
- </template>
|
|
|
- </el-form-item>
|
|
|
- </el-col>
|
|
|
- <el-col :span="24" label="" class="btn" v-if="useSave">
|
|
|
- <slot name="submit">
|
|
|
- <el-button type="primary" @click="save(formRef)">{{ submitText || submitTextDefault }}</el-button>
|
|
|
- </slot>
|
|
|
- </el-col>
|
|
|
- </el-form>
|
|
|
- </div>
|
|
|
-</template>
|
|
|
-
|
|
|
-<script setup>
|
|
|
-import { get, isFunction } from 'lodash-es'
|
|
|
-const { t } = useI18n()
|
|
|
-const submitTextDefault = t('common.save')
|
|
|
-const props = defineProps({
|
|
|
- modelValue: { type: Object },
|
|
|
- rules: { type: Array, default: () => {} },
|
|
|
- labelWidth: { type: String, default: 'auto' },
|
|
|
- disabled: { type: Boolean, default: false },
|
|
|
- fields: { type: Array, default: () => [] },
|
|
|
- submitText: { type: String },
|
|
|
- useSave: { type: Boolean, default: true },
|
|
|
- span: { type: Number, default: 24 } // 限制两侧的距离,24就是整行全用
|
|
|
-})
|
|
|
-const emits = defineEmits(['update:modelValue', 'dataChange', 'save'])
|
|
|
-const formRef = ref()
|
|
|
-const form = computed({
|
|
|
- get() {
|
|
|
- return props.modelValue
|
|
|
- },
|
|
|
- set(value) {
|
|
|
- console.log(value)
|
|
|
- emits('update:modelValue', value)
|
|
|
- }
|
|
|
-})
|
|
|
-const save = async (formEl) => {
|
|
|
- if (!formEl) return
|
|
|
- await formEl.validate((valid, fields) => {
|
|
|
- if (valid) {
|
|
|
- emits('save', form.value)
|
|
|
- } else {
|
|
|
- console.log('error submit!', fields)
|
|
|
- }
|
|
|
- })
|
|
|
-}
|
|
|
-const getField = (item, data) => {
|
|
|
- let res = get(data, item, null)
|
|
|
- if (item === 'type') res = res === null ? `text` : res
|
|
|
- if (item === 'placeholder') res = res === null ? `请输入${data.label}` : res
|
|
|
- if (item === `selectplaceholder`) res = res === null ? `请选择${data.label}` : res
|
|
|
- if (item === 'required') res = res === null ? false : res
|
|
|
- if (item === `error`) res = res === null ? `${data.label}错误` : res
|
|
|
- return res
|
|
|
-}
|
|
|
-const dataChange = (model) => {
|
|
|
- const value = form.value[model]
|
|
|
- emits('dataChange', { model, value })
|
|
|
-}
|
|
|
-const display = (field) => {
|
|
|
- let dis = get(field, `display`)
|
|
|
- if (!isFunction(dis)) return true
|
|
|
- else {
|
|
|
- return dis(field, form)
|
|
|
- }
|
|
|
-}
|
|
|
-const getDateFormat = (e) => {
|
|
|
- if (e === 'year') return 'YYYY'
|
|
|
- if (e === 'month') return 'MM'
|
|
|
- if (e === 'date') return 'YYYY-MM-DD'
|
|
|
- if (e === 'daterange') return 'YYYY-MM-DD'
|
|
|
- if (e === 'datetime') return 'YYYY-MM-DD HH:mm:ss'
|
|
|
- if (e === 'datetimerange') return 'YYYY-MM-DD HH:mm:ss'
|
|
|
- if (e === 'time') return 'HH:mm:ss'
|
|
|
-}
|
|
|
-</script>
|
|
|
-<style scoped>
|
|
|
-.btn {
|
|
|
- text-align: center;
|
|
|
-}
|
|
|
-
|
|
|
-.form {
|
|
|
- display: flex;
|
|
|
- flex-direction: row;
|
|
|
- flex-wrap: wrap;
|
|
|
-}
|
|
|
-</style>
|