一、需求
-
动态添加/删减表格
-
选中code,根据code找出相对应的name和日期,并且填充到input之中
-
选中name,根据name找出相对应的code和日期,并且填充到input之中
-
日期默认为一年前的今天
-
表头根据UI图修改
-
可选时间范围是后台给的时间和当前时间的前一天这个区间
-
获取日期后跟默认时间相比较,规则如下:
1、 后台所给时间比默认时间大,选择默认时间
2、后台所给时间比默认时间小,选择后台所给时间
二、完整代码
<template>
<div class="main">
<el-table
:data="tableData"
style="width: 100%"
:header-cell-style="{
background: '#eeeeee',
color: '#000000',
fontWeight: '600',
textAlign: 'center',
}"
>
<el-table-column prop="code" label="代码">
<template slot-scope="scope">
<el-select
v-model="scope.row.code"
filterable
remote
reserve-keyword
placeholder="输入选择"
:loading="loading"
@change="queryCode($event, scope.$index)"
>
<el-option
v-for="item in options"
:key="item.code"
:label="item.code"
:value="item.code"
:disabled="item.disabled"
/>
</el-select>
</template>
</el-table-column>
<el-table-column prop="name" label="名称">
<template slot-scope="scope">
<el-select
v-model="scope.row.name"
filterable
remote
reserve-keyword
placeholder="请选择"
:loading="loading"
@change="queryName($event, scope.$index)"
>
<el-option
v-for="item in options"
:key="item.code"
:label="item.name"
:value="item.name"
:disabled="item.disabled"
/>
</el-select>
</template>
</el-table-column>
<el-table-column prop="start_date" label="日期">
<template slot-scope="scope">
<el-date-picker
v-model="scope.row.start_date"
type="date"
format="yyyy/MM/dd"
value-format="yyyy/MM/dd"
:picker-options="pickerOptions"
@focus="OutputIndex(scope.$index)"
placeholder="选择日期"
/>
</template>
</el-table-column>
<el-table-column prop="address" label="操作" width="80">
<template slot-scope="scope">
<i
:class="scope.row.status"
@click="operation(scope.row, scope.$index)"
/>
</template>
</el-table-column>
</el-table>
</div>
</template>
<script>
import { getList } from "@/api/index";
export default {
name: "timeFrame",
data() {
return {
tableData: [
{
code: "",
name: "",
start_date: "",
status: "increase",
},
],
options: [], // 保存后端所给的数据
loading: false,
optionsArr: [], // 保存所有选过的code,选过之后不能再次选择,这个数组中的code相对应的对象都添加disable
testTime: [], // 保存被选的当前行后台传回的时间,根据这个时间去控制当前行每个时间的可选范围
tableIndex: "", // 被保存的下标,根据此下标去找testTime数组中的相对应的时间,控制可选时间的范围
pickerOptions: {
disabledDate: (time) => {
return this.selectTime(time); // 调用控制当前行时间可选范围的方法
},
},
};
},
mounted() {
// 获取后端数据
this.getList();
// 给表格第一行的时间赋值默认时间(一年前的今天)
this.tableData[0].start_date = this.OutputTime();
},
methods: {
// 获取后端数据
getList() {
getList().then((res) => {
console.log(res.data);
this.options = res.data.result;
});
},
// 获取当前下标,给选择时间控件使用
OutputIndex(index) {
// 保存一个下标,根据下标去找this.testTime数组中相对应的时间
this.tableIndex = index;
},
// 时间可选范围的处理
selectTime(time) {
// 根据下标去获取保存在this.testTime数组中相对应的时间
const rowTime = this.testTime[this.tableIndex];
// 解析当前时间,把后端传回的时间转换为时间戳
const timestamp = Date.parse(rowTime);
// 返回一个true
return (
// 过去的48小时不能选择
time.getTime() > Date.now() - 48 * 60 * 60 * 1000 ||
// 后台传的时间的以前的时间不可以选
time.getTime() < timestamp
);
},
// 根据所选代码赋值
queryCode(code, index) {
// 被选过的code
this.optionsArr[index] = code;
// 根据选择的code找后端给的数据中的当前对象
const optionsObj = this.options.find((obj) => {
return obj.code === code;
});
// 根据选择的code找列表中的当前对象
const tableDataObj = this.tableData.find((obj) => {
return obj.code === code;
});
// 后台传给的时间
const productTime = optionsObj.start_date;
// 默认时间
const defaultTime = this.OutputTime();
// 根据下标保存被选过的时间
this.testTime[index] = productTime;
/*
* 后台传的时间比默认时间大,选择默认时间
* 后台传时间比默认时间小,选择后台传时间
* */
// 用后台传给的时间和默认时间作比较
if (new Date(productTime) >= new Date(defaultTime)) {
// 后台传的时间比默认时间大,选择默认时间
this.$set(tableDataObj, "start_date", productTime);
} else {
// 后台传时间比默认时间小,选择后台传时间
this.$set(tableDataObj, "start_date", defaultTime);
}
// 给当前对象相对应的name复制
this.$set(tableDataObj, "name", optionsObj.name);
// 遍历所保存的后台传回的数据和遍历已选的,如果code相同择给当前对象添加disabled未true;
this.options.map((i) => {
i.disabled = false;
this.optionsArr.map((j) => {
if (i.code === j) {
i.disabled = true;
}
});
});
},
// 根据所选名称赋值
queryName(name, index) {
// 根据name查找后台传输数据中相对应的对象
const optionsObj = this.options.find((obj) => {
return obj.name === name;
});
// 被选中的对象的code保存到this.optionsArr数组中指定下标的位置
this.optionsArr[index] = optionsObj.code;
// 根据选择的code找列表中的当前对象
const tableDataObj = this.tableData.find((obj) => {
return obj.name === name;
});
// 后台传给的时间
const productTime = optionsObj.start_date;
// 默认时间
const defaultTime = this.OutputTime();
// 根据下标保存被选过的时间
this.testTime[index] = productTime;
/*
* 后台传的时间比默认时间大,选择默认时间
* 后台传的时间比默认时间小,选择后台传的时间
* */
// 用后台传给的时间和默认时间作比较
if (new Date(productTime) >= new Date(defaultTime)) {
// 后台传的时间比默认时间大,选择默认时间
tableDataObj.start_date = productTime;
} else {
// 后台传的时间比默认时间小,选择后台传的时间
tableDataObj.start_date = defaultTime;
}
// 给当前对象相对应的name复制
tableDataObj.code = optionsObj.code;
// 遍历所保存的后台传回的数据和遍历已选的,如果code相同择给当前对象添加disabled未true;
this.options.map((i) => {
i.disabled = false;
this.optionsArr.map((j) => {
if (i.code === j) {
i.disabled = true;
}
});
});
},
// 增加或减少列表
operation(row, index) {
// 用increase字段来判断是增加列表还是删减列表,increase是曾加,reduce是删减
if (row.status === "increase") {
// 创建一个对象
const obj = {
code: "",
name: "",
start_date: this.OutputTime(),
status: "reduce",
};
// 把创建对象push到tableData数组中
this.tableData.push(obj);
} else {
// 在optionsArr数组中寻找是否有当前code
if (this.optionsArr.includes(row.code)) {
// 如果有就删去下标对应的当前对象
this.tableData.splice(index, 1);
// 同时删掉optionsArr数组中当前的code
this.optionsArr.splice(index, 1);
// 遍历保存的后台数据,把被删掉的code对应的对象的disabled改为false
this.options.map((i) => {
i.disabled = false;
this.optionsArr.map((j) => {
if (i.code === j) {
i.disabled = true;
}
});
});
} else {
// 删掉未被复制code空列表的当前行
this.tableData.splice(index, 1);
}
}
},
// 输出一年前时间
OutputTime() {
const nowDate = new Date();
const date = new Date(nowDate);
date.setDate(date.getDate() - 365);
const Slash = "/";
const year = date.getFullYear();
let month = date.getMonth() + 1;
let strDate = date.getDate();
if (month >= 1 && month <= 9) {
month = "0" + month;
}
if (strDate >= 0 && strDate <= 9) {
strDate = "0" + strDate;
}
const currentDate = year + Slash + month + Slash + strDate;
return currentDate;
},
},
};
</script>
<style lang="scss" scoped>
.main {
width: 820px;
margin: 0 auto;
::v-deep .el-input__inner {
border: none;
}
::v-deep .el-table__row {
td {
text-align: center;
}
}
.increase {
display: inline-block;
width: 20px;
height: 20px;
background-image: url("../../assets/images/increase.svg");
background-repeat: no-repeat;
}
.reduce {
display: inline-block;
width: 20px;
height: 20px;
background-image: url("../../assets/images/reduce.svg");
background-repeat: no-repeat;
}
}
</style>
三、后台传回的数据格式
"result": [{
"code": "10000",
"name": "Shirley Jackson",
"start_date": "2021/03/08"
},
{
"code": "20000",
"name": "Eric Wilson",
"start_date": "2021/03/18"
},
{
"code": "30000",
"name": "Shirley Wilson",
"start_date": "2020/08/27"
},
{
"code": "40000",
"name": "Ruth Gonzalez",
"start_date": "2020/09/02"
},
{
"code": "50000",
"name": "Eric Harris",
"start_date": "2020/09/03"
},
]