el-date-picker 日期组件切换的坑
问题描述:
问题1. 根据类型切换需要的时间选择器组件(搜索栏是一个form组件,里面有input、select、picker等,在使用的页面里传入指定的类型就能展示)第一次按顺序切换日常发,周常发,月常发是没问题的,但是当第二次选择周常发时,选择器无变化,然后再一次切换会出现上一次应该出现的选择器,并且会有 问题2. 选择器错位的现象
解决:
传给后端的值为 startTIme、endTime但实际选择器保存的是一个未格式化的时间,问题1:应该在每次切换select值后删除日期的值(为了处理后端需要的数据格式因此日 周 月保存的时间值是同一个)问题2:在form组件中给每个picker添加key
完整的formComponent组件
<!--
* @Description: form组件 页面
* @Use: type可选值:'',numberInput,select,dept,radio,switch,date,daterange,dateNoTime,datetimerange
* @Author: mhf
* @Date: 2023-06-29 17:08:33
-->
<!-- eslint-disable vue/no-mutating-props -->
<template>
<div class="search-component">
<!-- 表单区域 -->
<el-form ref="formRef" :model="form" :inline="inline" :rules="formRules">
<el-form-item
v-for="(item, index) in formLabel"
:key="index"
:label="item.label + ' :'"
:prop="item.value"
>
<el-input
v-if="!item.type"
v-model.trim="form[item.value]"
:placeholder="'请输入' + item.label"
size="small"
:type="item.type ? item.type : 'text'"
/>
<el-input
v-if="item.type === 'numberInput'"
v-model.number="form[item.value]"
:placeholder="'请输入' + item.label"
size="small"
/>
<el-select
v-if="item.type === 'select'"
v-model.trim="form[item.value]"
filterable
:placeholder="'请选择' + item.label"
clearable
size="small"
>
<el-option
v-for="(items, index) in item.opts"
:key="index"
:label="items[item.optLabel]"
:value="items[item.optValue]"
@click.native="selectClick(item, items)"
/>
</el-select>
<treeselect
v-if="item.type === 'dept'"
v-model="form[item.value]"
class="treeBox"
:options="item.opts"
:show-count="true"
:placeholder="'请选择' + item.label"
/>
<template v-if="item.type === 'radio'">
<el-radio
v-for="items in item.opts"
:key="items.value"
v-model="form[item.value]"
:label="items.value"
>{{ items.label }}
</el-radio>
</template>
<el-switch v-if="item.type === 'switch'" v-model="form[item.value]" />
<el-date-picker
v-if="item.type === 'date'"
key="date"
v-model="form[item.value]"
type="date"
placeholder="选择日期"
value-format="yyyy-MM-dd HH:mm:ss"
/>
<el-date-picker
v-if="item.type === 'dateNoTime'"
key="dateNoTime"
v-model="form[item.value]"
type="date"
placeholder="选择日期"
value-format="yyyy-MM-dd"
/>
<el-date-picker
v-if="item.type === 'datetimerange'"
key="datetimerange"
v-model="form[item.value]"
type="datetimerange"
:picker-options="pickerOptions"
range-separator="至"
start-placeholder="开始日期"
end-placeholder="结束日期"
align="right"
value-format="yyyy-MM-dd HH:mm:ss"
/>
<el-date-picker
v-if="item.type === 'daterange'"
key="daterange"
v-model="form[item.value]"
type="daterange"
:picker-options="pickerOptions"
range-separator="至"
start-placeholder="开始日期"
end-placeholder="结束日期"
align="right"
value-format="yyyy-MM-dd"
@change="daterangeChange"
/>
<el-date-picker
v-if="item.type === 'week'"
key="week"
v-model="form[item.value]"
type="week"
format="yyyy 第 WW 周"
placeholder="选择周"
@change="weekChange"
>
</el-date-picker>
<el-date-picker
v-if="item.type === 'month'"
key="month"
v-model="form[item.value]"
type="month"
placeholder="选择月"
value-format="yyyy-MM-dd"
@change="monthChange"
>
</el-date-picker>
</el-form-item>
<el-form-item>
<slot name="formSlot" />
</el-form-item>
<div v-if="showOperationBtn" class="right-handle">
<el-form-item>
<el-button
type="primary"
size="small"
icon="el-icon-search"
@click="handleSearch"
>查询
</el-button>
<el-button
size="small"
icon="el-icon-refresh"
@click="handleResetFrom"
>重置
</el-button>
</el-form-item>
<el-form-item />
<el-form-item>
<slot name="handleSlot" />
</el-form-item>
</div>
</el-form>
</div>
</template>
<script>
export default {
name: "SearchComponent",
props: {
inline: {
type: Boolean,
default: true,
},
// eslint-disable-next-line vue/require-default-prop
form: {
type: Object,
required: true,
},
// eslint-disable-next-line vue/require-default-prop
formLabel: {
type: Array,
required: true,
},
// eslint-disable-next-line vue/require-default-prop
formRules: {
type: Object,
default: () => {
return {};
},
},
labelWidth: {
type: Number,
default: 90,
},
showOperationBtn: {
type: Boolean,
default: true,
},
},
// 用来以对象方式存放数据
data() {
return {
pickerOptions: {
shortcuts: [
{
text: "今天",
onClick(picker) {
const startTime = new Date(new Date().setHours(0, 0, 0));
const endTime = new Date(new Date().setHours(23, 59, 59));
// const endTime = new Date(); //
picker.$emit("pick", [startTime, endTime]);
},
},
{
text: "最近一周",
onClick(picker) {
const end = new Date();
const start = new Date();
start.setTime(start.getTime() - 3600 * 1000 * 24 * 7);
picker.$emit("pick", [start, end]);
},
},
{
text: "最近一个月",
onClick(picker) {
const end = new Date();
const start = new Date();
start.setTime(start.getTime() - 3600 * 1000 * 24 * 30);
picker.$emit("pick", [start, end]);
},
},
{
text: "最近三个月",
onClick(picker) {
const end = new Date();
const start = new Date();
start.setTime(start.getTime() - 3600 * 1000 * 24 * 90);
picker.$emit("pick", [start, end]);
},
},
],
},
};
},
created() {},
mounted() {},
methods: {
selectClick(item, items) {
this.$emit("selectChange", { item, items });
},
handleSearch() {
this.$emit("handleSearch", this.form);
},
handleResetFrom() {
this.$emit("handleResetFrom");
},
daterangeChange(val) {
this.$emit("daterangeChange", val);
},
weekChange(val) {
let timeArr = [];
if (val) {
let startTime = new Date(val.getTime()); //开始时间
let endTime = new Date(val.getTime() + 24 * 60 * 60 * 1000 * 6); //结束时间
timeArr = [
startTime.toISOString().slice(0, 10),
endTime.toISOString().slice(0, 10),
];
}
this.$emit("getTimeArr", timeArr);
},
monthChange(val) {
const [year, month, day] = val.split("-");
const endDate = new Date(year, month, 0).getDate();
let timeArr = [`${year}-${month}-${day}`, `${year}-${month}-${endDate}`];
this.$emit("getMonthArr", timeArr);
},
},
};
</script>
<style lang="scss" scoped>
.search-component {
.right-handle {
display: inline-block;
margin-left: 30px;
}
}
.treeBox {
width: 242px;
}
</style>
使用的完整的页面
<!--
* @Description: 常发拥堵路段 页面
* @Author: mhf
* @Date: 2023-09-14 15:46:36
-->
<template>
<div>
<newPageCompYt
ref="newPageCompYt"
idName="id"
:formLabel="formLabel"
:btnList="btnList"
:tableData="tableData"
:tableConfig="tableConfig"
:tableDataColumn="tableDataColumn"
:total="total"
:paginationConfig.sync="paginationConfig"
:pageSizes="pageSizes"
:exportTypeAndUrl="exportTypeAndUrl"
:customObj="customObj"
@on-response="getBtnType"
@resetForm="resetForm"
@getTableData="getTableData"
@daterangeChange="daterangeChange"
@getTimeRange="getTimeRange"
@getMonthArr="getMonthArr"
@formSelectChange="formSelectChange"
>
<template slot="roadType" slot-scope="scope">
<dict-tag
:options="dict.type.traffic_road_type"
:value="scope.row.roadType"
/>
</template>
<template slot="roadDirection" slot-scope="scope">
<dict-tag
:options="dict.type.traffic_road_direction"
:value="scope.row.roadDirection"
/>
</template>
</newPageCompYt>
</div>
</template>
<script>
import { getLastNumDay } from "@/utils/publicFun";
import { getRoadBlockList } from "@/api/statisticAnalysis/statisticAnalysis";
export default {
name: "roadCongested",
components: {},
props: {},
dicts: ["traffic_often_type", "traffic_road_type", "traffic_road_direction"],
computed: {
customObj() {
let flag = false;
if (this.paginationConfig.queryAllTime) {
flag =
this.paginationConfig.queryAllTime.length > 0 ||
this.paginationConfig.queryAllTime !== [];
} else {
flag = false;
}
return {
startTime: flag
? this.paginationConfig.queryAllTime[0] + " 00:00:00"
: null,
endTime: flag
? this.paginationConfig.queryAllTime[1] + " 23:59:59"
: null,
oftenType: this.paginationConfig.oftenType,
pageNum: this.paginationConfig.pageNum,
pageSize: this.paginationConfig.pageSize,
};
},
},
data() {
return {
formLabel: [
{
label: "常发类型",
value: "oftenType",
type: "select",
opts: [],
dict: "traffic_often_type",
optLabel: "dictLabel",
optValue: "dictValue",
},
{
label: "日期",
value: "queryAllTime",
type: "daterange",
},
],
btnList: [
{
name: "导出",
icon: "iconfont if-daochu",
color: "#1492FF",
hasPermi: "system:user:resetPwd",
},
],
tableData: [],
tableConfig: {
isLoading: false,
},
tableDataColumn: [
{ name: "序号", value: "index" },
{ name: "路段名称", value: "roadName" },
{ name: "道路方向", value: "roadDirection", isSlot: true },
{ name: "道路等级", value: "roadType", isSlot: true },
],
total: 0,
paginationConfig: {
pageNum: 1,
pageSize: 10,
},
pageSizes: [5, 10, 15, 20],
exportTypeAndUrl: {
isCustom: true,
exportType: "trafficTrend",
exportUrl: "/trafficRun/dataReport/congestedRoad",
},
};
},
methods: {
getTableData() {
this.tableConfig.isLoading = true;
const { queryAllTime, ...obj } = this.paginationConfig;
getRoadBlockList(obj).then((response) => {
this.tableData = response.data.rows !== null ? response.data.rows : [];
this.total = response.data.total;
this.tableConfig.isLoading = false;
});
},
getSETime(timeArr) {
if (timeArr.length > 0) {
this.$set(this.paginationConfig, "startTime", timeArr[0] + " 00:00:00");
this.$set(this.paginationConfig, "endTime", timeArr[1] + " 23:59:59");
} else {
this.$set(this.paginationConfig, "startTime", null);
this.$set(this.paginationConfig, "endTime", null);
}
},
daterangeChange(timeRange) {
this.getSETime(timeRange);
},
getTimeRange(timeRange) {
this.getSETime(timeRange);
},
getMonthArr(timeRange) {
this.getSETime(timeRange);
},
weekChange(val) {
// let timeArr = []
// if (val) {
// let startTime = new Date(val.getTime()); //开始时间
// let endTime = new Date(val.getTime() + (24 * 60 * 60 * 1000) * 6); //结束时间
// timeArr = [startTime.toISOString().slice(0, 10), endTime.toISOString().slice(0, 10)];
// }
},
formSelectChange(obj) {
if (obj.item.label === "常发类型") {
let arr = [
{
label: "日期",
value: "queryAllTime",
type: "daterange",
},
{
label: "日期",
value: "queryAllTime",
type: "week",
},
{
label: "日期",
value: "queryAllTime",
type: "month",
},
];
this.formLabel[1] = arr[obj.items.dictValue - 1]
this.$set(this.paginationConfig, 'queryAllTime', null)
delete this.paginationConfig.queryAllTime // 主要是这步 清空原先保存的值(问题1)
this.getSETime([])
}
},
getBtnType(type) {
console.log(type);
},
resetForm() {
let timeArr = getLastNumDay(30, false);
this.$set(this.paginationConfig, "queryAllTime", timeArr);
this.$set(this.paginationConfig, "startTime", timeArr[0]);
this.$set(this.paginationConfig, "endTime", timeArr[1]);
this.$set(this.paginationConfig, "oftenType", "1");
this.formLabel[1] = {
label: "日期",
value: "queryAllTime",
type: "daterange",
};
},
},
created() {
this.resetForm();
},
mounted() {},
};
</script>
<style lang="scss" scoped></style>
问题2 看此段即可
<el-date-picker
v-if="item.type === 'datetimerange'"
key="datetimerange"
v-model="form[item.value]"
type="datetimerange"
:picker-options="pickerOptions"
range-separator="至"
start-placeholder="开始日期"
end-placeholder="结束日期"
align="right"
value-format="yyyy-MM-dd HH:mm:ss"
/>