zoukankan      html  css  js  c++  java
  • vue 模仿机票自定义日历组件,区间选择

    1.创建组件  components > calander > index.vue

    <template>
      <div class="page" v-if="show">  
        <div class="box">  
          <div class="box_head" v-if="!propshow">
            <div class="font28" @click="calanderShowData">取消</div>
            <div class="font28" @click="calanderSubmit">确定</div>        
          </div>
    
          <div class="box-flex">  
            <div class="flex-item item-content-current-day  item-content-tit">  
              <div class="item-content titleHead">{{currentDate}}</div>  
            </div>  
            </div>  
          </div>  
          <div class="box-flex">  
            <div class="flex-item">  
              <div class="item-content"></div>  
            </div>  
            <div class="flex-item">  
              <div class="item-content"></div>  
            </div>  
            <div class="flex-item">    
              <div class="item-content"></div>  
            </div>  
            <div class="flex-item">  
              <div class="item-content"></div>  
            </div>  
            <div class="flex-item">  
              <div class="item-content"></div>  
            </div>  
            <div class="flex-item">  
              <div class="item-content"></div>  
            </div>  
            <div class="flex-item">  
              <div class="item-content"></div>  
            </div>  
          </div>  
          <div class="box-flex">  
            <div class="flex-item flexData" v-for='(item, index) in currentDayList' :key='item' @click='itemFun(item.num,mouth[index],index, "first", item.state)' :class="{'hover-date': Section[index] && item.num, 'noBack': !item.state && item.num && !propshow}">  
                <div class="item-content red-background" v-if='currentDay === item.num && mouth[index].mouth === currentMouth.mouth && currentMouth.year === mouth[index].year' :class="{'hoverColorData' : Section[index] && item.num, 'hover-date':active[index]}">
                  <p>今天</p>
                  <p v-if="item.number && propshow">{{item.number}}展位</p>              
                </div>  
                <div class="item-content backgroundData" v-else :class="{'hover-date':active[index]}" >
                  <p>{{item.num}}</p>
                  <p v-if="item.number && propshow">{{item.number}}展位</p>
                </div>  
            </div>  
          </div>  
              <div class="box">  
          <div class="box-flex">  
            <div class="flex-item item-content-current-day  item-content-tit">  
              <div class="item-content titleHead">{{currentDateTwo}}</div>  
            </div>  
    
            </div>  
          </div>  
          <div class="box-flex">  
            <div class="flex-item">  
              <div class="item-content"></div>  
            </div>  
            <div class="flex-item">  
              <div class="item-content"></div>  
            </div>  
            <div class="flex-item">    
              <div class="item-content"></div>  
            </div>  
            <div class="flex-item">  
              <div class="item-content"></div>  
            </div>  
            <div class="flex-item">  
              <div class="item-content"></div>  
            </div>  
            <div class="flex-item">  
              <div class="item-content"></div>  
            </div>  
            <div class="flex-item">  
              <div class="item-content"></div>  
            </div>  
          </div>  
          <div class="box-flex">  
            <div class="flex-item flexData" v-for='(item, index) in currentDayListData' :key='item' @click='itemFun(item.num,mouths[index],index, "last", item.state)' :class="{'hover-date': Sections[index] && item.num, 'noBack': !item.state && item.num && !propshow}">  
                <div class="item-content backgroundData" :class="{'hover-date':actives[index]}">
                  <p>{{item.num}}</p>
                  <p v-if="item.number && propshow">{{item.number}}展位</p>
                </div>  
            </div>  
          </div> 
    
      <div v-if="propshow" class="propshowData"></div>
    </div>  
    </template>  
    
    <script>
    import vue from 'vue'
    export default {
      name: 'calander',
      data () {
        return {
          calanderList: [],
          show: false,
          currentDate: '2017年05月03日',
          currentDateTwo: '2017年06月03日',
          dayList: '',
          currentDayList: [],
          currentObj: '',
          currentDay: '',
          mouth: [],
          currentMouth: null,
          hoverDate: {'date': null, 'mouth': null, 'year': null},
          activeClick: 0,
          active: [],
          actives: [],
          Section: [],
          firstIndex: 0,
          lastIndex: 0,
          currentDayListData: [],
          currentJudge: false,
          currentObjNew: '',
          Sections: [],
          lastType: '',
          fristType: '',
          numArray: [],
          numArrayTwo: []
        }
      },
      props: {
        propshow: false,
        boothArray: [], // 从父级传来的数组,中主要携带number展位数,
        calanderList: [],
        yearAndmouthFirst: {},
        yearAndmouthTwo: {},
        calanderShow: false
      },
      mounted () {
        let timeData = this.getNextMonth(new Date(),1)
        var currentObj = this.getCurrentDayString()
        this.currentDate = currentObj.getFullYear() + '' + (currentObj.getMonth() + 1) + '' + currentObj.getDate() + ''
        this.currentDateTwo = timeData.getFullYear() + '' + (timeData.getMonth() + 1) + '' + timeData.getDate() + ''
        
        // this.currentObjNew = currentObj.getFullYear() + '/' + (currentObj.getMonth() + 2) + '/' + currentObj.getDate()
        this.currentDay = currentObj.getDate()
        
        this.currentObj = currentObj
        this.currentMouth = {
          mouth: currentObj.getMonth() + 1,
          year: currentObj.getFullYear()
        }
    
        setTimeout(() => {
          this.setSchedule(currentObj, 'newMonth') 
          this.setSchedule(this.getNextMonth(new Date(),1), 'nextMonth')            
          // this.setSchedule(new Date(this.currentObjNew), 'nextMonth') 
        },100);
      },
      methods: {    
        monthDay: function (year, month) {
            month = parseInt(month, 10);
            var d = new Date(year, month, 0);  //这个是都可以兼容的
            var date = new Date(year + "/" + month + "/0")   //IE浏览器可以获取天数,谷歌浏览器会返回NaN
            return d.getDate();
        },
        getNextMonth: function (date,length) {
          let yy = date.getFullYear()
          let mm = date.getMonth()
          let dd = date.getDate()
          
          let nm= 0//目标月份
          nm = mm+length
          let nd = 0//目标天数
          if(this.monthDay(yy,nm+1)<dd){
            nd = this.monthDay(yy,nm+1)
          }else{
            nd = dd-1
          }
    
          date.setDate(1)
          date.setMonth(nm)
          date.setDate(nd)
          return date
        },
        calanderSubmit(){
          console.log(this.numArray)
          this.$emit('assignment', this.numArray)
        },
        calanderShowData(){
          this.$emit('calanderShowClick', this.calanderShow)
        },
        formatTwo (n) {
          if (n >= 10) return n
          else return '0' + n
        },
        // 判断日历的当前日期是否不可点击
        isDisabled (calander, index, item) {
          // if (new Date(calander).getTime() < new Date().getTime()) {
          //   this.mouth[index].state = 'disabled'
          //   return false
          // }
        },
        getWeekDayNextMonth(){
          var myDate = new Date()
          myDate.setMonth(myDate.getMonth() + 1);
          myDate.setDate(1);
          var weekDay=new Array(7, 1, 2, 3, 4, 5, 6)
          return weekDay[myDate.getDay()];
        },
        itemFun (item, yearAndmouth, index, type, stateClick) {  
          if (stateClick) {
            let dataD = new Date();
            let curMonthDays = new Date(dataD.getFullYear(), (dataD.getMonth()+1), 0).getDate()
            this.hoverDate = {'date': item, 'mouth': yearAndmouth.mouth, 'year': yearAndmouth.year}
    
            if (type == 'first') {
              var activeArrayData = this.active
              var SectionArrayData = this.Section
            } else {
              var activeArrayData = this.actives
              var SectionArrayData = this.Sections              
            }
    
            if (this.activeClick == 0) {
              this.yearAndmouthFirst = yearAndmouth
              this.yearAndmouthFirst.date = item
              for(let i=0; i<this.active.length; i++){
                this.active[i] = false
                vue.set(this.active, i, this.active[i])                    
              }
              for(let i=0; i<this.actives.length; i++){
                this.actives[i] = false
                vue.set(this.actives, i, this.actives[i])                    
              }
              for(let t=0; t<this.Section.length; t++){
                this.Section[t] = false
                vue.set(this.Section, t, this.Section[t])
              }
              for(let t=0; t<this.Sections.length; t++){
                this.Sections[t] = false
                vue.set(this.Sections, t, this.Sections[t])
              }
              this.numArray = []
              this.activeClick = 1
              this.fristType = type
              this.firstIndex = item
              this.yearFirst = yearAndmouth.year
              this.mouthFirst = yearAndmouth.mouth
              
              activeArrayData[index] = true
              vue.set(activeArrayData, index, activeArrayData[index])
              this.numArray.push(this.yearAndmouthFirst)
              console.log(this.numArray)
            } else if (this.activeClick == 1){  
              this.numArray = []
              this.yearAndmouthTwo = yearAndmouth
              this.yearAndmouthTwo.date = item
              if (this.firstIndex != index) {
                this.activeClick = 0
                this.lastIndex = item
                this.lastType = type
                this.yeaTwo = yearAndmouth.year
                this.mouthTwo = yearAndmouth.mouth
    
                activeArrayData[index] = true
                vue.set(activeArrayData, index, activeArrayData[index])
                if (this.fristType == this.lastType) {
                  if (this.lastIndex > this.firstIndex) {
                    var indexCenter = this.lastIndex - this.firstIndex + 1          
                  } else {
                    var indexCenter = this.firstIndex - this.lastIndex + 1                            
                  }
                  for(let j=0; j<indexCenter; j++){
                    if (this.lastIndex < this.firstIndex) {
                      var indexData = j + index
                      this.numArray.push({'date': item + j, 'mouth': yearAndmouth.mouth, 'year': yearAndmouth.year})
                    } else {
                      this.numArray.unshift({'date': item - j, 'mouth': yearAndmouth.mouth, 'year': yearAndmouth.year})                
                      var indexData = index - j
                    }
                    SectionArrayData[indexData] = true
                    vue.set(SectionArrayData, indexData, SectionArrayData[indexData])
                  }
                } else {
                  if (this.fristType == 'first') {
                    var indexCenter = curMonthDays - this.firstIndex + 1
                    var indexCenters = this.lastIndex
                  } else {
                    var indexCenter = curMonthDays - this.lastIndex + 1
                    var indexCenters = this.firstIndex       
                  }
                  
                  for(let j=0; j<indexCenter; j++){
                    if (this.fristType == 'first') {
                      var indexData = this.firstIndex + j
                      this.numArray.push({'date': indexData, 'mouth': this.mouthFirst, 'year': this.yearFirst})                
                    } else {
                      var indexData = this.lastIndex + j
                      this.numArray.push({'date': item + j, 'mouth': this.mouthTwo, 'year': this.yeaTwo})                
                    }
                    this.Section[indexData + 1] = true
                    vue.set(this.Section, indexData, this.Section[indexData]) 
                  } 
                
                  var monthData = this.getWeekDayNextMonth()
                  for(let j=0; j<indexCenters; j++){
                    if (this.fristType == 'first') {
                      var indexDatas = j + monthData - 1
                      this.numArrayTwo.unshift({'date': item - j, 'mouth': this.mouthTwo, 'year': this.yeaTwo})                
                    } else {
                      var indexDatas = this.firstIndex - j + monthData -2
                      this.numArrayTwo.unshift({'date': this.firstIndex - j , 'mouth': this.mouthFirst, 'year': this.yearFirst})                
                    }
                    this.Sections[indexDatas] = true
                    vue.set(this.Sections, indexDatas, this.Sections[indexDatas])
                  }
                }
                this.numArray = this.numArray.concat(this.numArrayTwo)
              } 
            }
          }
        },
        doDay: function (e) {
          var that = this
          var currentObj = that.currentObj
          var Y = currentObj.getFullYear()
          var m = currentObj.getMonth() + 1
          let newData = new Date 
          let newMonth=newData.getMonth()+1;
          let d = currentObj.getDate()
          var str = ''
          if (e.currentTarget.dataset.key === 'left') {
            m -= 1
            if (m <= 0) {
              str = (Y - 1) + '/' + 12 + '/' + d
            } else {
              str = Y + '/' + m + '/' + d
            }
            this.currentJudge = true
          } else if(e.currentTarget.dataset.key === 'right') {
            if (newMonth !== m) {
              m += 1
              if (m <= 12) {
                str = Y + '/' + m + '/' + d
              } else {
                str = (Y + 1) + '/' + 1 + '/' + d
              }
              this.currentJudge = true
            } else {
              this.currentJudge = false          
            }
          } else if (e.currentTarget.dataset.key === 'leftTwo'){   
            if (newMonth !== m) {
              m -= 1
              if (m <= 0) {
                str = (Y - 1) + '/' + 12 + '/' + d
              } else {
                str = Y + '/' + m + '/' + d
              }
              this.currentJudge = true
            } else {
              this.currentJudge = false
            }
          } else if (e.currentTarget.dataset.key === 'rightTwo'){
            m += 1
            if (m <= 12) {
              str = Y + '/' + m + '/' + d
            } else {
              str = (Y + 1) + '/' + 1 + '/' + d
            }
            this.currentJudge = true
          }
          if (this.currentJudge) {
            currentObj = new Date(str)
            this.currentDate = currentObj.getFullYear() + '' + (currentObj.getMonth() + 1) + '' + currentObj.getDate() + ''
            this.currentDateTwo = currentObj.getFullYear() + '' + (currentObj.getMonth() + 2) + '' + currentObj.getDate() + ''        
            this.currentObjNew = currentObj.getFullYear() + '/' + (currentObj.getMonth() + 2) + '/' + currentObj.getDate() + '/'        
            
            this.currentObj = currentObj
            if (e.currentTarget.dataset.key == 'left' || e.currentTarget.dataset.key == 'right') {
              this.setSchedule(currentObj, 'newMonth')
            } else {
              this.setSchedule(new Date(this.currentObjNew), 'nextMonth')
            }
          }
        },
        getCurrentDayString: function () {
          var objDate = this.currentObj
          if (objDate !== '') {
            return objDate
          } else {
            var cobj = new Date()
            var a = cobj.getFullYear() + '/' + (cobj.getMonth() + 1) + '/' + cobj.getDate()
            return new Date(a)
          }
        },
        setSchedule: function (currentObj, type) {
          var that = this
          var m = currentObj.getMonth() + 1
          var Y = currentObj.getFullYear()
          var d = currentObj.getDate()
          var newDate = new Date()
          var newYear = newDate.getFullYear()
          var newMonth = newDate.getMonth() + 1
          
          // var dayString = Y + '/' + m + '/' + currentObj.getDate()
          var currentDayNum = new Date(Y, m, 0).getDate()
          var currentDayWeek = currentObj.getUTCDay() + 1
          
          var result = currentDayWeek - (d % 7 - 1)
          
          var firstKey = result <= 0 ? 7 + result : result
          
          var currentDayListNew = []
    
          var mouth = []
          var f = 0
          for (var i = 0; i < 42; i++) {
            mouth[i] = {
              'mouth': m,
              'year': Y
            }
            currentDayListNew[i] = {
              'num': '',
              'number': '',
              'state': false
            }
            if (i < firstKey - 1) {
              currentDayListNew[i].num = ''
            } else {
              if (f < currentDayNum) {
                currentDayListNew[i].num = f + 1
                f = currentDayListNew[i].num
                if (newYear == Y && newMonth == m) {
                  if (f >= d) {
                    currentDayListNew[i].state = true
                  }
                } else {
                  if (f <= d) {
                    currentDayListNew[i].state = true
                  }
                }
              } else if (f >= currentDayNum) {
                currentDayListNew[i].num = ''
              }
              if (this.boothArray.length > 0) {
                this.boothArray.forEach((element, indexArray) => {
                  if (element.year == Y && element.mouth == m) {
                    if (element.date == currentDayListNew[i].num) {
                      currentDayListNew[i].number = String(element.number)
                    }
                  }
                })
              }
              if (this.calanderList.length > 0) {
                this.calanderList.forEach((element, indexList) => {
                  if (element.year == Y && element.mouth == m) {
                    if (element.date == currentDayListNew[i].num) {
                      if (type == 'newMonth') {
                        this.Section[i] = true
                      } else {
                        this.Sections[i] = true
                      }                  
                    }
                  }
                });
              }          
            }
          }
    
          if (type == 'newMonth') {
            that.currentDayList = currentDayListNew
            that.mouth = mouth
          } else {
            that.currentDayListData = currentDayListNew     
            that.mouths = mouth                   
          }
          this.show = true                
        }
      }
    }
    </script>
    
    <style scoped>
    .box_head{
      height: 1.173333rem /* 88/75 */;
      background: #fff;
      display: flex;
      justify-content: space-between;
      align-items: center;
      padding: 0 .4rem /* 30/75 */;
      border-bottom: .013333rem /* 1/75 */ solid #E5E5E5;
    }
    .noBack{
      background: #bbb!important;
      /* border-radius: 5px!important; */
    }
    .hoverColorData{
      color: #fff!important;
    }
    .propshowData{
      position: absolute;
      left: 0;
      right: 0;
      bottom: 0;
      top: 0;
      background: rgba(0, 0, 0, 0.1);
      z-index: 9999;
    }
    .page{
      background: #fff;
      position: relative;
    }
    .titleHead{
      margin: .266667rem /* 20/75 */ 0!important;
    }
    .sectionBack{
      background: #8A2BE2;
    }
    page {  
      background-color: #2a8cef;  
      background:-webkit-gradient(linear, 0 0, 0 bottom, from(#2a8cef), to(#8A2BE2));  
      display: flex;  
      flex-direction: column;  
      width: 100%;  
      flex-wrap: nowrap;  
      justify-content: flex-start;  
      align-items: stretch;  
      font-size: 16px;  
      color: #222;
    } 
    .disabled{
      color: #ccc !important;
    } 
    .hover-date{
      background: #367EED;
      color: #fff !important;
      border-radius: 5px;
    }  
    .box {  
      display: block;  
      /* margin: 10px;   */
      border-top: .013333rem /* 1/75 */ solid #efefef;  
    } 
    .glyphicon-triangle-left img{
      transform:rotate(180deg)
    } 
      .glyphicon img{
        width:12px;
        height: 19px;
        margin-top:15px;
      }
    .box-flex {  
      display: -webkit-box;  
      display: -webkit-flex;  
      display: flex;  
      flex-wrap: wrap;  
      padding: 0 .133333rem /* 10/75 */;
    }  
      
    .flex-item {  
      flex-flow: nowrap;  
      flex-grow: 1;  
      flex-shrink: 1;  
      width: 14%;  
      margin: 1px 1px 1px 0px;
    }  
      
    .item-content {  
      margin: 1px;  
      padding: 5px 1px;  
      text-align: center;  
      /* height: 45px;   */
      /* line-height: 45px;   */
      font-size:14px;
      position: relative;
          flex-wrap: wrap;
        justify-content: center;
    }  
    .item-content i{
      width:100%;
      text-align: center;
      left:0;
      position: absolute;
      top:8px;
    }
    .item-content span{
      width:100%;
      text-align: center;
      left:0;
      position: absolute;
      top:3px;
      font-size:12px;
      color: #367EED;
      line-height: 1;
    }
    .item-content-tit{
      width:30%;
      /* margin: .133333rem 10/75 0; */
    }
    .item-content-tit .item-content{
        font-size:17px;
    }
      .red-background{
        color:#367EED;
        border-radius: 5px;
      }
      
      
    .item-content-current-day {  
      flex-grow: 2;  
    }  
    </style>

    2.页面中引用组件

    <calander @assignment="assignment" :propshow="propshow" :boothArray="boothArray" :calanderList="calanderList"></calander> 
    
    
    <script>
        import calander from '@/components/calander'
        export default {
           components: {
             calander
           },
       data() {
          return {
            calanderList: [],
            boothArray: [],
            propshow: false,
          };
        },
        methods: {
          assignment(){
            // 组件调取父级方法
          },
        }
        }
    </script>
  • 相关阅读:
    定制博客园CSS
    后记:Cookie安全大辩论总结
    硬造的轮子趟过的坑--浮点型转字符串函数
    支付宝Cookie高危漏洞引发的思考
    博客园人氣提升密籍
    写个PHP框架吧
    开发一个程序员专用的搜索引擎
    三种常见网站工程师招聘条件总结
    golang之vscode环境配置
    golang环境安装
  • 原文地址:https://www.cnblogs.com/gqx-html/p/9962148.html
Copyright © 2011-2022 走看看