- 引入comForm组件
<ComForm
:formColumn="addFormColumn"
:formData="addFormData"
:layout="formLayout"
></ComForm>
- 相关的数据配置,这里用到的是vue3的语法
const addFormColumn = ref([
{
label: '标题:',
type: 'input',
visible: true,
name: 'title',
lableStyle: addLableStyle,
valueStyle: addValueStyle,
itemStyle: addItemStyle,
required: true
},
{
label: '内容:',
type: 'textarea',
visible: true,
name: 'content',
lableStyle: addLableStyle,
valueStyle: { ...addValueStyle, width: '80rem', height: '12rem' },
itemStyle: addItemStyle
}
]);
const addFormData = reactive({
title: '',
content: ''
});
- 样式设置
const addLableStyle = {
width: '8rem',
height: '3.5rem',
lineHeight: '3.5rem'
};
const addValueStyle = {
width: '30rem',
height: '3.5rem',
lineHeight: '3.5rem'
};
const addItemStyle = {
marginBottom: '2rem'
};
const formLayout = {
layout: 'inline'
};
4.编写comForm组件
<template>
<div id="comForm">
<a-form
ref="form"
:class="isBorder ? 'form-border' : null"
:layout="layout.layout"
:model="formData"
name="basic"
:label-col="{ span: 8 }"
:wrapper-col="{ span: 16 }"
autocomplete="off"
>
<a-form-item
v-for="(item, index) in formColumn"
:style="item.itemStyle ? item.itemStyle : null"
:key="index"
:label="item.label ? item.label : null"
:labelCol="{ style: item.lableStyle ? item.lableStyle : null }"
:name="item.name"
labelAlign="right"
:rules="
item.pattern
? [
{
required: item.required ? item.required : false,
pattern: item.newRules ? item.newRules.pattern : '',
message: item.newRules.message
}
]
: [
{
required: item.required ? item.required : false,
message: item.label + '不能为空'
}
]
"
>
<a-input
v-if="item.type === 'input' && item.visible"
:allowClear="item.allowClear ? item.allowClear : false"
:disabled="item.disabled || false"
@change="(value) => selectChange(value, item.name)"
v-model:value="formData[item.name]"
key="
"
:style="item.valueStyle ? item.valueStyle : null"
/>
<!-- 添加了前缀 -->
<a-input
v-if="item.type === 'pre-input' && item.visible"
:allowClear="item.allowClear ? item.allowClear : false"
:disabled="item.disabled || false"
@change="(value) => selectChange(value, item.name)"
v-model:value="formData[item.name]"
key=""
:style="item.valueStyle ? item.valueStyle : null"
:placeholder="item.placeholder ? item.placeholder : '请输入内容'"
>
<template #prefix>
<user-outlined type="user" />
</template>
</a-input>
<a-input-password
v-if="item.type === 'passWord' && item.visible"
v-model:value="formData[item.name]"
key=""
:placeholder="item.placeholder ? item.placeholder : '请输入内容'"
:style="item.valueStyle ? item.valueStyle : null"
>
<template #prefix>
<lock-outlined />
</template>
</a-input-password>
<a-date-picker
v-else-if="item.type === 'date' && item.visible"
:locale="locale"
v-model:value="formData[item.name]"
:style="item.valueStyle ? item.valueStyle : null"
format="YYYY-MM-DD"
value-format="YYYY-MM-DD"
@change="(value) => selectChange(value, item.name)"
:disabled-date="item.disabled ? disabledDate : null"
/>
<a-time-picker
:locale="locale"
v-else-if="item.type === 'time' && item.visible"
v-model:value="formData[item.name]"
:style="item.valueStyle ? item.valueStyle : null"
format="HH:mm"
value-format="HH:mm"
@change="(value) => selectChange(value, item.name)"
:popup-style="popupStyle"
/>
<a-select
v-else-if="item.type === 'select' && item.visible"
:placeholder="item.placeholder ? item.placeholder : '请输入内容'"
:disabled="item.disabled || false"
:mode="
item.mode == 'multiple'
? 'multiple'
: item.mode == 'tags'
? 'tags'
: 'null'
"
:allowClear="item.allowClear ? item.allowClear : false"
:style="item.valueStyle ? item.valueStyle : null"
@change="(value) => selectChange(value, item.name, item)"
:filter-option="filterOption"
show-search
v-model:value="formData[item.name]"
:options="item.options"
>
<!-- <a-select-option
v-for="(_item, _index) in item.options"
:key="_index"
:value="_item.value"
>
{{ _item.label }}
</a-select-option> -->
</a-select>
<a-select
v-else-if="item.type === 'inputSelect' && item.visible"
v-model:value="formData[item.name]"
show-search
:placeholder="item.placeholder ? item.placeholder : '请输入内容'"
style="width: 200px"
:disabled="item.disabled || false"
:show-arrow="true"
:not-found-content="null"
:allowClear="item.allowClear ? item.allowClear : false"
:options="item.options"
:style="item.valueStyle ? item.valueStyle : null"
:filter-option="true"
@search="(value) => handleInputSelectSearch(value, item.name, item)"
@change="(value) => handleInputChange(value, item.name, item)"
></a-select>
<a-textarea
:allowClear="item.allowClear ? item.allowClear : false"
v-model:value="formData[item.name]"
v-else-if="item.type === 'textarea' && item.visible"
:style="item.valueStyle ? item.valueStyle : null"
:disabled="item.disabled || false"
@change="(value) => selectChange(value, item.name)"
/>
<a-checkbox-group
v-else-if="item.type === 'checkBoxUnit' && item.visible"
v-model:value="formData[item.name]"
:options="item.options"
>
</a-checkbox-group>
<a-checkbox
v-model:checked="formData[item.name]"
v-else-if="item.type === 'checkbox' && item.visible"
>
{{ item.title }}
</a-checkbox>
<!-- 这里利用绑定v-model:id父子组件来实现绑定 避免孙子组件向爷爷组件传值 -->
<div v-else-if="item.type === 'companyId' && item.visible">
<ComCascader
v-model:companyId="formData[item.name]"
:style="item.valueStyle ? item.valueStyle : null"
:unitAllData="item.options"
:isDidsabled="isDidsabled"
></ComCascader>
</div>
<div v-if="item.visible && item.boTip" style="color: red">
{{ item.boTip }}
</div>
</a-form-item>
</a-form>
<slot name="button"></slot>
</div>
</template>
<script lang="ts">
import {
defineComponent,
reactive,
ref,
toRefs,
warn,
onMounted,
inject,
toRaw,
nextTick
} from 'vue';
import {
ISearchFormColumn,
ISearchFormData
} from '@/views/support/airport/type';
import locale from 'ant-design-vue/es/date-picker/locale/zh_CN';
import dayjs from 'dayjs';
import ComCascader from '../cascader/ComCascader.vue';
import { UserOutlined, LockOutlined } from '@ant-design/icons-vue';
export default defineComponent({
name: '',
props: {
isBorder: {
default: false,
type: Boolean
},
formColumn: {
default: function () {
return [];
}
// type: Array as () => ISearchFormColumn[]
// type: Array
},
formData: {
type: Object,
default: function () {
return {};
}
},
layout: {
type: Object,
default: function () {
return {};
}
},
isDidsabled: {
type: Boolean
}
},
emits: [],
setup(props, { attrs, slots, emit, expose }) {
const newFormData = ref(props['formDat']);
const form = ref(null);
// props.formColumn.forEach((item)=>{
// item.visible=true
// })
const data = reactive({}); //里面写所有的响应式数据,像vue2中的data一样
const bgColor = ref('');
//祖孙组件传值
const updateToGrandFather = inject('updateArea');
const checkValidateTo = inject('checkValidate');
const airPortEditArea = inject('toAirPortEditChange');
const selectChange = (value, name, item) => {
emit('toSelectChang', value, name, item);
if (typeof updateToGrandFather == 'function') {
updateToGrandFather(value, name);
}
};
const filterOption = (input: string, option: any) => {
return option.label.toLowerCase().indexOf(input.toLowerCase()) >= 0;
};
//搜素输入框的事件祖孙之间传值
const seachValueToGrandF = inject('updateSelectValue');
const handleInputSelectSearch = (
value: string,
nType: string,
record: object
) => {
emit('handleInputSelectSearch', value, nType, record);
};
const handleInputChange = (
value: string,
nType: string,
record: object
) => {
emit('handleInputChange', value, nType, record);
};
//回调显示是否通过校验
const validate = (calback) => {
form.value
.validate()
.then(() => {
calback(true);
})
.catch(() => {
calback(false);
});
};
const popupStyle = {
width: '14rem',
textAlign: 'center'
};
const disabledDate = (current) => {
return current && current >= dayjs().startOf('day');
};
return {
filterOption,
locale,
dayjs,
validate,
...toRefs(data),
selectChange,
form,
checkValidateTo,
handleInputSelectSearch,
handleInputChange,
seachValueToGrandF,
newFormData,
popupStyle,
disabledDate
};
},
components: { ComCascader, UserOutlined, LockOutlined }
});
</script>
<style lang="scss" scoped>
// 公共组件尽量少些静态样式
textarea.ant-input {
max-width: none !important;
resize: none;
}
/deep/.ant-checkbox-wrapper {
> span:nth-child(2) {
width: 12rem;
}
}
</style>