【Vue+Element】封装一个带时间段选项的日期组件、并且子任务日期限制在父任务日期内

需求如下

添加上午、下午时间段选择

要在element日期组件旁边添加一个上午、下午的选项框,没有这样的插槽使用,所以自己封装一个组件。通过定位的方式,将两个选项框移动到该位置。

由于我这边项目父组件是先渲染好组件,再获取数据,所以出现这边子组件渲染好但是没有数据的情况,使用watch监听它的变化

子任务日期限制在父任务日期内

新建子任务的时候,获取父任务时间范围,传递给子组件进行限制

实现

数据库如下

父组件使用子组件:

<!--html-->
<datepickerAMPM
    :dateRange="form.dateRange"
    :startTimePeriod="form.startTimePeriod"
    :endTimePeriod="form.endTimePeriod"
    :parentStartTimeStr="parentStartTimeStr"
    :parentEndTimeStr="parentEndTimeStr"
    @changeDateRange="changeDateRange"
    @changeStartP="changeStartP"
    @changeEndP="changeEndP"
/>

 父组件js

<!--js vue3 setup-->
import datepickerAMPM from "./datepickerAPMP.vue";

let form = ref({
    dateRange: [],
    startTimePeriod: '',
    endTimePeriod: '',
})

新建时,form为空
编辑时,初始化...获取form数据
// 选择父任务后,清空时间
   if (form.value.parentId){
      form.value.dateRange = []
      form.value.startTime = ''
      form.value.endTime = ''
      getTaskDetail(form.value.parentId)//获取父任务开始、结束时间,给子任务做一个时间限定
          .then((res) => {
            parentStartTimeStr.value = res.content.startTime
            parentEndTimeStr.value = res.content.endTime
          })
      }else {
          parentStartTimeStr.value = ''
          parentEndTimeStr.value = ''
      }

const changeDateRange = (e) => {
    // console.log('e',e)
    if (e.startTime!==''){
        form.value.startTime = e.startTime
        form.value.dateRange[0] = e.startTime
    }
    if (e.endTime!==''){
        form.value.endTime = e.endTime
        form.value.dateRange[1] = e.endTime
    }
}
const changeStartP = (e) => {
    if (e.startTimePeriod!==''){
        form.value.startTimePeriod = e.startTimePeriod
        // console.log('传输后的SP',form.value.startTimePeriod)
    }
}
const changeEndP = (e) => {
    if (e.endTimePeriod!==''){
        form.value.endTimePeriod = e.endTimePeriod
        // console.log('传输后的EP',form.value.startTimePeriod)
    }
}

子组件html+js:

<template>
  <div style="display: flex" class="selector">
    <el-date-picker
        style="width: 100%; height: 36px; "
        v-model="theDateRange"
        @change="changeDateRange"
        type="daterange"
        range-separator="至"
        start-placeholder="开始日期"
        end-placeholder="结束日期"
        format="YYYY/MM/DD"
        value-format="YYYY-MM-DD"
        :disabled-date="pickerOptions0"
    >
    </el-date-picker>
    <el-select
        v-model="theStartTimePeriod"
        placeholder="时间段"
        size="small"
        style="width: 85px;height: 36px;position: absolute;left: 30%;top: 2px;"
        @change="changeStartP"
    >
      <el-option
          v-for="item in period"
          :key="item.value"
          :label="item.label"
          :value="item.value"
      >
      </el-option>
    </el-select>
    <el-select
        v-model="theEndTimePeriod"
        placeholder="时间段"
        size="small"
        style="width: 85px;height: 36px;position: absolute;left:78%;top: 2px;"
        @change="changeEndP"
    >
      <el-option
          v-for="item in period"
          :key="item.value"
          :label="item.label"
          :value="item.value">
      </el-option>
    </el-select>
  </div>
</template>
<script>
import {watch, defineComponent, ref, toRefs} from "vue";

export default defineComponent({
  name: "datepickerAMPM",
  emits: ['changeDateRange','changeStartP','changeEndP'],
  props: {
    dateRange: {
      type: Array,
      default: [],
    },
    startTimePeriod: {
      type: String,
      default: '上午',
    },
    endTimePeriod: {
      type: String,
      default: '上午',
    },
    parentStartTimeStr: {
      type: String,
      default: '',
    },
    parentEndTimeStr: {
      type: String,
      default: '',
    },
  },
  setup(props, ctx) {
    // 转成响应式对象
    const { dateRange,startTimePeriod,endTimePeriod } = toRefs(props);

    const theDateRange = ref([])
    const theStartTimePeriod = ref('')
    const theEndTimePeriod = ref('')
    // 父任务日期字符串,用于限制子任务日期范围
    let theParentStartTimeStr = ref('')
    let theParentEndTimeStr = ref('')

    // 使用watch监听props的变化
    // 监听时间范围
    watch(dateRange, (newVal) => {
      theDateRange.value = newVal;
    });
    // 监听开始时间段
    watch(startTimePeriod, (newVal) => {
      theStartTimePeriod.value = newVal;
    });
    // 监听结束时间段
    watch(endTimePeriod, (newVal) => {
      theEndTimePeriod.value = newVal;
    });

    // 用于传给父组件
    let dateP = ref({
      startTime: theDateRange[0]===''?'':theDateRange[0],
      endTime: theDateRange[1]===''?'':theDateRange[1]
    })
    let datePS = ref({startTimePeriod: theStartTimePeriod.value})
    let datePE = ref({endTimePeriod: theEndTimePeriod.value})

    // 若有父任务的时间范围,将子任务时间范围限制在父任务的时间范围内
    let pickerOptions0 = (time) => {
      if (theParentStartTimeStr.value !== '' || theParentEndTimeStr.value !== '') {
        let parentStartTime = new Date(theParentStartTimeStr.value) // 8.64e7就是一天的时间戳
        let parentEndTime = new Date(theParentEndTimeStr.value)
        // 返回限制日期 它开始时间是包含(限制)的,所以要减1天,让他不包含(限制)
        return time.getTime() <= parentStartTime.getTime() - 8.64e7 || time.getTime() >= parentEndTime.getTime()
      } else {
        // 返回其余不限制的日期
        return false
      }
    }

    const period = ref([
      {
        value: '上午',
        label: '上午',
      },
      {
        value: '下午',
        label: '下午',
      }
    ])

    const changeDateRange = (data) => {
      if (data){
        //data格式 {0: '2024-01-22', 1: '2024-01-24'}
        dateP.value.startTime = data[0]
        dateP.value.endTime = data[1]
        if (theStartTimePeriod.value!=='') { // 有startP
          dateP.value.startTimePeriod = theStartTimePeriod.value
        }
        if (theEndTimePeriod.value!=='') { // 有endP
          dateP.value.endTimePeriod = theEndTimePeriod.value
        }
      }
      // 任何时候都传出去,在外面判断
      ctx.emit("changeDateRange", dateP.value);
    };
    const changeStartP = (sp) =>{
      datePS.value.startTimePeriod = sp
      // 任何时候都传出去,在外面判断
      ctx.emit("changeStartP", datePS.value);
    }
    const changeEndP = (ep) =>{
      datePE.value.endTimePeriod = ep
      // 任何时候都传出去,在外面判断
      ctx.emit("changeEndP", datePE.value);
    }

    return {
      changeDateRange,
      pickerOptions0,
      theDateRange,
      theStartTimePeriod,
      theEndTimePeriod,
      period,
      changeStartP,
      changeEndP,
      dateP,
      dateRange,
      startTimePeriod,
      endTimePeriod,

      datePS,
      datePE
    };
  },
});
</script>


<style scoped>
.selector /deep/ .el-range-editor--medium .el-range-input {
  text-align: left;
  margin-left: 10%;
  /*color: red;*/
  /*border: 1px red solid;*/
}

.selector /deep/ .el-select .el-input__inner {
  border: 0;

}
</style>

  • 10
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值