• 日期组件


    自定义日期组件

    DatePicker.vue

    <template>
      <div class="e-calendar-wrapper">
        <div class="e-calendar">
          <div class="e-date-select">
            <el-button
              type="primary"
              style="background: #43BAFE"
              icon="el-icon-plus"
              size="small"
              @click="addMeeting"
            >添加会议</el-button>
          </div>
          <div class="e-calendar-container" v-show="!showYear">
            <div class="e-calendar-toolbar">
              <div class="e-calendar-svg" @click="prevMonth">
                <svg viewBox="0 0 24 24" class="e-calendar-svg-icon">
                  <path d="M15.41 7.41L14 6l-6 6 6 6 1.41-1.41L10.83 12z"></path>
                </svg>
                <transition name="e_calendar_svg_btn">
                  <div class="e-calendar-svg-cover" v-if="prevMonthClick"></div>
                </transition>
              </div>
              <div class="e-calendar-toolbar-title">
                <transition :name="fadeXType">
                  <div :key="showDate.monthStr" class="e-calendar-toolbar-title-content">
                    <strong>{{showDate.year}}年</strong>
                    <span>{{ showDate.monthStr }}</span>
                  </div>
                </transition>
              </div>
              <div class="e-calendar-svg" @click="nextMonth">
                <svg viewBox="0 0 24 24" class="e-calendar-svg-icon">
                  <path d="M10 6L8.59 7.41 13.17 12l-4.58 4.59L10 18l6-6z"></path>
                </svg>
                <transition name="e_calendar_svg_btn">
                  <div class="e-calendar-svg-cover" v-if="nextMonthClick"></div>
                </transition>
              </div>
            </div>
            <div class="e-calendar-week">
              <span class="e-calendar-week-day">日</span>
              <span class="e-calendar-week-day">一</span>
              <span class="e-calendar-week-day">二</span>
              <span class="e-calendar-week-day">三</span>
              <span class="e-calendar-week-day">四</span>
              <span class="e-calendar-week-day">五</span>
              <span class="e-calendar-week-day">六</span>
            </div>
            <div class="e-calendar-monthday">
              <transition :name="fadeXType">
                <div :key="showDate.monthStr" class="e-calendar-monthday-wrapper">
                  <div class="e-calendar-monthday-row" v-for="( row,index) in rows" :key="index">
                    <span
                      v-for="(day,index) in row"
                      :key="index"
                      class="e-calendar-monthday-row-day"
                      @click="selectDay(day)"
                      :class="{'active': day.selected, 'disabled': day.disabled, 'pointer': day.value !== ''}"
                    >
                      <span v-text="day.value" class="e-calendar-monthday-row-day-value"></span>
                      <transition name="e_calendar_day">
                        <span class="e-calendar-monthday-row-day-cover" v-if="day.selected"></span>
                      </transition>
                    </span>
                  </div>
                </div>
              </transition>
            </div>
          </div>
          <ul class="e-calendar-year" v-show="showYear" ref="yearList">
            <li
              v-for="item in yearList"
              :key="item"
              v-text="item"
              :class="{'active': item === selectDate.year}"
              @click="selectYear(item)"
            ></li>
          </ul>
          <div class="e-calendar-actions">
            <button class="btn" @click="cancel">取消</button>
            <button class="btn" @click="confirm">确定</button>
          </div>
        </div>
      </div>
    </template>
    <script>
    import Vue from "vue";
    import { Button } from "element-ui";
    Vue.use(Button);
    // 阿拉伯数字 转 汉字数字的基本库
    const weekJson = {
      1: "星期日",
      2: "星期一",
      3: "星期二",
      4: "星期三",
      5: "星期四",
      6: "星期五",
      7: "星期六"
    };
    const monthJson = {
      1: "1月",
      2: "2月",
      3: "3月",
      4: "4月",
      5: "5月",
      6: "6月",
      7: "7月",
      8: "8月",
      9: "9月",
      10: "10月",
      11: "11月",
      12: "12月"
    };
    export default {
      name: "DatePicker",
      props: {
        // 打开date picker的初始值,必传,格式是(2017-08-11)
        date: {
          type: String,
          required: true
        },
        // 日期最小值
        minDate: {
          type: String,
          default: "1970-01-01"
        },
        // 日期最大值
        maxDate: {
          type: String,
          default: "2020-12-31"
        }
      },
      computed: {
        yearList() {
          const result = [];
          for (let i = this.copyMinDate.year; i <= this.copyMaxDate.year; i += 1) {
            result.push(i);
          }
          return result;
        },
        title() {
          // calendar 上面的所有 title 信息包括二部分
          return {
            year: "",
            monthday: ""
          };
        },
        rows() {
          const { year, month } = this.showDate;
          const months = new Date(year, month, 0).getDate();
          const result = [];
          let row = [];
          let weekValue;
          // 按照星期分组
          for (let i = 1; i <= months; i += 1) {
            // 根据日期获取星期,并让开头是1,而非0
            weekValue = new Date(year, month, i).getDay() + 1;
            // 判断月第一天在星期几,并填充前面的空白区域
            if (i === 1 && weekValue !== 1) {
              this.addRowEmptyValue(row, weekValue);
              this.addRowDayValue(row, i);
            } else {
              this.addRowDayValue(row, i);
              // 判断月最后一天在星期几,并填充后面的空白区域
              if (i === months && weekValue !== 7) {
                this.addRowEmptyValue(row, 7 - weekValue + 1);
              }
            }
            // 按照一周分组
            if (weekValue % 7 === 0 || i === months) {
              result.push(row);
              row = [];
            }
          }
          this.showDate.monthStr = monthJson[this.showDate.month + 1];
          console.log("rows", result);
          return result;
        }
      },
      data() {
        return {
          selectDate: {
            year: "",
            month: "",
            day: "",
            week: "",
            date: "",
            weekStr: "",
            monthStr: ""
          }, // 选择的时间,默认是用户传的date时间
          showDate: {
            year: "",
            month: "",
            day: "",
            week: "",
            date: "",
            monthStr: "",
            weekStr: ""
          },
          copyMinDate: {
            year: "",
            month: "",
            day: ""
          },
          copyMaxDate: {
            year: "",
            month: "",
            day: ""
          },
          toolbar: "",
          fadeXType: "fadeX_Prev",
          nextMonthClick: false,
          prevMonthClick: false,
          showYear: false
        };
      },
      created() {
        this.initDatePicker();
      },
      methods: {
        addMeeting() {
          alert(111);
        },
        initDatePicker() {
          this.showDate = { ...this.splitDate(this.date, true) };
          this.copyMinDate = { ...this.splitDate(this.minDate) };
          this.copyMaxDate = { ...this.splitDate(this.maxDate) };
          this.selectDate = { ...this.showDate };
        },
        splitDate(date, addStr) {
          let result = {};
          const splitValue = date.split("-");
          try {
            if (!splitValue || splitValue.length < 3) {
              throw new Error("时间格式不正确");
            }
            result = {
              year: Number(splitValue[0]),
              month: Number(splitValue[1]) - 1,
              day: Number(splitValue[2])
            };
            if (addStr) {
              result.week =
                new Date(result.year, result.month, result.day).getDay() + 1;
              result.monthStr = monthJson[result.month + 1];
              result.weekStr = weekJson[result.week];
            }
          } catch (error) {
            console.error(error);
          }
          return result;
        },
        addRowEmptyValue(row, count) {
          for (let w = 1; w < count; w += 1) {
            row.push({
              value: ""
            });
          }
        },
        addRowDayValue(row, i) {
          const value = { value: i };
          const { day, month, year } = this.selectDate;
          const showDate = this.showDate;
          // 判断已经选择的
          if (year === showDate.year && month === showDate.month && day === i) {
            value.selected = true;
          }
          // 当日期在最小值之外,禁止点击
          if (this.isMinLimitMonth() && i < this.copyMinDate.day) {
            value.disabled = true;
          }
          // 当日期在最大值之外,禁止点击
          if (this.isMaxLimitMonth() && i > this.copyMinDate.day) {
            value.disabled = true;
          }
          row.push(value);
        },
        /**
         * 切换到上一个月
         */
        prevMonth() {
          if (this.prevMonthClick) {
            return;
          }
          this.prevMonthClick = true;
          setTimeout(() => {
            this.prevMonthClick = false;
          }, 500);
          this.fadeXType = "fadeX_Prev";
          // 如何当前月份已经小于等于minMonth 就不让其在执行
          if (this.isMinLimitMonth()) {
            return;
          }
          const { year, month } = this.showDate;
          // 判断当前月份,如果已经等于1(1就是一月,而不是二月)
          if (month <= 0) {
            this.showDate.year = year - 1;
            this.showDate.month = 11;
          } else {
            this.showDate.month -= 1;
          }
        },
        /**
         * 切换到下一个月
         */
        nextMonth() {
          if (this.nextMonthClick) {
            return;
          }
          this.nextMonthClick = true;
          setTimeout(() => {
            this.nextMonthClick = false;
          }, 500);
          this.fadeXType = "fadeX_Next";
          // 如何当前月份已经大于等于maxMonth 就不让其在执行
          if (this.isMaxLimitMonth()) {
            return;
          }
          const { year, month } = this.showDate;
          // 判断当前月份,如果已经等于12(12就是十二月)
          if (month >= 11) {
            this.showDate.year = year + 1;
            this.showDate.month = 0;
          } else {
            this.showDate.month += 1;
          }
        },
        resetSelectDate(dayValue) {
          this.selectDate = { ...this.showDate };
          this.selectDate.day = dayValue;
          this.selectDate.week =
            new Date(this.showDate.year, this.showDate.month, dayValue).getDay() +
            1;
          this.selectDate.weekStr = weekJson[this.selectDate.week];
        },
        selectDay(day) {
          if (day.disabled || day.selected || day.value === "") {
            return;
          }
          this.resetSelectDate(day.value);
        },
        selectYear(value) {
          this.showYear = false;
          this.showDate.year = value;
          let type;
          // 当日期在最小值之外,月份换成最小值月份 或者 当日期在最大值之外,月份换成最大值月份
          if (this.isMinLimitMonth()) {
            type = "copyMinDate";
          } else if (this.isMaxLimitMonth()) {
            // 当日期在最大值之外,月份换成最大值月份
            type = "copyMaxDate";
          }
          if (type) {
            this.showDate.month = this[type].month;
            this.showDate.day = this[type].day;
            this.resetSelectDate(this.showDate.day);
            return;
          }
          let dayValue = this.selectDate.day;
          // 判断日是最大值,防止另一个月没有这个日期
          if (this.selectDate.day > 28) {
            const months = new Date(
              this.showDate.year,
              this.showDate.month,
              0
            ).getDate();
            // 当前月份没有这么多天,就把当前月份最大值赋值给day
            dayValue = months < dayValue ? months : dayValue;
          }
          this.resetSelectDate(dayValue);
        },
        isMinLimitMonth() {
          return (
            this.showDate.year <= this.copyMinDate.year &&
            this.showDate.month <= this.copyMinDate.month
          );
        },
        isMaxLimitMonth() {
          return (
            this.showDate.year >= this.copyMaxDate.year &&
            this.showDate.month >= this.copyMaxDate.month
          );
        },
        openYearList() {
          if (this.showYear) {
            this.showYear = false;
            return;
          }
          const index = this.yearList.indexOf(this.selectDate.year);
          this.showYear = true;
          setTimeout(() => {
            this.$refs.yearList.scrollTop = (index - 3) * 40;
          });
        },
        openCalendarList() {
          this.showYear = false;
        },
        // 保持两位数
        keepDoubleDigit(number) {
          return number > 9 ? number : `0${number}`;
        },
        confirm() {
          const { year, month, day, week, weekStr, monthStr } = this.selectDate;
          this.$emit("confirm", {
            date: `${year}-${this.keepDoubleDigit(month)}-${this.keepDoubleDigit(
              day
            )}`,
            year,
            month,
            week,
            monthStr,
            weekStr,
            day
          });
        },
        cancel() {
          this.$emit("cancel");
        }
      }
    };
    </script>
    
    <style lang="scss">
    @import "@/assets/css/basic.scss";
    @import "@/assets/css/borderBox.scss";
    .e- {
      &calendar-wrapper {
        position: fixed;
        left: 0;
        top: 0;
        bottom: 0;
        right: 0;
        // background-color: rgba(0, 0, 0, 0.5);
        background: #333333;
        border: 1px solid #a5a5a5;
        box-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.5);
        border-radius: 5px;
        z-index: 99999;
        display: flex;
        justify-content: center;
        align-items: center;
        flex-direction: row;
      }
      &calendar {
        //background-color: #a5a5a5;
         310px;
        color: #e6e6e6;
        opacity: 0.8;
      }
      &date-select {
        //background-color: #00bcd4;
        padding: 3px 3px;
        color: #ffffff;
      }
      &date-year {
        font-size: 18px;
        padding-bottom: 4px;
        position: relative;
         66px;
        height: 25px;
        overflow: hidden;
        &-select {
          position: absolute;
          opacity: 0.7;
          &.active {
            opacity: 1;
          }
        }
      }
      &date-monthday {
        font-size: 26px;
        position: relative;
         100%;
        height: 36px;
        overflow: hidden;
        &-select {
          position: absolute;
          opacity: 0.7;
          &.active {
            opacity: 1;
          }
        }
      }
      &calendar-container {
         auto;
      }
      &calendar-toolbar {
        margin: 5px 10px 5px 10px;
        height: 40px;
        display: flex;
        justify-content: space-between;
        align-items: center;
        &-title {
          position: relative;
           100px;
          height: 22px;
          text-align: center;
          &-content {
            position: absolute;
             100%;
            font-size: 16px;
          }
        }
      }
      &calendar-svg {
        padding: 8px;
        position: relative;
        height: 40px;
         40px;
        &-icon {
          display: block;
          fill: currentColor;
          height: 24px;
           24px;
          user-select: none;
          position: relative;
          z-index: 2;
        }
        &-cover {
          position: absolute;
          left: 0;
          top: 0;
          z-index: 1;
           100%;
          height: 100%;
          background-color: #e0e0e0;
          border-radius: 50%;
          opacity: 0;
          display: inline-block;
        }
      }
      &calendar-week {
         100%;
        font-size: 12px;
        //color: rgba(0, 0, 0, 0.87);
        color: #ffffff;
        opacity: 0.7;
        display: flex;
        justify-content: center;
        align-items: center;
        height: 16px;
        &-day {
          flex: 1;
          text-align: center;
        }
      }
      &calendar-monthday {
        padding-top: 10px;
        font-size: 14px;
        position: relative;
         100%;
        min-height: 210px;
        overflow: hidden;
        &-wrapper {
          position: absolute;
           100%;
          height: 100%;
        }
        &-row {
          display: flex;
          justify-content: center;
          align-items: center;
          &-day {
            display: flex;
            justify-content: center;
            align-items: center;
            flex: 1;
            position: relative;
            height: 35px;
            &.pointer {
              cursor: pointer;
            }
            &-value {
              position: relative;
              z-index: 1;
            }
            &-cover {
               25px;
              height: 25px;
              background-color: #00bcd4;
              position: absolute;
              left: 10px;
              top: 5px;
              transform: translate3d(0, 0, 0);
              z-index: 0;
              border-radius: 50%;
              opacity: 1;
              display: block;
            }
            &.active {
              color: #ffffff;
            }
            &.disabled {
              opacity: 0.4;
              cursor: not-allowed;
            }
          }
        }
      }
      &calendar-year {
        height: 276px;
        overflow: auto;
        li {
          padding: 10px;
          text-align: center;
          font-size: 16px;
          &.active {
            color: #00bcd4;
            font-size: 20px;
            font-weight: bold;
          }
        }
      }
      &calendar-actions {
        padding: 0 20px 15px;
        display: flex;
        justify-content: flex-end;
        align-items: center;
        .btn {
          color: #00bcd4;
          margin-left: 40px;
          font-size: 16px;
          background-color: transparent;
        }
      }
    }
    .fadeX_Prev-enter-active,
    .fadeX_Prev-leave-active,
    .fadeX_Next-enter-active,
    .fadeX_Next-leave-active,
    .fadeY-enter-active,
    .fadeY-leave-active {
      transition: all 0.3s;
    }
    .fadeX_Prev-enter {
      transform: translateX(-100px);
      opacity: 0;
    }
    .fadeX_Prev-leave-active {
      transform: translateX(100px);
      opacity: 0;
    }
    .fadeX_Next-enter {
      transform: translateX(100px);
      opacity: 0;
    }
    .fadeX_Next-leave-active {
      transform: translateX(-100px);
      opacity: 0;
    }
    .fadeY-enter {
      transform: translateY(30px);
      opacity: 0;
    }
    .fadeY-leave-active {
      transform: translateY(-30px);
      opacity: 0;
    }
    .e_calendar_svg_btn-enter-active,
    .e_calendar_svg_btn-leave-active {
      transition: all 1s;
    }
    .e_calendar_svg_btn-enter {
      opacity: 1;
    }
    .e_calendar_day-enter-active {
      transition: all 0.2s;
    }
    .e_calendar_svg_btn-leave-active,
    .e_calendar_day-enter {
      opacity: 0;
    }
    .e_calendar_day-enter {
       0;
      height: 0;
      transform: translate3d(12px, 12px, 0);
    }
    </style>
    

     

    basic.scss
    @import "./color";
    
    //reset element style
    html {
    -ms-overflow-style:none;
    overflow:-moz-scrollbars-none;
    }
    html::-webkit-scrollbar{0}
    body,div,span,header,footer,nav,section,aside,article,ul, li, a, p, textarea, button, input, select  {
      padding: 0;
      margin: 0;
      list-style: none;
      font-weight: normal;
      font-style: normal;
      text-decoration: none;
      border: none;
      font-family: 'Hiragino Sans GB', 'Hiragino Sans GB W3', 'Microsoft YaHei', 'WenQuanYi Micro Hei', sans-serif;
      -webkit-tap-highlight-color:transparent;
      &:focus {
        outline: none;
      }
    }
    html{
      -webkit-overflow-scrolling : touch !important;
      overflow: auto !important;
      height: 100% !important;
    }
    body{
      -webkit-overflow-scrolling : touch !important;
      overflow: auto !important;
      position: relative;
      height:100% !important;
      100%;
      background:$c-little-gray;
      font-size: 12px;
    }
    .clearfix {
      zoom: 1;
      &::after {
        visibility: hidden;
        display: block;
        font-size: 0;
        content: " ";
        clear: both;
        height: 0;
      }
    }
    .vertical-middle {
      height: 100%;
       0;
      display: inline-block;
      vertical-align: middle;
    }
    
    .pull-left{
      float:left;
    }
    .pull-right{
      float:right;
    }
    .mt6{
      margin-top: 6px;
    }
    .ml60{
      margin-left: 60px;
    }
    
    .pointer{
      cursor: pointer;
    }
    [v-cloak] {
      display: none;
    }
    .slide-fade-enter-active {
        transition: all .6s ease;
    }
    
    .slide-fade-leave-active {
        transition: all .5s ease;
    }
    
    .slide-fade-enter,
    .slide-fade-leave-active {
        transform: translateX(60px);
        opacity: 0;
    }

    color.vue

    $c-block : #000;
    $c-natural-block : #3B3F44;
    $c-gray : #979797;
    $c-small-gray: rgb(151, 151, 151);
    $c-some-gray: rgb(190,190,190);
    $c-light-gray : #BEBEBE;//提示文字
    $c-text-main : #3B3D5B;//提示文字
    $c-half-main : lighten($c-text-main, 50%);//提示文字
    $c-smoky-gray : #DAD7D9;
    $c-lightslate-gray: #E0E0E0; //边框颜色
    $c-half-lightslate-gray: #F0F0F0; //边框颜色
    $c-little-gray: #f9f9f9; //背景
    
    $c-ivory : #f7f7f7;
    $c-light-white: #EEEEEE;
    $c-white : #FFF;
    
    $c-red : #E34F51;
    $c-natural-red : #E44F51;
    $c-light-red : #EF7979 ;
    
    $c-pink : #ffa1a1;
    
    $c-orange : #f34e19;
    
    $c-blue : #1975C3;
    
    $c-green : #25C354;
    
    $c-yellow : #F6A623;
    
    $c-primary : #00bcd4;
    $c-success : #6AC8D4;
    $c-light-blue : #6EB8F1;
    
    $c-purple-grey : #212340;// 导航栏背景
    
    $b-lightslate-gray : 1px solid $c-lightslate-gray;
    $b-half-lightslate-gray : 1px solid $c-half-lightslate-gray;
    $b-main: 1px solid $c-text-main;
    $b-half-main: 1px solid lighten($c-text-main, 50%);
    $b-bolder-active-main: 3px solid $c-text-main;
    $b-mask: rgba(59,61,91,0.60);
    $b-transparent-block: rgba(0,0,0,0);
    
    // app colors
    $c-start: #6bf3d4; // 渐变起始色
    $c-end: #6eb8f1; // 渐变终止色
    $c-light-blue : #6EB8F1;
    
    $c-number: #D67573; //用于数字提示
    $c-red: #E44F51; //用于数字提示
    $c-bg-tip: #E44F51; //用于数字提示
    
    $c-bg: #f9f9f9; //背景;
    $c-bg-white: #ffffff; //白色背景;
    $c-gray : #979797;//灰色字体
    $c-light-gray : #bebebe;//提示文字
    $c-lightslate-gray: #E0E0E0; //边框颜色
    
    $c-divider:#e6e6e6; //用于分割线
    
    $c-tabBar: #667980; // 用于默认Tab bar Icon
    $c-introdution: #667980; // 用于默认Tab bar Icon
    
    $c-btnText: #6eb8f1; //适用于高亮按钮文字
    
    $c-title: #4d4d4d; // 适用于标题
    $c-text: #4d4d4d; // 适用于正文
    
    $c-title-white: #ffffff; // 适用于标题
    $c-text-white: #ffffff; // 适用于正文
    $c-text-main : #3B3D5B;//提示文字
    $c-text-gold: #FFE98D;// 金字
    $c-border-main : #3B3D5B;//提示文字
    
    $c-assistTxt: #808080; //适用于辅助文字
    $c-subtitle: #808080; //适用于副标题
    
    $c-tipText: #b3b3b3; //适用于提示性文字
    $c-timeText: #b3b3b3; //适用于时间文字
    
    $c-border:#e6e6e6; //适用于边框
    $c-light-border:#f0f0f0; //浅颜色边框
    $c-bg-authenticate:#F5A623;// 认证边框色
    
    $c-status: #6AC8D4; //选中的状态
    $c-border-common:#e0e0e0;
    $c-border-half-common: rgba(224,224,224,0.5);
    
    $b-border-half-common: 1px solid $c-border-common;
    $b-border-common: 1px solid $c-border-half-common;
    

      borderBox.scss

    body,div,span,header,footer,nav,section,aside,article,ul, li, a, p, h1, h2, h3, h4,h5, i, b, textarea, button, input, select  {
      box-sizing: border-box;
    }
    

      使用

     <date-picker
            v-if="showDatePicker"
            :date="date"
            :min-date="minDate"
            :max-date="maxDate"
            @confirm="confirm"
            @cancel="cancel"
          ></date-picker>
    
    <script>
    import DatePicker from "@/components/DatePicker.vue";
    export default {
      components: {
        DatePicker
      },
      data() {
        return {
          showDatePicker: false,
          date: "2019-01-28",
          minDate: "2000-09-11",
          maxDate: "2020-09-11",
          selectedDate: "点击选择日期"
        };
      },
      computed: {},
      methods: {
        confirm(value) {
          this.showDatePicker = false;
          this.selectedDate = value;
        },
        cancel() {
          this.showDatePicker = false;
        }
      }
    };
    </script>
    

      

  • 相关阅读:
    如何让一个浮动垂直居中:两种方式!带来效果~~~~~~
    rgba()和opacity之间的区别(面试题)
    常用浏览器内核!IE,Chrome ,Firefox,Safari,Opera 等内核
    有关Option.inSamplSize 和 Compress 图片压缩
    Android App 启动 Activity 创建解析
     (转)windows一台电脑添加多个git账号
    Handler向子线程发送数据
    Android Touch事件分发
    int 转十六进制
    JVM client模式和Server模式
  • 原文地址:https://www.cnblogs.com/xuqp/p/10329767.html
Copyright © 2020-2023  润新知