<!-- -->
<template>
<a-form-model :ref="formKey" :model="form" :label-col="layout_.labelCol" :wrapper-col="layout_.wrapperCol" :rules="formRules" style="width: 100%;">
<div class="p-page-form-con" :style="getLayoutStyle">
<div
:key="'p-page-form-item-' + index"
v-for="(item, index) in formList"
class="item"
:style="getItemOccupiedNum(item)"
>
<a-form-model-item :label="item.cnName" :style="['label','imgGroup'].indexOf(item.type)>=0?'width: 100%; margin-bottom: 0px;':'width: 100%;'" :prop="item.enName" v-bind="item.formItemAttr || {}" >
<a-input v-if="item.type === 'input'" v-model="item.value" v-bind="item.itemAttr || {}" @change="(...ages)=>{changeEvent(item,...ages)}"/>
<p-ImgGroup v-if="item.type === 'imgGroup'" v-model="item.value" v-bind="item.itemAttr || {}" @change="(...ages)=>{changeEvent(item,...ages)}"></p-ImgGroup>
<p-UpLoadFile v-if="item.type === 'UpLoad'" v-model="item.value" v-bind="item.itemAttr || {}" @change="(...ages)=>{changeEvent(item,...ages)}"></p-UpLoadFile>
<p-Cascader v-if="item.type === 'cascader'" v-model="item.value" :optionsList="item.optionList" :itemAttr="item.itemAttr || {}" @change="(...ages)=>{changeEvent(item,...ages)}"></p-Cascader>
<p-InputRange v-if="item.type === 'inputRange'" v-model="item.value" v-bind="item.itemAttr || {}" @change="(...ages)=>{changeEvent(item,...ages)}"></p-InputRange>
<!-- <p-RadioGroup v-if="item.type === 'radioGroup'" v-model="item.value" :optionsList="item.optionList" :itemAttr="item.itemAttr || {}" ></p-RadioGroup> -->
<p-TextGroup v-if="item.type === 'TextGroup'" v-model="item.value" v-bind="item.itemAttr || {}" @textGroupEvent="textGroupEvent"></p-TextGroup>
<!-- <a-date-picker v-if="item.type === 'datePicker'" v-model="item.value" valueFormat="YYYY-MM-DD" type="date" v-bind="item.itemAttr || {}"/> -->
<a-date-picker v-if="item.type === 'datePicker'"
v-bind="item.itemAttr || {}"
v-model="item.value"
:locale="locale"
@change="(...ages)=>{changeEvent(item,...ages)}"
/>
<!-- :default-value="moment(item.value, 'YYYY-MM-DD')" -->
<!-- type="date"
valueFormat="YYYY-MM-DD"
format="YYYY-MM-DD" -->
<!-- @change="(...args)=>{onDateChange(...args,item)}" -->
<a-range-picker v-bind="item.itemAttr || {}" v-if="item.type === 'rangePicker'" :locale="locale" v-model="item.value" @change="(...ages)=>{changeEvent(item,...ages)}" @panelChange="(...ages)=>{rangePickerPanelChange(item,index,...ages)}" />
<div v-bind="item.itemAttr || {}" v-if="item.type === 'label'"> {{ item.value }} </div>
<a-select v-bind="item.itemAttr || {}" v-if="item.type === 'select'" v-model="item.value" @change="(...ages)=>{changeEvent(item,...ages)}">
<a-select-option :key="(optItem.enName || optItem.value )+ optIndex" v-for="(optItem, optIndex) in item.optionList"
:value="optItem.enName || optItem.value" v-bind="optItem">
{{ optItem.cnName || optItem.label }}
</a-select-option>
</a-select>
<a-checkbox-group v-bind="item.itemAttr || {}" v-if="item.type === 'checkboxGroup'" :options="item.optionList" v-model="item.value" @change="(...ages)=>{changeEvent(item,...ages)}"/>
<a-textarea v-bind="item.itemAttr || {}" v-if="item.type=== 'textarea'" v-model="item.value" @change="(...ages)=>{changeEvent(item,...ages)}"/>
<a-radio-group v-bind="item.itemAttr || {}" v-if="item.type === 'radioGroup'" v-model="item.value" @change="(...ages)=>{changeEvent(item,...ages)}">
<a-radio v-if="!item.itemAttr.type || item.itemAttr.type=='radio'" :key="(optItem.enName || optItem.value) + optIndex" v-for="(optItem, optIndex) in item.optionList"
:value="optItem.enName || optItem.value" v-bind="optItem">
{{ optItem.cnName || optItem.label }}
</a-radio>
<a-radio-button v-if="item.itemAttr.type && item.itemAttr.type=='button'" :key="(optItem.enName || optItem.value) + optIndex" v-for="(optItem, optIndex) in item.optionList"
:value="optItem.enName || optItem.value" v-bind="optItem">
{{ optItem.cnName || optItem.label }}
</a-radio-button>
</a-radio-group>
<!-- item.itemAttr.type=='custom1' && -->
<slot v-if="item.type === 'custom' && !item.componentName" :name="item.enName" :value="item.value" :itemData="{ attr: item.itemAttr || {}, value: item.value }" ></slot>
<component v-if="item.type=='custom' && item.componentName" :is="item.componentName" v-bind="item.itemAttr || {}" v-model="item.value" @change="(...ages)=>{changeEvent(item,...ages)}"></component>
</a-form-model-item>
</div>
</div>
</a-form-model>
</template>
<script>
import IS from "./../utils/is";
import UUID from "./../utils/uuid";
import PCascader from './components/cascader.vue'
// import PInputRange from './components/InputGroup.vue'
import PRadioGroup from './components/RadioGroup.vue'
// import PTextGroup from './components/TextGroup.vue'
import moment from 'moment';
import locale from 'ant-design-vue/es/date-picker/locale/zh_CN';
// import Vue from 'Vue';
export default {
// import引入的组件需要注入到对象中才能使用
name: "PPageForm",
components: {PCascader,PRadioGroup},
props: {
// columnNum 此值必填 表示表单按照几列进行布局 默认值为 3
// rowNum 此值选填 表示表单按几行进行布局 ,先设置一个初值,之后会根据formDataList的值自动进行校正 默认值为 4
// rowHeight: 设置行高,默认为 100px
// rowGap 此值选填 表示表单的每一行之间的间隙 默认值为 1px
// coliumnGap 此值选填 表示表单每一列之间的间隙 默认值为 10px
// labelCol 此值选填 为 Form 本身属性,label 标签布局,同 <Col> 组件,设置 span offset 值,如 {span: 3, offset: 12} 或 sm: {span: 3, offset: 12} 请参照 Form span: 4
// wrapperCol 此值选填 为 Form 本身属性,需要为输入控件设置布局样式时,使用该属性,用法同 labelCol 请参照 Form span: 14
/**
* 用于控制表单布局
* @prop {Object} layout { rowNum: 4, columnNum: 3, rowGap: "1px", rowHeight:'100px', coliumnGap: "10px", labelCol: { span: 4 }, wrapperCol: { span: 14 }, }
* columnNum 此值必填 表示表单按照几列进行布局 默认值为 3
* rowNum 此值选填 表示表单按几行进行布局 ,先设置一个初值,之后会根据formDataList的值自动进行校正 默认值为 4
* rowHeight: 设置行高,默认为 100px
* rowGap 此值选填 表示表单的每一行之间的间隙 默认值为 1px
* coliumnGap 此值选填 表示表单每一列之间的间隙 默认值为 10px
* labelCol 此值选填 为 Form 本身属性,label 标签布局,同 <Col> 组件,设置 span offset 值,如 {span: 3, offset: 12} 或 sm: {span: 3, offset: 12} 请参照 Form span: 4
* wrapperCol 此值选填 为 Form 本身属性,需要为输入控件设置布局样式时,使用该属性,用法同 labelCol 请参照 Form span: 14
*/
layout: {
type: Object,
default: ()=>{ return { rowNum: 4, columnNum: 3, rowGap: "1px", rowHeight:'100px', coliumnGap: "10px", labelCol: { span: 4 }, wrapperCol: { span: 14 }, }},
},
// 表示表单的校验规则 此对象中的key值将与formDataList中的enName的值对应 详细可参考 Form 的 rules 表单验证规则
formRules:{type: Object, default:()=>{
return {
// userName1: [
// { required: true, message: 'Please input Activity name', trigger: 'blur' },
// { min: 3, max: 5, message: 'Length should be 3 to 5', trigger: 'blur' },
// ],
// userName2: [{ required: true, message: 'Please select Activity zone', trigger: 'blur' }],
// userName3: [{ required: true, message: 'Please pick a date', trigger: 'blur' }],
// userName4: [
// {
// required: true,
// message: 'Please select at least one activity type',
// trigger: 'blur',
// },
// ],
// userName5: [
// { required: true, message: 'Please select activity resource', trigger: 'blur' },
// ],
// userName6: [{ required: true, message: 'Please input activity form', trigger: 'blur' }],
}
} },
// 表单数据
// enName 表示表单字段英文名称,主要用于最后表单返回的key
// cnName 表示表单字段中文名称,主要用于表单的label
// type 表示表单项的类型,包含:input select 等,具体参照
formDataList:{type:Array, required: false, default:()=>{ return [
// { enName:'userName1', cnName:'用户名1', type:'input',value:'',numRowsOccupied: 1, numColumnOccupied: 1 ,formItemAttr:{},itemAttr:{},},
// { enName:'userName2', cnName:'用户名2', type:'input',value:'',numRowsOccupied: 1, numColumnOccupied: 1 ,formItemAttr:{},itemAttr:{},},
// { enName:'userName3', cnName:'用户名3', type:'input',value:'',numRowsOccupied: 1, numColumnOccupied: 1 ,formItemAttr:{},itemAttr:{},},
// { enName:'userName4', cnName:'用户名4', type:'input',value:'',numRowsOccupied: 1, numColumnOccupied: 1 ,formItemAttr:{},itemAttr:{},},
// { enName:'userName5', cnName:'用户名5', type:'input',value:'',numRowsOccupied: 1, numColumnOccupied: 1 ,formItemAttr:{},itemAttr:{},},
// { enName:'userName6', cnName:'用户名6', type:'input',value:'',numRowsOccupied: 1, numColumnOccupied: 1 ,formItemAttr:{},itemAttr:{},},
// { enName:'userName7', cnName:'用户名7', type:'input',value:'',numRowsOccupied: 1, numColumnOccupied: 1 ,formItemAttr:{},itemAttr:{},},
// { enName:'userName8', cnName:'用户名8', type:'input',value:'',numRowsOccupied: 1, numColumnOccupied: 1 ,formItemAttr:{},itemAttr:{},},
// { enName:'userName9', cnName:'用户名9', type:'input',value:'',numRowsOccupied: 1, numColumnOccupied: 1 ,formItemAttr:{},itemAttr:{},},
// { enName:'userName10',cnName:'用户名10',type:'input',value:'',numRowsOccupied: 1, numColumnOccupied: 1 ,formItemAttr:{},itemAttr:{},},
// { enName:'userName11',cnName:'用户名11',type:'input',value:'',numRowsOccupied: 1, numColumnOccupied: 1 ,formItemAttr:{},itemAttr:{},},
// { enName:'userName12',cnName:'用户名12',type:'input',value:'',numRowsOccupied: 1, numColumnOccupied: 1 ,formItemAttr:{},itemAttr:{},},
]}},
// 表单的事件
PEvent:{type:Function},
showHelp:{type:Boolean, default: () => { return false }}
},
data() {
// 这里存放数据
return {
// moment,
locale,
formKey:UUID(),
layout_: { rowNum: 4, columnNum: 3, rowGap: "1px", rowHeight:'100px', coliumnGap: "10px", labelCol: { span: 4 }, wrapperCol: { span: 14 }, }, // rowNum: 4, columnNum: 3, rowGap: "1px", coliumnGap: "2px"
formList: [],
form: {},
// 存放字段事件
eventList:{},
formChangeKey:'',
formListItemKeys:{}
};
},
// 监听属性 类似于data概念
computed: {
getLayoutStyle() {
const res = {
"grid-template-columns": "",
"grid-template-rows": "",
gap: "",
};
const { rowNum, columnNum, rowGap, rowHeight, coliumnGap } = this.layout;
res["grid-template-columns"] = new Array(columnNum)
.fill(`${100 / columnNum}%`)
.join(" ");
// res['grid-template-rows'] = new Array(rowNum).fill(`${100/rowNum}%`).join(' ')
// grid-template-rows: repeat(auto-fill, 100px);
// grid-template-columns: repeat(auto-fill, 100px);
// res['grid-template-columns'] = new Array(columnNum).fill(`repeat(auto-fill, 100px)`).join(' ')
res["grid-template-rows"] = new Array(Math.ceil(rowNum))
.fill(`repeat(auto-fill, ${rowHeight})`)
.join(" ");
res["gap"] = `${rowGap} ${coliumnGap}`;
return res;
},
},
// 监控data中的数据变化
watch: {
layout: {
handler(val) {
this.layout_ = {...this.layout_,...val}
},
deep: true,
immediate: true,
},
formDataList: {
handler(val) {
const newDataKey = UUID('MDUUID',JSON.stringify(val))
if(!this.formChangeKey){
this.formChangeKey = newDataKey
this.registerComponent(val)
this.setLayout(val);
this.setFormValue(val)
}else{
if(this.formChangeKey != newDataKey){
this.formChangeKey = newDataKey
this.registerComponent(val)
this.setLayout(val);
this.setFormValue(val)
}
}
},
deep: true,
immediate: true,
},
formList: {
handler(val) {
const tempObj = {}
val.forEach(item=>{
const {enName,value}= item
tempObj[enName] = value
})
this.form = {...this.form,...tempObj}
},
deep: true,
// immediate: true,
},
form: {
handler(val, oldVal) {
// this.eventList
// Object.keys(val).forEach(key=>{
// if(val[key] != oldVal[key] && this.eventList[key]){
// // console.log('判断更新===》',val[key] != oldVal[key] && this.eventList[key],oldVal[key],val[key]);
// }
// })
// if(!IS.isNullOrUnDef(val) && !IS.isEmpty(val)){
// this.PEvent && this.PEvent('formChange',val)
// }
},
deep: true,
// immediate: true,
},
},
// 生命周期 - 创建完成(可以访问当前this实例)
created() {},
// 生命周期 - 挂载完成(可以访问DOM元素)
mounted() {
// this.formList = this.createFormItem(12);
// console.log('@@@@@@@@@@@@@@@@@@@@@@@@@@@@@==1===>',UUID('MDUUID',JSON.stringify({name:'小明',age:12,class:[]})));
// console.log('@@@@@@@@@@@@@@@@@@@@@@@@@@@@@==2===>', UUID('MDUUID',JSON.stringify({name:'小明',age:12,class:[{name:'一般',sss:'12'}]})));
if(this.$isShowHelp == true &&this.showHelp==true){
console.log(`
组件名称:
PPageForm
使用方法:
<p-PageForm ref="PPageForm" :formDataList="[]" >
<template v-slot:userName7="{value, itemData}" >
<a-date-picker :format="'YYYY-MM-DD'"v-model="value" v-bind="itemData || {}"/>
</template>
</p-PageForm>
备注:
<template v-slot:userName7="{value, itemData}" ></template> 中的 【v-slot:userName7="{value, itemData}"】 是固定用法,
userName7 :表示 【formDataList】中对应的数据的【enName】的值
value : 表示 【formDataList】中对应的数据的【value】的值,可用于绑定v-model
itemData : 表示 【formDataList】中对应的数据的 【itemAttr + value】 的值 ,如:{attr: itemAttr || {}, value: value }
props属性说明
props: {
// 表单的事件
// 参数: @param {string} type 对应的取值有:change 、textGroupEvent 、formChange; change 表示表单项值的change事件 ; textGroupEvent 表示 【TextGroup】类型 的点击事件; formChange 表示表单上的值变化事件
// 参数: @param {*} item
// 参数: @param {*} data
PEvent:{type:Function},
// columnNum 此值必填 表示表单按照几列进行布局 默认值为 3
// rowNum 此值选填 表示表单按几行进行布局 ,先设置一个初值,之后会根据formDataList的值自动进行校正 默认值为 4
// rowGap 此值选填 表示表单的每一行之间的间隙 默认值为 1px
// rowHeight: 设置行高,默认为 100px
// coliumnGap 此值选填 表示表单每一列之间的间隙 默认值为 10px
// labelCol 此值选填 为 Form 本身属性,label 标签布局,同 <Col> 组件,设置 span offset 值,如 {span: 3, offset: 12} 或 sm: {span: 3, offset: 12} 请参照 Form span: 4
// wrapperCol 此值选填 为 Form 本身属性,需要为输入控件设置布局样式时,使用该属性,用法同 labelCol 请参照 Form span: 14
layout: {
type: Object,
default: ()=>{ return { rowNum: 4, columnNum: 3, rowGap: "1px", rowHeight:'100px', coliumnGap: "10px", labelCol: { span: 4 }, wrapperCol: { span: 14 }, }},
},
// 表示表单的校验规则 此对象中的key值将与formDataList中的enName的值对应 详细可参考 Form 的 rules 表单验证规则
formRules:{type: Object,
default:()=>{
return {
// userName1: [
// { required: true, message: 'Please input Activity name', trigger: 'blur' },
// { min: 3, max: 5, message: 'Length should be 3 to 5', trigger: 'blur' },
// ],
}
}
},
// 表单数据
// enName 此项必填 表示表单字段英文名称,主要用于最后表单返回的key
// cnName 此项必填 表示表单字段中文名称,主要用于表单的label
// type 此项必填 表示表单项的类型,包含如下:
input 对应的value值的类型: String
select, 对应的value值的类型: String || Array
checkboxGroup, 对应的value值的类型: String || Array
textarea, 对应的value值的类型: String
radioGroup, 对应的value值的类型: String
inputRange, 对应的value值的类型: Array // input范围 可接受input的所有属性 对应的value 是数组
datePicker, 对应的value值的类型: moment 具体参照 https://1x.antdv.com/components/date-picker-cn/
rangePicker, 对应的value值的类型: moment[] 自定义日期范围选择 具体参照 https://1x.antdv.com/components/date-picker-cn/ 中的 RangePicker
cascader, 对应的value值的类型: Array
imgGroup, 对应的value值的类型: Array // 展示图片用的(可参照【PImgGroup】的帮助文档) [{url:'',title:''}] || ['url1','url1'] || [{ status:'success' | 'error' | 'info' | 'warning'| '404' | '403' | '500',statusTitle:''}] || [{url:'',title:'', isShowWatermark: true}]
UpLoad, 对应的value值的类型:
TextGroup, 对应的value值的类型: Array // 用于展示 【 字符串(text) link按钮(link) 】格式的数据,其中个数可选,搭配任意。 此项可配点击事件,事件将会触发表单的【PEvent】事件(对应的type值为:textGroupEvent); 如: value:[{ type: 'text', label: '待定', border: true, isEvent: true }, { type: 'link', label: '查看核定通知书', isEvent: true },]
label, 对应的value值的类型: String // 此类型用于显示值 一般的文本
custom, 对应的value值的类型: 请参照自定义组件要求填写 // 自定义组件可在 标签内使用<p-PageForm> </p-PageForm>
// componentName 此项可选 表示自定义组件名称,和【type = 'custom'】 配套使用,使用场景为:当自定义组件不想使用插槽的方式时可使用此方式 如在<p-QueryCard>组件中想要扩展自定义查询条件时,可用此方式
// componentItem 此项可选 表示自定义组件本身,和【type = 'custom'】 配套使用,使用场景为:当自定义组件不想使用插槽的方式时可使用此方式 如在<p-QueryCard>组件中想要扩展自定义查询条件时,可用此方式
// value 此项必填 表单元素的预设值;此项值的类型需要根据所使用的的表单项类型不同而不同,详情参看上面的 【type】的对应类型
// numRowsOccupied 此项可选 表示当前表单项所占的行数 默认值 1行
// numColumnOccupied 此项可选 表示当前表单项所占列数 默认值 1列 最大值不能超过 【columnNum】 的值
// formItemAttr 此项可选 表示【a-form-model】所对应的属性,具体请参照 https://1x.antdv.com/components/form-model-cn/#Form.Item 中 【Form.Item 】 的属性
// itemAttr 此项可选 表示表单项对应的属性值,可对自定义组件进行传值
// optionList 此项可选 表示表单项所需要使用的数据
// isChangeEvent 此项可选 表示是否监听表单项的变化,具体会通过【PEvent】返回
formDataList:{type:Array, required: false, default:()=>{ return [
// { enName:'userName1', cnName:'用户名1', type:'input',value:'', componentName:'Pbutton', componentItem:Pbutton, numRowsOccupied: 1, numColumnOccupied: 1 ,formItemAttr:{},itemAttr:{},optionList:[],isChangeEvent:true,},
// { enName:'userName2', cnName:'用户名2', type:'input',value:''},
]}}
}
表单提交事件的使用
方法名称: onSubmit
参数: @param {Function} backFun 参数(formRes)为表单结果 如: {userName1:'',userName2:''}
使用方式: this.$refs['PPageForm'].onSubmit((formRes)=>{}) || const formRes = await this.$refs['PPageForm'].onSubmit() || this.$refs['PPageForm'].onSubmit().then(formRes=>{})
`);
}
},
// 方法集合
methods: {
registerComponent(componentlist){
// console.log('注册组件======》',componentlist);
componentlist.forEach(item=>{
const {componentItem,componentName} = item
if(!IS.isNullOrUnDef(componentItem)){
// Vue.component(componentName,componentItem)
this.$VUE.component(componentName,componentItem)
}
})
// console.log('注册组件 1======》',Vue);
},
changeEvent(item,...args){
const {eventList, form, PEvent, $nextTick} = this
// console.log('changeEvent 1======>',item);
// console.log('changeEvent 2======>',...args);
const changeList = {
select:(value, option)=>{
// console.log('判断更新===》',item.enName,value)
this.PEvent && this.PEvent('change',item.enName,value)
},
checkboxGroup:(checkedValue)=>{
this.PEvent && this.PEvent('change',item.enName,checkedValue)
},
textarea:(e)=>{
this.PEvent && this.PEvent('change',item.enName,e.target.value)
},
radioGroup:(e)=>{
this.PEvent && this.PEvent('change',item.enName,e.target.value)
},
rangePicker:(dates,dateStrings)=>{
// function(dates: [moment, moment] | [string, string], dateStrings: [string, string])
this.PEvent && this.PEvent('change',item.enName,dates)
},
datePicker:(date,dateString)=>{
// function(date: moment | string, dateString: string)
this.PEvent && this.PEvent('change',item.enName,date)
},
cascader:(value, selectedOptions)=>{
this.PEvent && this.PEvent('change',item.enName,value)
},
input:(e)=>{
this.PEvent && this.PEvent('change',item.enName,e.target.value)
},
UpLoad:(val)=>{
this.PEvent && this.PEvent('change',item.enName,val)
}
}
eventList[item.enName] && changeList[item.type] && changeList[item.type](...args)
if(!IS.isNullOrUnDef(form) && !IS.isEmpty(form)){
$nextTick(()=>{
setTimeout(() => {
PEvent && PEvent('formChange','form',form)
}, 500);
})
}
},
rangePickerPanelChange(item,index,value, mode){
const {itemAttr} = item
const getDateFormat = (item_)=>{
const mode_ = item_.itemAttr['mode']
const format_ = item_.itemAttr['format']
let valFormat = 'YYYY-MM'
if(!IS.isNullOrUnDef(mode_) && !IS.isEmpty(mode_)){
if(IS.isArray(mode_)){
valFormat = mode_[0]
}
}
if(!IS.isNullOrUnDef(format_) && !IS.isEmpty(format_)){
valFormat = format_
}
return valFormat
}
const type = getDateFormat(item)
const tempVal = [moment(value[0]).format(type),moment(value[1]).format(type)]
// console.log('rangePickerPanelChange=====>',item,index,tempVal, mode,this.formList,item.itemAttr['format']);
this.formList[index].value =tempVal
itemAttr['mode'] && (item.itemAttr['mode'] = [...itemAttr['mode']])
itemAttr['mode'] && (this.formList[index].itemAttr['mode'] = [...itemAttr['mode']])
},
getMomentVal(dateStr,dateFormat){
return !dateStr?null:moment(dateStr,dateFormat)
},
textGroupEvent(label){
const {PEvent} = this
PEvent && PEvent('textGroupEvent',label)
},
createFormItem(count_) {
const itemObj = { numRowsOccupied: 1, numColumnOccupied: 2 };
const tempArr = new Array(count_).fill({});
for (let i = 0; i < 5; i++) {
const ll = Math.floor(Math.random() * (11 - 1) + 1);
tempArr[ll] = { ...itemObj };
}
return tempArr;
},
getItemOccupiedNum(item) {
const tempStyle = {};
const { columnNum } = this.layout;
// numRowsOccupied 表示占几行 numColumnOccupied 表示占几列
const { numRowsOccupied, numColumnOccupied } = item;
if (IS.isNumber(numColumnOccupied)) {
let tempNumColumnOccupied = numColumnOccupied;
if (columnNum < numColumnOccupied) {
tempNumColumnOccupied = columnNum;
}
tempStyle["grid-row-end"] = 1;
tempStyle["grid-column-end"] = `span ${tempNumColumnOccupied || 1}`;
tempStyle["grid-row-end"] = `span ${numRowsOccupied || 1}`;
}
return tempStyle;
},
setLayout(dataList) {
const { columnNum } = this.layout_;
let tempRowCount = dataList.length / columnNum;
dataList.forEach((item) => {
const { numRowsOccupied, numColumnOccupied } = item;
if (IS.isNumber(numColumnOccupied) && numColumnOccupied > 1) {
// 行数加1
if (IS.isNumber(numRowsOccupied)) {
tempRowCount = tempRowCount + numRowsOccupied;
} else {
// tempRowCount = tempRowCount + numColumnOccupied
tempRowCount += 1;
}
}
});
this.layout_.rowNum = tempRowCount;
},
setFormValue(dataList){
this.setFormValueNew(dataList)
// // this.form
// const tempObj = {}
// const tempArr = dataList
// dataList.forEach((item,index_)=>{
// const {enName,value,isChangeEvent,key} = item
// const newKey = UUID('MDUUID',JSON.stringify(item))
// tempObj[enName] = value
// if(!key){
// tempArr[index_].key = newKey
// }
// // tempArr.push({...item,key:UUID('MDUUID',JSON.stringify(item))})
// this.eventList[enName] = isChangeEvent || false
// })
// console.log('重新渲染=======》',dataList,tempArr);
// // this.formListItemKeys
// this.formList = tempArr
// this.form = tempObj
},
setFormValueNew(dataList){
const getKey = (val)=>{
return UUID('MDUUID',JSON.stringify(val))
}
const tempObj = {}
const tempArr = []
const listItemKey = {}
if(this.formList.length==0){
dataList.forEach(item=>{
const {enName,value,isChangeEvent} = item
tempObj[enName] = value
const newKey = getKey(item)
tempArr.push({...item,key:newKey})
listItemKey[enName] = newKey
this.eventList[enName] = isChangeEvent || false
})
this.formListItemKeys = listItemKey
this.formList = tempArr
this.form = tempObj
}else{
const tempList = []
const createItem = (enName_,value_,newKey_,item_,index_,isChangeEvent_)=>{
this.formListItemKeys[enName_] = newKey_
this.form[enName_] = value_
tempList.push(Object.assign({},this.formList[index_],{...item_,key:newKey_}))
this.eventList[enName_] = isChangeEvent_ || false
}
dataList.forEach((item,index)=>{
const {enName,value,isChangeEvent,key} = item
const newKey = getKey(item)
const oldKey = key // this.formListItemKeys[enName]
if(oldKey){
if(oldKey != newKey){
// 新的数据key和老的数据key不一样,直接创建新的key和对应的数据
createItem(enName,value,newKey,item,index,isChangeEvent)
}else{
tempList.push(item)
}
}else{
// 没有指定字段的key,直接创建新的key和对应的数据
createItem(enName,value,newKey,item,index,isChangeEvent)
}
})
this.formList = tempList
}
},
resetForm(){
this.setFormValue(this.formDataList)
},
onSubmit(backFun){
const self=this
return new Promise((resolve, reject) => {
self.$refs[self.formKey].validate(valid => {
if (valid) {
backFun && backFun(self.form)
resolve(self.form);
} else {
console.log('error submit!!');
reject('error submit!!');
return false;
}
});
})
},
},
};
</script>
<style lang="less" scoped>
.p-page-form-con {
// width: 300px;
// height: 200px;
// background: #9c5b5b;
// border: 3px solid #f2f30e;
display: grid;
grid-template-columns: 1fr 1fr;
// grid-template-rows: 1fr 1fr 1fr 1fr;
gap: 2px 3px;
justify-content: center;
// 在容器中设置grid-auto-flow 属性可以改变单元格排列方式
// column 按列排序 row 按行排列 dense 元素使用前面空余栅格
grid-auto-flow: row;
// overflow: auto;
.item {
// height: 40px;
// line-height: 40px;
// border: 1px solid red;
display: flex;
justify-content: flex-start;
align-items: flex-start;
overflow: hidden;
// padding: 5px;
}
// .item:nth-child(3) {
// // grid-row-start: 1;
// grid-row-end:1;
// /* 占几列 */
// grid-column-end: span 3;
// /* 占几行 */
// grid-row-end: span 1;
// }
}
</style>