一,父组件-清单列表页(说明:这里的清单列表页也是一个子组件,可以请看示例图)
<template>
<div id="engineeringList">
<transition name="screening-box">
<div class="screening-box" v-show="options.isShow" @click.stop="setShow">
<!-- -->
<div
class="screening-box"
v-show="options.isShow"
@click.stop="setShow"
>
<transition name="screening">
<div class="screening" v-if="options.isShow" @click.stop>
<!-- 头部 -->
<div class="screening-header">
{{
options.editMode == "edit" ? "工程量编辑" : "工程量清单查看"
}}
<i
class="ifca-iconfont ifca-icon-gengduo-left"
@click="setShow"
></i>
</div>
<div class="box-content">
<!-- 中间内容 -->
<div
class="content-class"
v-for="(item, i) in options.dataSource"
:key="i"
@click.stop="editClick(item, i)"
>
<div
class="projectlist"
v-if="item.dataRowState != 'Deleted'"
>
<div class="projectTitle">
<div class="left">工程量清单{{ i + 1 }}</div>
<i
v-if="options.editMode != 'view'"
class="right iconfont icon-lajixiang"
@click.stop="deleteClick(item, i)"
></i>
</div>
<div class="projectContent">
<div class="contentOne">
<span class="titleColor">内容:</span>
<span>{{ item.content }}</span>
</div>
<div class="contentTwo">
<div class="subtitle">
<span class="titleColor">单位:</span>
<span>{{ item.unitOfMeasurement }}</span>
</div>
<div class="subtitle">
<span class="titleColor">工程量:</span>
<span>{{ item.quantities }}</span>
</div>
</div>
<div class="contentTwo">
<div class="subtitle">
<span class="titleColor">单价:</span>
<span>{{ item.comprehensiveAmt }}</span>
</div>
<div class="subtitle">
<span class="titleColor">总价:</span>
<span>{{ item.sumComprehensiveAmt }}</span>
</div>
</div>
<div class="contentTwo">
<div class="subtitle">
<span class="titleColor">税率:</span>
<span>{{ item.taxTotalAmtName.key }}</span>
</div>
<div class="subtitle">
<span class="titleColor">税额:</span>
<span>{{ item.taxRate }}</span>
</div>
</div>
</div>
</div>
</div>
<!-- 添加清单 -->
<div
class="addJect"
@click="addClick"
v-if="options.editMode != 'view'"
>
<span class="icon">+</span>
<span>添加工程量清单</span>
</div>
</div>
<!-- 底部按钮 -->
<div class="button-box">
<div
class="buttonClass defaultButtonClass"
@click="buttonClick('cancel')"
>
关闭
</div>
<div
class="buttonClass primaryButtonClass"
@click="buttonClick('save')"
v-if="options.editMode != 'view'"
>
保存
</div>
</div>
</div>
</transition>
</div>
</div>
</transition>
<!-- 工程清单新增底部滑块 -->
<engineeringEdit
v-if="engineeringEditOptions.isShow"
:options="engineeringEditOptions"
@callBack="formCallBack"
></engineeringEdit>
</div>
</template>
<script>
import engineeringEdit from "./engineeringEdit";
export default {
components: {
engineeringEdit,
},
props: {
// 接受父组件传过来的值
options: {
type: Object,
default: {
isShow: false,
// 注意: editMode属性有两个值:
// "view"不能新增修改删除只有查看功能
// "edit"可以新增修改删除
editMode: "view",
// dataSource后台给到的清单列表数据
dataSource: [],
},
},
},
data() {
return {
// 传给子组件的数据
engineeringEditOptions: {
isShow: false,
item: {},
},
engineeringEditIndex: -1,
listData: []
};
},
created() {
// 深拷贝数据给到listData
this.listData = JSON.parse(JSON.stringify(this.options.dataSource))
},
methods: {
setShow() {
this.options.isShow = !this.options.isShow;
},
/**
* 按钮点击事件
* type : 取消 cancel ; 保存 save
*/
buttonClick(type) {
if (type == "save") {
this.$emit("callBack", JSON.stringify(this.listData));
}
this.setShow();
},
/**
* 点击新增工程清单事件
*/
addClick() {
//重置下标
this.engineeringEditIndex = -1;
//格式化数据
this.engineeringEditOptions.item = {
// dataRowState默认是新增数据
dataRowState: "Added",
content: "",
unitOfMeasurement: "",
quantities: "",
comprehensiveAmt: "",
sumComprehensiveAmt: 0,
taxTotalAmt: 0,
taxTotalAmtName: {},
taxRate: 0,
};
this.engineeringEditOptions.isShow = true;
},
// 新增回调(这里新增保存和修改保存是一个回调,根据engineeringEditIndex来判断)
formCallBack(formData) {
let dataList = JSON.parse(formData);
// 只要engineeringEditIndex不是-1 它就是修改数据!
// 然后把子组件传过来的dataList替换掉options.dataSource中的那条数据!!
// 否则就是新增数据,直接push到options.dataSource中
if (this.engineeringEditIndex > -1) {
this.listData[this.engineeringEditIndex] = dataList;
} else {
this.listData.push(dataList);
}
},
// 删除
deleteClick(item, index) {
// 如果是新增数据直接可以删除
if (item.dataRowState == "Added")
this.listData.splice(index, 1);
else {
item.dataRowState = "Deleted";
}
},
// 编辑
editClick(item, i) {
//记录当前编辑数据的下标,以便编辑完后,直接替换原数据
this.engineeringEditIndex = i;
// 如果dataRowState == "Unchanged"则把dataRowState改为修改状态
if (item.dataRowState == "Unchanged") item.dataRowState = "Modified";
this.engineeringEditOptions.item = item;
this.engineeringEditOptions.isShow = true;
},
},
};
</script>
<style scoped lang="less"></style>
二,子组件(添加和修改页面)
<template>
<div id="engineeringEdit">
<ifca-popup-balck
v-model="options.isShow"
@on-show="onShow"
@on-hide="onHide"
maxHeight="90%"
:headerShow="true"
head-title="新增工程量清单"
@on-click-left="show = false"
>
<div class="formContent">
<!-- 表单 -->
<ifca-form @submit="submit" :formItem="formItem">
<ifca-form-cell
title="内容:"
v-model="formData.content"
:required="true"
:input="true"
:activeOff="true"
:autofocus="true"
:isLink="false"
></ifca-form-cell>
<ifca-form-cell
title="单位:"
v-model="formData.unitOfMeasurement"
:required="true"
:input="true"
:activeOff="true"
:autofocus="true"
:isLink="false"
></ifca-form-cell>
<ifca-form-cell
title="工程量:"
v-model="formData.quantities"
:required="true"
inputType="number"
:input="true"
:activeOff="true"
:autofocus="true"
:isLink="false"
name="myUnit"
@on-change="numberChange"
></ifca-form-cell>
<ifca-form-cell
title="单价:"
v-model="formData.comprehensiveAmt"
:required="true"
inputType="number"
:input="true"
:activeOff="true"
:autofocus="true"
:isLink="false"
name="myUnit"
@on-change="numberChange"
></ifca-form-cell>
<ifca-form-cell
title="总价:"
v-model="formData.sumComprehensiveAmt"
inputType="number"
:input="false"
:activeOff="true"
:autofocus="true"
:isLink="false"
name="myUnit"
></ifca-form-cell>
<ifca-form-radio
title="税率:"
v-model="formData.taxTotalAmtName"
name="税率"
:required="true"
placeholder="请选择税率"
:list="taxRateList"
@on-change="taxRateChange"
></ifca-form-radio>
<ifca-form-cell
title="税额:"
v-model="formData.taxRate"
:input="false"
:activeOff="true"
:autofocus="true"
:isLink="false"
name="myUnit"
></ifca-form-cell>
</ifca-form>
<!-- 按钮信息 -->
<div class="button-box">
<div class="buttonClass defaultButtonClass" @click="closelClick()">
关闭
</div>
<div class="buttonClass primaryButtonClass" @click="confirmClick()">
确认
</div>
</div>
</div>
</ifca-popup-balck>
</div>
</template>
<script>
import { calculationAmt } from "@/assets/js/formatData.js";
export default {
props: {
// 接受父组件传过来的值
options: {
type: Object,
default: {
isShow: false,
editMode: "view",
item: {
dataRowState: "Added",
content: "",
unitOfMeasurement: "",
quantities: "",
comprehensiveAmt: "",
sumComprehensiveAmt: 0,
taxTotalAmt: 0,
taxTotalAmtName: {},
taxRate: 0,
},
},
},
},
data() {
return {
// 税率
taxRateList: [],
//表单数据
formData: {},
};
},
created() {
this.getTaxData();
// 注意!!!这里当组件打开时会把options.item数据给到formData中,让它显示!
this.formData = JSON.parse(JSON.stringify(this.options.item));
},
methods: {
onShow() {},
onHide() {},
// 关闭
closelClick() {
this.options.isShow = false;
},
// 确认
confirmClick() {
if (!this.checkData()) {
return;
}
console.log(1111, this.formData);
this.options.isShow = false;
// 传值给父组件
this.$emit("callBack", JSON.stringify(this.formData));
},
// 表单校验
checkData() {
if (!this.formData.content) {
this.messageAlert("内容不能为空");
return false;
}
if (!this.formData.unitOfMeasurement) {
this.messageAlert("单位不能为空");
return false;
}
if (!this.formData.quantities) {
this.messageAlert("工程量不能为空");
return false;
}
if (!this.formData.comprehensiveAmt) {
this.messageAlert("单价不能为空");
return false;
}
if (!this.formData.taxTotalAmtName.value) {
this.messageAlert("请选择税率");
return false;
}
return true;
},
messageAlert(content) {
$ifcaPopup.tips({ content: content, time: 1500 });
},
},
};
</script>
<style scoped lang="less"></style>
三,说明:前端这边每次操作(新增,修改,删除)都会给数据添加对应的状态,这样做会告诉后台这个列表里哪些数据是新增或修改或删除的!!!
四,示例图