vue的年度选择器组件YearPicker

691 阅读1分钟

element-ui和iView的DatePicker的年份选择组件不兼容ie11,所以只能自己动手写个了,需要的希望给个收藏点赞,thank you。

代码:

<template>
  <div class="year-picker">
    <input placeholder="请选择年份"
           :class="['year-picker__input','year-picker__input--real',showYearContent?'year-picker__input--focus':'']"
           v-model="value"
           type="text"
           readonly
           @click.stop="inputFocus"
    >
    <div class="year-picker__year-box" v-if="showYearContent">
      <div class="year-picker__input">{{value}}</div>
      <div class="year-picker__year-title">
        <span class="to-left" @click="toLeft()"><<</span>
        <strong>{{yearStart}}--{{yearEnd - 1}}</strong>
        <span class="to-right" @click="toRight()">>></span>
      </div>
      <div class="year-picker__year-content">
        <span v-for="(item,index) in yearList" :key="index" :class="{ 'year-text': 1 ,'year-disable':yearDis(item)}"
              @click="chooseYear(item)">{{item}}
        </span>
      </div>
    </div>
  </div>
</template>

<script>
export default {
  name: 'YearPicker',
  props: {
    yearDisable: {
      type: String,
      default: 'no'
    },
    value: {
      type: Number,
    }
  },
  data() {
    return {
      yearLists: [],
      year: '',
      showYearContent: false,
      yearStart: 2010,<template>
  <div class="year-picker">
    <input placeholder="请选择年份"
           :class="['year-picker__input','year-picker__input--real',showYearContent?'year-picker__input--focus':'']"
           v-model="value"
           type="text"
           readonly
           @click.stop="inputFocus"
    >
    <div class="year-picker__year-box" v-if="showYearContent">
      <div class="year-picker__input">{{value}}</div>
      <div class="year-picker__year-title">
        <span class="to-left" @click="toLeft()"><<</span>
        <strong>{{yearStart}}--{{yearEnd - 1}}</strong>
        <span class="to-right" @click="toRight()">>></span>
      </div>
      <div class="year-picker__year-content">
        <span v-for="(item,index) in yearList" :key="index" :class="{ 'year-text': 1 ,'year-disable':yearDis(item)}"
              @click="chooseYear(item)">{{item}}
        </span>
      </div>
    </div>
  </div>
</template>

<script>
export default {
  name: 'YearPicker',
  props: {
    yearDisable: {
      type: String,
      default: 'no'
    },
    yearStart:{  //默认年份开始
      type: Number,
      default: 2010
    },
    yearEnd:{ //默认年份结束
      type: Number,
      default: 2030
    },
    value: {
      type: Number,
    }
  },
  data() {
    return {
      yearLists: [],
      year: '',
      showYearContent: false,
    }
  },
  created() {
    document.addEventListener('click', this.lisFunc, true)
  },
  destroyed() {
    document.removeEventListener('click', this, lisFunc, true)
  },
  methods: {
    lisFunc(e) {
      const box = document.querySelector('.year-picker__year-box')
      if (!box.contains(e.target)) {
        this.inputBlur();
      }
    },
    inputFocus() {
      this.showYearContent = true
    },
    inputBlur() {
      this.showYearContent = false
    },
    chooseYear(year) {
      if (year > this.yearDis) return
      this.showYearContent = false
      this.year = year + '年'
      this.$emit('input', year)
    },
    toLeft() {
      this.yearStart -= 20
      this.yearEnd -= 20
    },
    toRight() {
      this.yearStart += 20
      this.yearEnd += 20
    }
  },
  computed: {
    yearDis() {
      return function (y) {
        switch (this.yearDisable) {
          case 'before': {
            return y < new Date().getFullYear()
          }
            break;
          case 'no': {
            return false
          }
            break;
          case 'after': {
            return y > new Date().getFullYear()
          }
        }
      }
    },
    yearList() {
      let arr = []
      for (let i = this.yearStart; i < this.yearEnd; i++) {
        arr.push(i)
      }
      return arr
    }
  }
}
</script>

<style scoped lang="less">
@blue-border: #004c99;
.year-picker {
  display: inline-block;
  width: 100%;
  border-radius: 2px;

  .year-picker__icon {
    position: absolute;
    transform: translate(-26px, 10px);
    color: #d9d9d9
  }

  .year-picker__input {
    color: #595959;
    width: 100%;
    height: 32px;
    border: none;
    border-radius: 2px;
    text-indent: 10px;
    line-height: 32px;
    outline: none;
    background: #fcfcfc;
  }

  .year-picker__input::placeholder {
    color: #c3cbd6;
  }

  .year-picker__input::-webkit-input-placeholder {
    color: #c3cbd6;
  }

  .year-picker__input--real {
    border: 1px solid #d9d9d9;
    height: 32px;
  }

  .year-picker__input--focus {
    //opacity: 0;
  }

  .year-picker__input--real:hover {
    border: 1px solid #ffc335;
  }

  .year-picker__year-title {
    height: 40px;
    width: 270px;
    border-top: 1px solid #d4d4d4;
    border-bottom: 1px solid #d4d4d4;
    display: flex;
    justify-content: space-around;
    align-items: center;

    span {
      color: #525252;
      cursor: pointer;
    }

    span:active {
      opacity: .5;
    }
  }

  .year-picker__year-box {
    position: absolute;
    z-index: 10;
    background: #ffffff;
    border-radius: 5px;
    border: 1px solid #eeeeee;
    box-shadow: 0 0 .38rem 0 rgba(0, 0, 0, 0.1);
    transform: translateY(-32px);
  }

  .year-picker__year-content {
    padding-top: 20px;
    width: 270px;
    height: 250px;
    display: flex;
    flex-wrap: wrap;
    justify-content: space-around;

    .year-text {
      color: #525252;
      font-size: 12px;
      width: 48px;
      height: 25px;
      display: flex;
      justify-content: center;
      align-items: center;
    }

    .year-text:hover {
      cursor: pointer;
      /*border: 1px solid #333333;*/
      background: rgba(157, 219, 252, 0.41);
      border-radius: 3px;
    }

    .year-disable {
      background: #f5f5f5;
    }

    .year-disable:hover {
      cursor: no-drop;
      background: #f5f5f5;
    }
  }
}
</style>

     

调用:

<YearPicker v-model="publishYear" @input="getPulishYear" />
 getPulishYear(data) {
      this.publishYear = data;
 },