vue3.0封装element-ui表单
前言
提示:以下是本篇文章正文内容,下面案例可供参考
代码如下(示例):
<template>
<div>
<el-form
ref="ruleFormRef"
:model="formData"
:rules="rules"
label-width="120px"
:inline="inline"
:disabled="formDisabled"
>
<template v-for="item in formList">
<el-form-item v-if="item.type === 'input'"
:label="item.label" :prop="item.key" :key="item.key"
>
<el-input
v-model="formData[item.key]"
:placeholder="item.placeholder && !formDisabled ? item.placeholder : ''"
:disabled="item.disabled ? item.disabled : false"
></el-input>
</el-form-item>
<el-form-item v-if="item.type === 'number'"
:label="item.label" :prop="item.key" :key="item.key"
>
<el-input-number
v-model="formData[item.key]"
:min="item.min ? item.min : -Infinity"
:max="item.max ? item.max : Infinity"
controls-position="right"
/>
</el-form-item>
<el-form-item v-if="item.type === 'textarea'"
:style="{width:item.width ? item.width : ''}"
:label="item.label" :prop="item.key" :key="item.key"
>
<el-input
v-model="formData[item.key]"
:autosize="{ minRows: item.minRows ? item.minRows : 2,
maxRows: item.maxRows ? item.maxRows: 4 }"
type="textarea"
:placeholder="item.placeholder && !formDisabled ? item.placeholder : ''"
></el-input>
</el-form-item>
<el-form-item v-else-if="item.type === 'select'"
:label="item.label" :prop="item.key" :key="item.key"
>
<el-select v-model="formData[item.key]"
@change="(val)=>changeSelect(val,item.key)"
:disabled="item.disabled ? item.disabled : false"
:placeholder="item.placeholder && !formDisabled ? item.placeholder : ' '">
<el-option
v-for="opt in item.optionList"
:key="opt.value"
:label="item.labelName ? opt[item.labelName] : opt.label"
:value="item.valueName ? opt[item.valueName] : opt.value"
:disabled="opt.disabled ? opt.disabled : false"
>
</el-option>
</el-select>
</el-form-item>
<el-form-item v-else-if="item.type === 'cascader'"
:label="item.label" :prop="item.key" :key="item.key"
>
<el-cascader
v-model="formData[item.key]"
:options="item.optionList"
:show-all-levels="false"
:placeholder="item.placeholder && !formDisabled ? item.placeholder : ' '"
:props="{
value: item.valueName,
label: item.labelName
}"
@change="(val) =>handleCascaderChange(val,item.key)"
></el-cascader>
</el-form-item>
<el-form-item v-else-if="item.type === 'timeDay'"
:label="item.label" :prop="item.key" :key="item.key">
<el-date-picker v-model="formData[item.key]" type="date"
value-format="YYYY-MM-DD"
:placeholder="item.placeholder && !formDisabled ? item.placeholder : ''">
</el-date-picker>
</el-form-item>
<el-form-item v-else-if="item.type === 'datetime'"
:label="item.label" :prop="item.key" :key="item.key">
<el-date-picker
v-model="formData[item.key]"
type="datetime"
value-format="YYYY-MM-DD HH:mm:ss"
:placeholder="item.placeholder && !formDisabled ? item.placeholder : ''"
>
</el-date-picker>
</el-form-item>
<el-form-item v-else-if="item.type === 'datetimerange'"
:label="item.label" :prop="item.key" :key="item.key">
<el-date-picker
v-model="formData[item.key]"
type="datetimerange"
value-format="YYYY-MM-DD HH:mm:ss"
:range-separator="item.range-separator ? item.range-separator : '-'"
:start-placeholder="item.startPlaceholder && !formDisabled ? item.startPlaceholder : ''"
:end-placeholder="item.endPlaceholder && !formDisabled ? item.endPlaceholder : ''"
>
</el-date-picker>
</el-form-item>
<el-form-item
v-else-if="item.type === 'radioGroup'"
:label="item.label" :prop="item.key" :key="item.key">
<el-radio-group v-model="formData[item.key]">
<el-radio v-for="radio in item.radioList" :key="radio.label"
:label="radio.label">{{radio.name}}</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item
v-else-if="item.type === 'switch'"
:label="item.label" :prop="item.key" :key="item.key">
<el-switch v-model="formData[item.key]" />
</el-form-item>
<el-form-item
v-else-if="item.type === 'checkBox'"
:label="item.label" :prop="item.key" :key="item.key">
<el-checkbox-group v-model="formData[item.key]" @change="handleChangeCheckBox">
<el-checkbox :label="check.label" v-for="(check,index) in item.checkBoxList" :key="index" :disabled="check.disabled ? check.disabled : false"/>
</el-checkbox-group>
</el-form-item>
</template>
<!-- <el-form-item>
<el-button type="primary" @click="submitForm(ruleFormRef)"
>确定</el-button
>
<el-button @click="resetForm(ruleFormRef)">取消</el-button>
</el-form-item> -->
</el-form>
</div>
</template>
<script setup>
import { defineEmits, defineExpose, ref } from 'vue'
const props = defineProps({
formList: {
type: Array,
required: true,
default: () => []
},
rules: {
type: Object,
required: false,
default: () => {}
},
inline: {
type: Boolean,
required: false,
default: () => false
},
formDisabled: {
type: Boolean,
required: false,
default: () => false
}
})
// 定义要emit的方法
const emit = defineEmits(['handleCascaderChange', 'changeSelect'])
// 初始化表单
const setFormData = () => {
const result = {}
props.formList.forEach((item) => {
if (['cascader', 'checkBox'].includes[item.type]) {
result[item.key] = item.default ? item.default : []
} else if (item.type === 'switch') {
result[item.key] = item.default ? item.default : false
} else if (item.type === 'number') {
result[item.key] = item.min ? item.min : 0
} else {
result[item.key] = item.default || item.default === 0 ? item.default : ''
}
})
return result
}
const formData = ref(setFormData())
const ruleFormRef = ref(null)
// 明确要暴露出去的属性,使得父组件能接收到数据
defineExpose({
state: {
formData,
ruleFormRef // 校验表单时候使用
}
})
// const submitForm = (val) => {
// emit('submitForm', formData)
// }
const handleCascaderChange = (value, key) => {
console.log(value, 999)
formData.value[key] = value
emit('handleCascaderChange', key, value)
}
const changeSelect = (value, key) => {
console.log(value)
emit('changeSelect', key, value)
}
const handleChangeCheckBox = (val) => {
console.log(val, 21836217)
}
</script>
使用组件
在vue文件中引入该组件,并注册使用
<addAndEdit :formList="state.formList"
:formEditObj="state.baseformList"
:rules="state.rules"
ref="addAndEditDom"
@changeSelect="changeSelect"></addAndEdit>
<script setup>
import addAndEdit from '@/components/form/addAndEdit.vue'
import { reactive } from 'vue'
const state = reactive({
baseformList: [
{
label: 'name1',
key: 'aaa',
type: 'input'
},
{
label: 'name2',
key: 'bbbb',
type: 'select',
name: 'valueName',
optionList: [],
placeholder: '请选择所属区域',
default: ''
},
],
rules:{
aaa: [
{
required: true,
message: '请输入视频名称',
trigger: 'blur'
}
],
bbbb: [
{
required: true,
message: '请选择***',
trigger: 'change'
}
]
}
})
</script>
编辑或展示详情时
// 设置表单不能编辑
const formDisabled = ref(false)
formDisabled.value = true
// 获取表单dom并赋值
const addAndEditDom1 = ref(null)
addAndEditDom1.value.state.formData.value = res.data
总结
封装一个易用表单组件,可以通过配置快速生成表单,简单且高效。