需求分析:点击新增后新增一个月度活动详情,提交时可同时提交多个月度活动详情。点击某一个月度活动信息的删除后可删除对应月度活动信息
H5部分:
<el-dialog :title="title" :visible.sync="open" append-to-body>
<el-form ref="form" :model="form" label-width="80px">
<el-button @click="addItem" type="primary">增加</el-button>
<div v-for="(item, index) in form.dynamicItem" :key="index" style="background-color:#f2f5f9;margin: 10px;" >
<el-form :model="form.dynamicItem[index]" :rules="rules" label-width="120px">
<!-- 动态产生重复表单项 -->
<el-row>
<el-col :span="8">
<el-form-item label="活动类型" prop="type" >
<el-select v-model="item.type" placeholder="请选择活动类型">
<el-option v-for="dict in activeType"
:key="dict.value" :label="dict.label" :value="parseInt(dict.value)" >
</el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :span="16">
<el-form-item label="活动开始时间" prop="starttime">
<el-time-picker
v-model="item.starttime"
format = 'HH:mm'
value-format = 'HH:mm'
placeholder="活动开始时间"
style="width: 30%">
</el-time-picker>
至
<el-time-picker
style="width: 30%"
v-model="item.endtime"
format = 'HH:mm'
value-format = 'HH:mm'
placeholder="活动结束时间">
</el-time-picker>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="8">
<el-form-item label="活动人数" prop="ptotal">
<el-select v-model="item.ptotal" placeholder="请选择活动人数">
<el-option v-for="dict in activePtotal"
:key="dict.value" :label="dict.label" :value="parseInt(dict.value)" />
</el-select>
</el-form-item>
</el-col>
<el-col :span="16">
<el-form-item label="报名开始时间" prop="regTime">
<el-date-picker
v-model="item.regTime"
type="daterange"
range-separator="至"
start-placeholder="开始日期"
end-placeholder="结束日期">
</el-date-picker>
</el-form-item>
</el-col>
</el-row>
<el-form-item label="活动题目" prop="title">
<el-input v-model="item.title" placeholder="请输入活动题目" />
</el-form-item>
<el-row>
<el-col :span="8">
<el-form-item label="活动场景" prop="scene">
<el-radio-group v-model="item.scene">
<el-radio :key="3" :label="1">室内</el-radio>
<el-radio :key="4" :label="2">室外</el-radio>
</el-radio-group>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="活动室名称" prop="roomnum">
<el-select v-model="item.roomnum" placeholder="请选择活动室名称">
<el-option label="请选择字典生成" value="1" />
</el-select>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="活动预算" prop="badget">
<el-input v-model="item.badget" placeholder="请输入活动预算" />
</el-form-item>
</el-col>
</el-row>
<el-row >
<el-col :span="8">
<el-form-item label="活动主管" prop="manager">
<el-input v-model="item.manager" placeholder="请输入活动主管" />
</el-form-item>
</el-col>
<el-col :span="16">
<el-form-item label="协助人员" prop="assistant">
<el-input v-model="item.assistant" placeholder="请输入协助人员" />
</el-form-item>
</el-col>
<el-button @click="delItem(index)" type="danger" style="float: right;">删除</el-button>
</el-row>
</el-form>
</div>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button type="primary" @click="submitForm">确 定</el-button>
<el-button @click="cancel">取 消</el-button>
</div>
</el-dialog>
抽取H5部分的主要框架:
<el-dialog :title="title" :visible.sync="open" append-to-body>
<el-form ref="form" :model="form" label-width="80px">
<el-button @click="addItem" type="primary">增加</el-button>
<!-- 动态产生重复表单项 -->
<div v-for="(item, index) in form.dynamicItem" :key="index" style="background-color:#f2f5f9;margin: 10px;" >
<el-form :model="form.dynamicItem[index]" :rules="rules" label-width="120px">
<el-row>
<el-col :span="8">
<el-form-item label="活动类型" prop="type" >
表单项1
</el-form-item>
</el-col>
<el-col :span="16">
<el-form-item label="活动开始时间" prop="starttime">
表单项2
</el-form-item>
</el-col>
<el-button @click="delItem(index)" type="danger" style="float: right;">删除</el-button>
</el-row>
</el-form>
</div>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button type="primary" @click="submitForm">确 定</el-button>
<el-button @click="cancel">取 消</el-button>
</div>
</el-dialog>
js部分
/** 点击新增后增加新的项目 **/
addItem(){
// console.log(this.form.dynamicItem);
this.form.dynamicItem.push({});
},
/** 点击按钮删除动态添加的表单 **/
delItem(index){
this.form.dynamicItem.splice(index,1);
}
页面中form数据对象声明
// 表单参数
form: {
dynamicItem: []
},
表单验证
// 表单校验
rules: {
type: [{ required: true, message: "活动类型不能为空", trigger: "change" }],
starttime: [{ required: true, message: "活动开始时间不能为空", trigger: "blur" }],
endtime: [{ required: true, message: "活动结束时间不能为空", trigger: "blur" }],
ptotal: [{ required: true, message: "活动人数不能为空", trigger: "change" }],
regTime: [{ required: true, message: "报名时间不能为空", trigger: "blur" }],
title: [{ required: true, message: "活动题目不能为空", trigger: "blur" }],
roomnum: [{ required: true, message: "活动室名称不能为空", trigger: "change" }],
badget: [{ required: true, message: "活动预算不能为空", trigger: "blur" }],
manager: [{ required: true, message: "活动主管不能为空", trigger: "blur" }],
}
export default {
name: "Month",
components: {
Form
},
data() {
return {
// 表单参数
form: {
dynamicItem: []
},
// 表单校验
rules: {
type: [{ required: true, message: "活动类型不能为空", trigger: "change" }],
starttime: [{ required: true, message: "活动开始时间不能为空", trigger: "blur" }],
endtime: [{ required: true, message: "活动结束时间不能为空", trigger: "blur" }],
ptotal: [{ required: true, message: "活动人数不能为空", trigger: "change" }],
regTime: [{ required: true, message: "报名时间不能为空", trigger: "blur" }],
title: [{ required: true, message: "活动题目不能为空", trigger: "blur" }],
roomnum: [{ required: true, message: "活动室名称不能为空", trigger: "change" }],
badget: [{ required: true, message: "活动预算不能为空", trigger: "blur" }],
manager: [{ required: true, message: "活动主管不能为空", trigger: "blur" }],
}
};
},
};
完整demo
<template>
<div class="app-container">
<el-date-picker
v-model="monthValue"
type="month"
style="width: 120px"
value-format="yyyy-MM"
format="yyyy-MM"
placeholder="选择月"
@change="changeMonth"
>
</el-date-picker>
<el-calendar v-model="nowDate" >
<template
slot="dateCell"
slot-scope="{date, data}"
>
<p :class="data.isSelected ? 'is-selected' : ''" style="width: 100%;height: 100%;" @click="clickDate(date)">
{{ data.day.split('-').slice(1).join('月')+"日"}} {{ data.isSelected ? '✔️' : ''}}
</p>
</template>
</el-calendar>
<!-- 对话框(添加 / 修改) -->
<el-dialog :title="title" :visible.sync="open" append-to-body>
<el-form ref="form" :model="form" label-width="80px">
<el-button @click="addItem" type="primary">增加</el-button>
<div v-for="(item, index) in form.dynamicItem" :key="index" style="background-color:#f2f5f9;margin: 10px;" >
<el-form :model="form.dynamicItem[index]" :rules="rules" label-width="120px">
<!-- 动态产生重复表单项 -->
<el-row>
<el-col :span="8">
<el-form-item label="活动类型" prop="type" >
<el-select v-model="item.type" placeholder="请选择活动类型">
<el-option v-for="dict in activeType"
:key="dict.value" :label="dict.label" :value="parseInt(dict.value)" >
</el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :span="16">
<el-form-item label="活动开始时间" prop="starttime">
<el-time-picker
v-model="item.starttime"
format = 'HH:mm'
value-format = 'HH:mm'
placeholder="活动开始时间"
style="width: 30%">
</el-time-picker>
至
<el-time-picker
style="width: 30%"
v-model="item.endtime"
format = 'HH:mm'
value-format = 'HH:mm'
placeholder="活动结束时间">
</el-time-picker>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="8">
<el-form-item label="活动人数" prop="ptotal">
<el-select v-model="item.ptotal" placeholder="请选择活动人数">
<el-option v-for="dict in activePtotal"
:key="dict.value" :label="dict.label" :value="parseInt(dict.value)" />
</el-select>
</el-form-item>
</el-col>
<el-col :span="16">
<el-form-item label="报名开始时间" prop="regTime">
<el-date-picker
v-model="item.regTime"
type="daterange"
range-separator="至"
start-placeholder="开始日期"
end-placeholder="结束日期">
</el-date-picker>
</el-form-item>
</el-col>
</el-row>
<el-form-item label="活动题目" prop="title">
<el-input v-model="item.title" placeholder="请输入活动题目" />
</el-form-item>
<el-row>
<el-col :span="8">
<el-form-item label="活动场景" prop="scene">
<el-radio-group v-model="item.scene">
<el-radio :key="3" :label="1">室内</el-radio>
<el-radio :key="4" :label="2">室外</el-radio>
</el-radio-group>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="活动室名称" prop="roomnum">
<el-select v-model="item.roomnum" placeholder="请选择活动室名称">
<el-option label="请选择字典生成" value="1" />
</el-select>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="活动预算" prop="badget">
<el-input v-model="item.badget" placeholder="请输入活动预算" />
</el-form-item>
</el-col>
</el-row>
<el-row >
<el-col :span="8">
<el-form-item label="活动主管" prop="manager">
<el-input v-model="item.manager" placeholder="请输入活动主管" />
</el-form-item>
</el-col>
<el-col :span="16">
<el-form-item label="协助人员" prop="assistant">
<el-input v-model="item.assistant" placeholder="请输入协助人员" />
</el-form-item>
</el-col>
<el-button @click="delItem(index)" type="danger" style="float: right;">删除</el-button>
</el-row>
</el-form>
</div>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button type="primary" @click="submitForm">确 定</el-button>
<el-button @click="cancel">取 消</el-button>
</div>
</el-dialog>
</div>
</template>
<style rel="stylesheet/scss" lang="scss">
@import "~@/assets/styles/month.scss";
</style>
<script>
import {
createMonth,
updateMonth,
deleteMonth,
getMonth,
getMonthPage,
exportMonthExcel,
createMonthActivities
} from '@/api/activity/month'
import {DICT_TYPE, getDictDataLabel, getDictDatas, getDictDatas2} from "@/utils/dict";
import Form from '@/views/bpm/form'
export default {
name: "Month",
components: {
Form
},
data() {
return {
//活动类型下拉框获取后端数据
activeType:null,
//活动人数下拉框获取后端数据
activePtotal:null,
monthValue:null,
nowDate:new Date(),
// 遮罩层
loading: true,
// 导出遮罩层
exportLoading: false,
// 显示搜索条件
showSearch: true,
// 总条数
total: 0,
// 月度活动列表
list: [],
// 弹出层标题
title: "",
// 是否显示弹出层
open: false,
dateRangeTime: [],
dateRangeRegTime: [],
dateRangeCreateTime: [],
//新增活动日期
addActiveDate:null,
// 查询参数
queryParams: {
pageNo: 1,
pageSize: 10,
id: null,
type: null,
ptotal: null,
title: null,
scene: null,
roomnum: null,
badget: null,
manager: null,
assistant: null,
},
// 表单参数
form: {
dynamicItem: []
},
// 表单校验
rules: {
type: [{ required: true, message: "活动类型不能为空", trigger: "change" }],
starttime: [{ required: true, message: "活动开始时间不能为空", trigger: "blur" }],
endtime: [{ required: true, message: "活动结束时间不能为空", trigger: "blur" }],
ptotal: [{ required: true, message: "活动人数不能为空", trigger: "change" }],
regTime: [{ required: true, message: "报名时间不能为空", trigger: "blur" }],
title: [{ required: true, message: "活动题目不能为空", trigger: "blur" }],
roomnum: [{ required: true, message: "活动室名称不能为空", trigger: "change" }],
badget: [{ required: true, message: "活动预算不能为空", trigger: "blur" }],
manager: [{ required: true, message: "活动主管不能为空", trigger: "blur" }],
}
};
},
created() {
this.monthValue=this.nowDate;
this.getList();
//活动类型下拉框获取数据
this.activeType=this.getDictDatas(DICT_TYPE.ACTIVITY_MONTH_TYPE);
//活动人数下拉框获取数据
this.activePtotal=this.getDictDatas(DICT_TYPE.ACTIVITY_MONTH_PTOTAL);
//活动场景单选框数据
// this.activeScene=this.getDictDatas(DICT_TYPE.ACTIVITY_MONTH_SCENE);
},
methods: {
/** 查询列表 */
getList() {
this.loading = true;
// 处理查询参数
let params = {...this.queryParams};
this.addBeginAndEndTime(params, this.dateRangeTime, 'time');
this.addBeginAndEndTime(params, this.dateRangeRegTime, 'regTime');
this.addBeginAndEndTime(params, this.dateRangeCreateTime, 'createTime');
// 执行查询
getMonthPage(params).then(response => {
this.list = response.data.list;
this.total = response.data.total;
this.loading = false;
});
},
/** 取消按钮 */
cancel() {
this.open = false;
this.reset();
},
/** 表单重置 */
reset() {
this.form.dynamicItem = [];
this.resetForm("form");
},
/** 提交按钮 */
submitForm() {
var flag=0;
var subData=this.form.dynamicItem;
//提交数据验证
subData.forEach((data,index)=>{
//对提交数据进行验证:type,starttime,endtime,ptotal,regTime,title,roomnum,manager,badget
if (!data.type||!data.starttime||!data.endtime||!data.ptotal||!data.regTime||!data.title||!data.roomnum||!data.manager||!data.badget){
alert("数据提交异常1");
flag=1;
}
}
)
if (flag===1){
return;
}
//数据信息进行处理并进行提交
subData.forEach((data,index)=>{
//对提交数据进行验证:type,starttime,endtime,ptotal,regTime,title,roomnum,manager,badget
data.regStarttime=data.regTime[0];
data.regEndtime=data.regTime[1];
if (typeof(data.starttime )=='string'){
var hourAndMinutesS=data.starttime.split(':');
data.starttime=new Date(this.addActiveDate.setHours(parseInt(hourAndMinutesS[0])));
data.starttime=new Date(this.addActiveDate.setMinutes(parseInt(hourAndMinutesS[1])));
}
if (typeof(data.endtime )=='string'){
var hourAndMinutesE=data.endtime.split(':');
data.endtime=new Date(this.addActiveDate.setHours(hourAndMinutesE[0]));
data.endtime=new Date(this.addActiveDate.setMinutes(hourAndMinutesE[1]));
}
console.log("处理过后的数据对象",data);
console.log("数据"+index,data);
}
)
console.log(this.form.dynamicItem);
// 添加的提交
createMonthActivities(this.form.dynamicItem).then(response => {
this.$modal.msgSuccess("新增成功");
this.open = false;
this.getList();
});
},
/** 上方月份选择后下方日历的联动 **/
changeMonth() {
//上方日期选择器选择了月份后,下方日历显示为选中月份
this.nowDate = new Date(this.monthValue);
console.log("this.nowDate",this.nowDate);
},
clickDate(date){
//点击某个日期后弹出弹出框
this.reset();
this.open = true;
this.title = "添加月度活动";
this.addActiveDate=date;
},
/** 点击新增后增加新的项目 **/
addItem(){
// console.log(this.form.dynamicItem);
this.form.dynamicItem.push({});
},
/** 点击按钮删除动态添加的表单 **/
delItem(index){
this.form.dynamicItem.splice(index,1);
}
}
};
</script>
整体效果及功能:
删除某个月度活动: