项目场景:

使用ant-design-vue实现一个自定义日期选择的下拉框,下拉框选项中包含近一周、近一个月、最近一年和自定义日期(如下图)。
在这里插入图片描述


问题描述

这里使用 a-select 组件的 dropdownRender 对下拉菜单进行扩展。当鼠标移入到自定义选项时,展示组件 a-range-picker ,当聚焦在 a-range-picker 时,下方的日期选择出现在左上方!(由图一到图二)

图一

在这里插入图片描述


原因分析:

提示:这里填写问题的分析:

a-range-picker 组件定义浮层的容器默认为body
在这里插入图片描述


解决方案:

修改 a-range-picker 浮层的容器为父元素

关键代码

<a-range-picker 
	v-show="rangPickerOpen" 
	change="rangPickerChange"
	openChange="openORclosePanel"
 	:getCalendarContainer="(trigger) => {
 		return trigger.parentNode || document.body;
		 }"
 /> ```

组件代码

<template>
  <div class="dateSelect">
    <a-select
      ref="selectRef"
      default-value="month"
      :open="open"
      @focus="selectFocus"
      @blur="selectBlur"
      @select="selected"
      v-model="val"
    >
      <div slot="dropdownRender" slot-scope="menu">
        <v-nodes :vnodes="menu" />
        <a-divider style="margin: 4px 0" />
        <div
          style="padding: 4px 16px; cursor: pointer; position: relative"
          @mousedown="(e) => e.preventDefault()"
          @mouseenter="rangPickerOpen = true"
          @mouseleave="rangPickerOpen = false"
        >
          <span>自定义</span>
          <div
            style="
              width: 300px;
              position: absolute;
              left: 100%;
              top: -5px;
              margin-left: 1px;
            "
          >
            <a-range-picker
              v-show="rangPickerOpen"
              @change="rangPickerChange"
              @openChange="openORclosePanel"
              
            />
          </div>
        </div>
      </div>
      <a-select-option value="week"> 近一周 </a-select-option>
      <a-select-option value="month"> 近一个月 </a-select-option>
      <a-select-option value="year"> 最近一年 </a-select-option>
      <a-select-option :key="i" v-for="(item,i) in customTime" :value="item.value"> {{item.title}} </a-select-option>
    </a-select>
  </div>
</template>

<script lang="ts">
import { Component, Ref, Vue, Emit, Watch } from "vue-property-decorator";
import moment from "moment";
import { Switch } from "ant-design-vue";

@Component({
  components: {
    VNodes: {
      functional: true,
      render: (h: any, ctx: any) => ctx.props.vnodes,
    },
  },
})
export default class DateSelect extends Vue {
  @Ref() readonly selectRef!:any
  rangPickerOpen: boolean = false;
  open: boolean = false;
  val:string = 'month'
  dateString:any[] = []
  customTime:any[] = []

  selectFocus() {
    this.open = true;
  }
  selectBlur() {
    if(this.rangPickerOpen) return
    this.open = false
  }
  selected() {
    this.selectRef.blur()
  }

  @Watch('val')
  onValChange() {
    if(this.val === 'custom') {
      this.$emit('selectChange', {
        startTime: this.dateString[0],
        endTime: this.dateString[1]
      })
    } else {
      const range = this.getTime(this.val)
      this.$emit('selectChange', range)
    }
  }

  getTime(range:any) {
    console.log(range);
    let startTime = ''
    let endTime = ''
    switch(range) {
      case 'week':
        startTime = moment().subtract(1, 'weeks').format('YYYY-MM-DD')
        endTime = moment().format('YYYY-MM-DD')
        break;
      case 'month':
        startTime = moment().subtract(1, 'months').format('YYYY-MM-DD')
        endTime = moment().format('YYYY-MM-DD')
        break;
      case 'year':
        startTime = moment().subtract(1, 'years').format('YYYY-MM-DD')
        endTime = moment().format('YYYY-MM-DD')
        break;
      default :
        startTime = ''
        endTime = ''
    }
    return {
      startTime,
      endTime
    }
  }
  
  // 日期选择改变后,select下新增一条自定义范围的时间选项
  rangPickerChange(date: any[], dateString: string[]) {
    this.dateString = dateString
    this.customTime = [{
      title: moment(date[0]).format('YYYY.M.D') + ' 至 ' + moment(date[1]).format('YYYY.M.D'),
      value: 'custom'
    }]
    this.val = this.customTime[0].value
  }
  // 弹出或关闭面板的回调
  openORclosePanel(status:boolean) {
    this.open = status
  }

}
</script>

<style scoped lang="less">
.dateSelect {
  margin-bottom: 16px;
  .ant-select {
    width: 240px;
  }
}
</style>
Logo

前往低代码交流专区

更多推荐