正常情况下,我们使用form,它的子项会是这样的,比如有input和select:
// input类型
<el-form-item label="活动名称" prop="name">
<el-input v-model="ruleForm.name">el-input>
el-form-item>
// select类型
<el-form-item label="活动区域" prop="region">
<el-select v-model="ruleForm.region" placeholder="请选择活动区域">
<el-option label="区域一" value="shanghai">el-option>
<el-option label="区域二" value="beijing">el-option>
el-select>
el-form-item>
那由此我们可以设计出封装后样子:
<el-form-item label="label" prop="prop">
// 如果是input类型
<el-input v-if="input" v-model="ruleForm.name">el-input>
// 如果是select类型
<el-select v-if="select" v-model="ruleForm.region" placeholder="请选择活动区域">
<el-option label="区域一" value="shanghai">el-option>
<el-option label="区域二" value="beijing">el-option>
el-select>
el-form-item>
<template>
<div class="Form">
<el-form
ref="form"
class="page-form"
:class="className"
:model="data"
:rules="rules"
:label-width="labelWidth"
>
<el-form-item
v-if="!item.Noshow"
v-for="(item, index) in fieldList"
:key="index"
:prop="item.value"
:label="item.label+':'"
:class="item.className"
:style="typePattern? 'float: left;':''"
>
<el-input
v-if="item.type === 'input' || item.type === 'password'"
v-model="data[item.value]"
:type="item.type"
:placeholder="getPlaceholder(item)"
@blur="blurEvent(item.event)"
:show-password="item.showPassword"
:style="item.style"
/>
<el-input
v-if="item.type === 'textarea'"
v-model.trim="data[item.value]"
:type="item.type"
:disabled="item.disabled"
:placeholder="getPlaceholder(item)"
:autosize="{minRows: 2, maxRows: 10}"
:maxlength="item.maxlength"
show-word-limit
@blur="blurEvent(item.event)"
/>
<el-input-number
v-if="item.type === 'inputNumber'"
v-model="data[item.value]"
:step="item.step"
size="small"
:min="item.min"
:max="item.max"
/>
<el-select
v-if="item.type === 'select'"
v-model="data[item.value]"
:disabled="item.disabled"
:clearable="item.clearable"
:filterable="item.filterable"
:placeholder="getPlaceholder(item)"
@change="changeEvent(item.event, data[item.value])"
>
<el-option
v-for="(childItem, childIndex) in listTypeInfo[item.list]"
:key="childIndex"
:label="childItem.label"
:value="childItem.value"
/>
el-select>
<el-cascader
v-if="item.type === 'cascader'"
v-model="data[item.value]"
:options="listTypeInfo[item.list]"
:props="{ expandTrigger: 'hover' }"
:filterable="item.filterable"
:clearable="item.clearable"
@change="changeEvent(item.event, data[item.value])"
>
el-cascader>
<el-radio
v-if="item.type === 'radio'"
v-for="(childItem, childIndex) in listTypeInfo[item.list]"
:key="childIndex"
v-model="data[item.value]"
:label="childItem.value"
@change="changeEvent(item.event, data[item.value])"
>
{{childItem.label}}
el-radio>
<el-checkbox
v-if="item.type === 'checked'"
v-for="(childItem, childIndex) in listTypeInfo[item.list]"
:key="childIndex"
v-model="data[item.value]"
:label="childItem.value"
@change="changeEvent(item.event, data[item.value])"
>
{{childItem.label}}
el-checkbox>
<el-switch
v-if="item.type === 'switch'"
v-model="data[item.value]"
:active-color="item.color"
>
el-switch>
<el-date-picker
v-if="item.type === 'date'"
v-model="data[item.value]"
:type="item.dateType"
:clearable="item.clearable"
:disabled="item.disabled"
:placeholder="getPlaceholder(item)"
:format="item.format"
:value-format="item.valueFormat"
:range-separator="item.rangeSeparator"
:picker-options="listTypeInfo[item.list]"
unlink-panels
start-placeholder="开始日期"
end-placeholder="结束日期"
/>
<el-time-picker
v-if="item.type === 'time'"
:is-range="item.isRange"
v-model="data[item.value]"
:range-separator="item.rangeSeparator"
:placeholder="getPlaceholder(item)"
start-placeholder="开始时间"
end-placeholder="结束时间"
>
el-time-picker>
<div v-if="item.type === 'tag'">
<el-tag
v-for="childItem in data[item.value]"
:key="childItem"
closable
:disable-transitions="false"
@close="handleClose(childItem,item.value)"
>
{{childItem}}
el-tag>
<el-input
class="input-new-tag"
v-if="inputVisible"
v-model="inputValue"
ref="saveTagInput"
@keyup.enter.native="handleInputConfirm(item.value)"
@blur="handleInputConfirm(item.value)"
>
el-input>
<el-button v-else class="button-new-tag" size="small" @click="showInput">{{item.btnName}}el-button>
div>
<template v-if="item.type === 'slot'">
<slot :name="'form-' + item.value" />
template>
el-form-item>
<div v-if="isShowBtn" class="btn" :style="typePattern? 'float: left;margin-left: 20px;':''">
<el-button type="primary" @click="submitForm('form')">{{typePattern?'查 询':'提 交'}}el-button>
<el-button v-if="typePattern" @click="resetForm('form')">重 置el-button>
div>
el-form>
div>
template>
<script>
export default {
name: 'wb-form',
props: {
// 自定义类名
className: {
type: String
},
// 表单数据
data: {
type: Object
},
// 相关字段
fieldList: {
type: Array
},
// 验证规则
rules: {
type: Object
},
// 相关的列表 (必填)
listTypeInfo: {
type: Object
},
// label宽度
labelWidth: {
type: String,
default: '100px'
},
// 展示类型(是否启用浮动模式)
typePattern: {
type: Boolean
},
// 是否显示按钮(不显示则自定义按钮)
isShowBtn: {
type: Boolean,
default: true
}
},
data () {
return {
// 是否显示标签名称
inputVisible: false,
// 添加的新标签名
inputValue: ''
}
},
// watch: {
// data: {
// handler: function (val) {
// console.log(val)
// // 将form实例返回到父级
// this.$emit('updateRef', this.$refs.form)
// },
// deep: true // 深度监听
// },
// },
methods: {
/**
* placeholder 输入框占位文本
* 通过方法,里面处理你想要的数据,最终return 出去
* */
getPlaceholder (row) {
let placeholder;
if (row.type === 'input' || row.type === 'textarea' || row.type === 'password') {
placeholder = '请输入' + row.label
} else if (row.type === 'select' || row.type === 'time' || row.type === 'date') {
placeholder = '请选择' + row.label
} else {
placeholder = row.label
}
return placeholder
},
/**
* 绑定的相关事件
* 可扩展Element 所有Event事件,以下都是常用的事件,(可自行扩展)
* */
// 失去焦点事件
blurEvent (evnet) {
let data = {
evnetName: evnet,
};
this.$emit('blurEvent', data)
},
// 发生改变的时候
changeEvent (evnet, value) {
let data = {
evnetName: evnet,
value: value
};
this.$emit('changeEvent', data)
},
// 派发按钮点击事件
handleClick (event, data) {
this.$emit('handleClick', event, data)
},
/**
* 标签专用函数
* */
// 关闭标签
handleClose(item,name) {
this.data[name].splice(this.data[name].indexOf(item), 1);
},
// 显示input
showInput() {
this.inputVisible = true;
},
// 失去焦点,所做的事情
handleInputConfirm(list) {
let inputValue = this.inputValue;
if (inputValue) {
this.data[list].push(inputValue);
}
this.inputVisible = false;
this.inputValue = '';
},
/**
* 提交表单
* */
submitForm (formName) {
if(this.type){
this.$emit('success')
}else {
this.$refs[formName].validate((valid) => {
if (valid) {
this.$emit('success')
} else {
console.log('error submit!!');
return false;
}
});
}
},
// 清除表单
resetForm (formName) {
this.$refs[formName].resetFields();
}
},
mounted () {
// 将form实例返回到父级 (为了更方便使用Ref)
this.$emit('formRef', this.$refs.form)
},
}
</script>
<el-input
v-if="item.type === 'input' || item.type === 'password'"
v-model="data[item.value]"
:type="item.type"
:placeholder="getPlaceholder(item)"
@blur="blurEvent(item.event)"