Parent component – Manifest page (note: the manifest page is also a child component, see the example figure)
<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>
<! - the head -- -- >
<div class="screening-header">{{ options.editMode == "edit" ? "Edit quantities" : "View quantities list"}}<i
class="ifca-iconfont ifca-icon-gengduo-left"
@click="setShow"
></i>
</div>
<div class="box-content">
<! -- Middle 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">Bill of Quantities {{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">Content:</span>
<span>{{ item.content }}</span>
</div>
<div class="contentTwo">
<div class="subtitle">
<span class="titleColor">Units:</span>
<span>{{ item.unitOfMeasurement }}</span>
</div>
<div class="subtitle">
<span class="titleColor">Quantity:</span>
<span>{{ item.quantities }}</span>
</div>
</div>
<div class="contentTwo">
<div class="subtitle">
<span class="titleColor">The unit price:</span>
<span>{{ item.comprehensiveAmt }}</span>
</div>
<div class="subtitle">
<span class="titleColor">The total price:</span>
<span>{{ item.sumComprehensiveAmt }}</span>
</div>
</div>
<div class="contentTwo">
<div class="subtitle">
<span class="titleColor">Rate:</span>
<span>{{ item.taxTotalAmtName.key }}</span>
</div>
<div class="subtitle">
<span class="titleColor">Tax:</span>
<span>{{ item.taxRate }}</span>
</div>
</div>
</div>
</div>
</div>
<! -- Add list -->
<div
class="addJect"
@click="addClick"
v-if="options.editMode ! = 'view'"
>
<span class="icon">+</span>
<span>Add bill of quantities</span>
</div>
</div>
<! -- Bottom button -->
<div class="button-box">
<div
class="buttonClass defaultButtonClass"
@click="buttonClick('cancel')"
>Shut down</div>
<div
class="buttonClass primaryButtonClass"
@click="buttonClick('save')"
v-if="options.editMode ! = 'view'"
>save</div>
</div>
</div>
</transition>
</div>
</div>
</transition>
<! -- Added bottom slider to project list -->
<engineeringEdit
v-if="engineeringEditOptions.isShow"
:options="engineeringEditOptions"
@callBack="formCallBack"
></engineeringEdit>
</div>
</template>
<script>
import engineeringEdit from "./engineeringEdit";
export default {
components: {
engineeringEdit,
},
props: {
// Accept the value from the parent component
options: {
type: Object.default: {
isShow: false.// Note that the editMode attribute has two values:
// "view" cannot be added or deleted
// "edit" can be added, modified or deleted
editMode: "view".// dataSource Specifies the list data
dataSource[],},},},data() {
return {
// Data passed to child components
engineeringEditOptions: {
isShow: false.item: {},},engineeringEditIndex: -1.listData: []}; },created() {
// Deep copy data to listData
this.listData = JSON.parse(JSON.stringify(this.options.dataSource))
},
methods: {
setShow() {
this.options.isShow = !this.options.isShow;
},
/** * button click event * type: cancel; Save save * /
buttonClick(type) {
if (type == "save") {
this.$emit("callBack".JSON.stringify(this.listData));
}
this.setShow();
},
/** * click add Project list event */
addClick() {
// reset the subscript
this.engineeringEditIndex = -1;
// Format the data
this.engineeringEditOptions.item = {
// dataRowState Specifies new data by default
dataRowState: "Added".content: "".unitOfMeasurement: "".quantities: "".comprehensiveAmt: "".sumComprehensiveAmt: 0.taxTotalAmt: 0.taxTotalAmtName: {},
taxRate: 0};this.engineeringEditOptions.isShow = true;
},
// Add callback (save and modify save is a callback, according to engineeringEditIndex)
formCallBack(formData) {
let dataList = JSON.parse(formData);
// As long as engineeringEditIndex is not -1, it changes the data!
// Replace the dataList from the subcomponent with options.dataSource.
// The data is pushed directly to the options.dataSource
if (this.engineeringEditIndex > -1) {
this.listData[this.engineeringEditIndex] = dataList;
} else {
this.listData.push(dataList); }},/ / delete
deleteClick(item, index) {
// Delete new data
if (item.dataRowState == "Added")
this.listData.splice(index, 1);
else {
item.dataRowState = "Deleted"; }},/ / edit
editClick(item, i) {
// Record the subscript of the currently edited data, so that the original data can be directly replaced after editing
this.engineeringEditIndex = i;
// If dataRowState == "Unchanged", change the dataRowState to changed state
if (item.dataRowState == "Unchanged") item.dataRowState = "Modified";
this.engineeringEditOptions.item = item;
this.engineeringEditOptions.isShow = true; ,}}};</script>
<style scoped lang="less"></style>
Copy the code
Subcomponents (adding and modifying pages)
<template>
<div id="engineeringEdit">
<ifca-popup-balck
v-model="options.isShow"
@on-show="onShow"
@on-hide="onHide"
maxHeight="90%"
:headerShow="true"
head-title="New Bill of Quantities"
@on-click-left="show = false"
>
<div class="formContent">
<! - form - >
<ifca-form @submit="submit" :formItem="formItem">
<ifca-form-cell
title=Content:"
v-model="formData.content"
:required="true"
:input="true"
:activeOff="true"
:autofocus="true"
:isLink="false"
></ifca-form-cell>
<ifca-form-cell
title="Unit:"
v-model="formData.unitOfMeasurement"
:required="true"
:input="true"
:activeOff="true"
:autofocus="true"
:isLink="false"
></ifca-form-cell>
<ifca-form-cell
title="Quantity:"
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="Unit Price:"
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="Total price:"
v-model="formData.sumComprehensiveAmt"
inputType="number"
:input="false"
:activeOff="true"
:autofocus="true"
:isLink="false"
name="myUnit"
></ifca-form-cell>
<ifca-form-radio
title="Tax rate:"
v-model="formData.taxTotalAmtName"
name="Rate"
:required="true"
placeholder="Please select tax rate"
:list="taxRateList"
@on-change="taxRateChange"
></ifca-form-radio>
<ifca-form-cell
title="Tax:"
v-model="formData.taxRate"
:input="false"
:activeOff="true"
:autofocus="true"
:isLink="false"
name="myUnit"
></ifca-form-cell>
</ifca-form>
<! -- Button info -->
<div class="button-box">
<div class="buttonClass defaultButtonClass" @click="closelClick()">Shut down</div>
<div class="buttonClass primaryButtonClass" @click="confirmClick()">confirm</div>
</div>
</div>
</ifca-popup-balck>
</div>
</template>
<script>
import { calculationAmt } from "@/assets/js/formatData.js";
export default {
props: {
// Accept the value from the parent component
options: {
type: Object.default: {
isShow: false.editMode: "view".item: {
dataRowState: "Added".content: "".unitOfMeasurement: "".quantities: "".comprehensiveAmt: "".sumComprehensiveAmt: 0.taxTotalAmt: 0.taxTotalAmtName: {},
taxRate: 0,},},},},data() {
return {
/ / rate
taxRateList: [].// Form data
formData: {}}; },created() {
this.getTaxData();
// Attention!! Here, when the component is opened, the options.item data is given to formData to display!
this.formData = JSON.parse(JSON.stringify(this.options.item));
},
methods: {
onShow() {},
onHide() {},
/ / close
closelClick() {
this.options.isShow = false;
},
/ / confirm
confirmClick() {
if (!this.checkData()) {
return;
}
console.log(1111.this.formData);
this.options.isShow = false;
// Pass the value to the parent component
this.$emit("callBack".JSON.stringify(this.formData));
},
// Form validation
checkData() {
if (!this.formData.content) {
this.messageAlert("Content cannot be empty.");
return false;
}
if (!this.formData.unitOfMeasurement) {
this.messageAlert("Units can't be empty.");
return false;
}
if (!this.formData.quantities) {
this.messageAlert("Work quantity cannot be empty.");
return false;
}
if (!this.formData.comprehensiveAmt) {
this.messageAlert("Unit price cannot be empty");
return false;
}
if (!this.formData.taxTotalAmtName.value) {
this.messageAlert("Please select tax rate");
return false;
}
return true;
},
messageAlert(content) {
$ifcaPopup.tips({ content: content, time: 1500}); ,}}};</script>
<style scoped lang="less"></style>
Copy the code
Each operation (add, modify, delete) will add the corresponding state to the data, which will tell the background this list of data is added or modified or deleted!!
Fourth, sample diagram