vue 里面日历能够自定义价格。

cell-month 组件

<template>
	<div class="cell-month">
		<div class="weeklist">
      <!--星期几-->
			<div class="week_box">
        <p v-for="(item,index) in weekData">
          {{item}}
        </p>
      </div>

      <!--slot插入时间-->
      <slot slot="select_month"></slot>

      <!--具体的时间-->
			<div class="monthDayList">
				<div
          v-for="(item,index) in daysData" class="dayList"
          @click="selectDate(item,index)"
          :class="{selectDay:isSelect == index,unData:item.day == ' '}">
				<p :class="item.price?'':'hui_color'">{{item.day}}</p>
				<span :class="item.price?'':'hidden'">{{item.price}}</span>
			   </div>
			</div>

		</div>
	</div>
</template>

<script>
	export default{

		props:{
			dateData: Array,
			day:String,
		},

		data(){

		return{
			weekData:['日','一','二','三','四','五','六'],
			currentDay: this.day,
			DaysInMonth:[],
			daysData:[],
			priceData:this.dateData,
      isSelect :-1,
      undate :1,
		 }
		},
		methods:{
			getYearMonthDay(){
			 let currentYear = this.$data.currentDay.substring(0,4); //当前年份
			 let currentMonth = this.$data.currentDay.substring(5,7); //当前月份
			//判断是否是闰年
			  if (this.isleapYears(currentYear)) {
			  	this.$data.DaysInMonth = [31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
			  }else{
			  	this.$data.DaysInMonth = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
			  }
             let monthDay = this.$data.DaysInMonth[Number(currentMonth)-1];//当前月的天数
             let daysData = [];
              //给数据源赋值
             for (var i = 0 ;i < Number(monthDay) ;i++) {
             	var priceDict = {'day':String(i+1),'price':0};
             	daysData.push(priceDict);
             }
             this.$data.daysData = daysData;
             var currentDay = `${currentYear}-${currentMonth}-01`;
              var dateObject = new Date(currentDay);
              var firstDay = dateObject.getDay();//得到每个月1号是周几
              for (var i  in this.$data.priceData) {
              	var price = this.$data.priceData[i];
              	var dayIndex = price.dateStr.substring(price.dateStr.length-2,price.dateStr.length);
              	var dayDict = daysData[Number(dayIndex)-1];
              	dayDict.price = price.price;
              }
             if (firstDay > 0) {
             	var firstDayData = [];
             	for (var i=0; i< firstDay;i++) {
             		var dict = {'day':' ',price:' '};
             		firstDayData.push(dict);
             	}
             	this.$data.daysData = firstDayData.concat(daysData);
             }else{
             	this.$data.daysData = daysData;
             }
			},
			isleapYears(year){
				if (((year % 4)==0) && ((year % 100)!=0) || ((year % 400)==0)) {
					return true;
				} else{
					return false;
				}
			},
			selectDate(item,index){

			  if(!item.price){
			    return
        }else{
          if (this.$data.daysData[index].day == 0) {
            return;
          }
          this.$data.isSelect = index;
          this.$store.commit('SetTicketPrice',item)
        }
				// this.back();
			},

		},

		created(){
			this.getYearMonthDay();
      // console.log(this.priceData)
		}

	}
</script>

<style scoped lang="less">
	.weeklist{
    .week_box{
      line-height: 42px;
      border:1px solid #eee;
      display: flex;
      p{
        float: left;
         14%;
        padding-left: 10px;
        padding-right: 10px;
        color: #999999;
        text-align: center;
        .font11;
        &:nth-child(1),&:last-child{
          color:#B49C63;
        }
      }
    }
		background-color: white;

	}

	.dayList{
		position: relative;
		float: left;
		 14%;
    display: flex;
    flex-direction: column;
    justify-content: center;
    align-items: center;
    height: 50px;
		p{
      float: initial;
       100%;
			text-align: center;
			padding: 0 0 0 0;
      font-size: 15px;
      color:#222222;
		}
    span{
      font-size: 11px;
      color:#FF5858;
      &.hidden{
        opacity: 0;
      }
    }

	}
	.monthDayList{
		background-color: #fff;
    overflow: hidden;
	}

	.selectDay{
		background-color: #B49C63;
		p{
			color: #fff;
		}
    span{
      color: #fff;
    }
	}

	.unData{
		p{
			color: white;
		}
	}
  .hui_color{
    color:#999999 !important;
  }



</style>

  页面引用

<div class="data_model">
            <div class="calender-content">
              <!--选择日期 取消按钮-->
              <div class="text_title">
                <b>选择日期</b>
                <span @click="show_date_model = false">取消</span>
              </div>

              <cell-month
                v-for = "(item,index) in classArray"
                :dateData= "item" :day = "item[0].dateStr"
                v-if = "index === selectMonth" :key = "index">
                <slot name="select_month">
                  <!--包含的日期-->
                  <div class="detail_time">
                    <div class="allMounth"
                         v-for="(item , index) in dateArray"
                         @click="selectMounth(index)">
                      <p :class="index === selectMonth?'active':''">
                        {{item.mounth.substring(5)}}月</p>
                      <!--<p>{{item.price}}起</p>-->
                    </div>
                  </div>
                </slot>
              </cell-month>

              <div class="sure_btn" @click="select_date">确定</div>

            </div>

          </div>

    script  如下
    import cellMonth from '@/components/cell-month'

    
    methods:{
    // 加载价格的接口。
          loadData(){
            //  数据里面的时间年都要完整。 例如1号,就要写 01
            let jsonArray = [
              {id: '4', dateStr: '2019-12-25', price: '¥2'},
              {id: '4', dateStr: '2019-12-26', price: '¥2'},
              {id: '4', dateStr: '2019-12-27', price: '¥2'},
              {id: '4', dateStr: '2019-12-28', price: '¥2'},
              {id: '4', dateStr: '2019-12-29', price: '¥2'},
              {id: '4', dateStr: '2019-12-30', price: '¥2'},
              {id: '4', dateStr: '2019-12-31', price: '¥2'},
              {id: '0', dateStr: '2020-01-01', price: '¥123'},
              {id: '0', dateStr: '2020-01-02', price: '¥123'},
              {id: '0', dateStr: '2020-01-03', price: '¥123'},
            ];
            let monthArray = [];
            for (var i in jsonArray) {
              var data = jsonArray[i];
              var dateDict = {'mounth':data.dateStr.substring(0,data.dateStr.length-3)};
              monthArray.push(dateDict);
            }
            //数组去重,获取有几个月
            var hash={};
            monthArray = monthArray.reduce(
              function (item,next) {
                hash[next.mounth]?'' :hash[next.mounth] = true && item.push(next);
                return item;
              },[]
            )
            console.log(monthArray);
            this.$data.dateArray = monthArray;
            //数据分组
            let classArray = [];
            for (var j in monthArray) {
              var newArray = new Array();
              for (var i in jsonArray) {
                var data = jsonArray[i];
                if (data.dateStr.substring(0,data.dateStr.length-3) == monthArray[j].mounth) {
                  newArray.push(data)
                }
              }
              classArray.push(newArray);
            }
            this.$data.classArray = classArray;
          },
          // 点击选择月份
          selectMounth(index){
            this.$data.selectMonth = index;
            console.log(index);
          },
          // 点击时间确认
          select_date() {
            this.show_date_model = false // 关闭弹窗
            var click_current_month = this.classArray[this.selectMonth][0].dateStr.substring(5,7)
            this.click_current_month = click_current_month
          },
},
created(){
          this.loadData();
        },

<style scoped lang="less">
.container{
padding-bottom:60px;
.ticket_item{
margin-bottom:5px;
100%;
.flex-justify-between();
background: @color_fff;
padding:20px 20px 10px 20px;
.ticket_item_left{
240px;
.name{
font-weight:500;
line-height: 30px;
.overflow2;
.font16;
i{
display: inline-block;
16px;
height: 16px;
background: url("../../../static/img/ic_jing.png") no-repeat;
background-size: cover;
margin-right:8px;
}
}
.tap{
margin:15px 0 11px;
.flex();
.flex-wrap();
span{
padding:0 7px;
line-height: 26px;
border:1px solid @color_border;
margin-right:8px;
color:@color_h4;
}
}
.need_know{
.flex-align-center();
line-height: 30px;
>span{
color:@color_h4;
}
>i{
4px;
height: 6px;
background: url("../../../static/img/ic_more.png");
background-size: cover;
margin-left:4px;
}
}
}
.ticket_item_right{
.flex-column();
.flex-justify-between();
.money{
b{
.font12;
color:@color_red;
font-weight: normal;
}
span{
.font18;
color:@color_red;
}
}
.btn{
background: @color_btn;
padding:8px;
border-radius: 3px;
color:#fff;
.font13;
margin-bottom:10px;
}
}
}
.need_conditions{
line-height: 32px;
background: @page_bg;
.padding20();
color:@color_red;
.font12;
}
.content_item{
border-bottom:1px solid @color_border;
.flex-justify-between();
.flex-align-center();
margin:0 20px;
padding:20px 0;
>span{
.font16;
color:@color_h2;
.flex-column();
b{
line-height: 20px;
font-weight: normal;
.font11;
color:@color_span;
}
}
.select_num{
.flex_center();
.btn{
.flex_center();
25px;
height: 25px;
border:1px solid @color_border;
&:active{
background: @color_btn;
color:@color_fff;
}
}
.input{
34px;
height: 25px;
border:1px solid @color_border;
margin:8px;
outline: none;
text-align: center;
.font12();
}
}
.input_text{
46%;
text-align: right;
line-height: 30px;
.font14;
color:@color_h3;
&::-webkit-input-placeholder{

}
}
.tel_box{
.flex-align-center();
input{
flex:1;
}
i{
19px;
height: 18px;
background: url("../../../static/img/ic_peoples.png");
background-size: cover;
margin-left:10px;
}
}
/*使用日期*/
.buy_time{
.flex();
.time_box{
.flex_center();
.flex-column();
text-align: center;
padding:6px;
border-radius: 3px;
min- 70px;
border:1px solid @color_h5;
margin-left:5px;
color:@color_h4;
&.active{
background: @color_btn;
color:@color_fff;
border:none;
}
&.disable{
color:@color_span;
}
span{
.font11;
line-height: 18px;
i{
display: block;

}
}
}
.time_box_more{
flex-direction: row;
i{
4px;
height: 7px;
background: url("../../../static/img/ic_switch_choice_jiatou_hui.png") no-repeat;
background-size: cover;
margin:0 11px;
}
}
}
}
.buy_btn_box{
position: fixed;
bottom:0;
100%;
height:60px;
.flex-justify-between();
.flex-align-center();
background: @color_fff;
border-top:1px solid @color_border;
.money{
margin-left:20px;
>span:nth-child(1){
.font14;
color:@color_red;
}
>span:last-child{
color:@color_red;
.font20;
font-weight: 600;
}
}
.buy_btn{
background: @color_btn;
height: 100%;
.flex_center();
140px;
.font18;
color:@color_fff;
}
}
}
.data_model{
position: fixed;
left:0;
top:0;
right:0;
bottom:0;
background: rgba(0,0,0,.4);
}
.calender-content{
background: #fff;
position: fixed;
bottom:0;
left:0;
100%;

.text_title{
text-align: center;
padding:20px 0 30px;
color:@color_h3;
position: relative;
.font16;
font-weight: 400;
span{
.font13;
position: absolute;
padding:20px;
top:0;
right:0;
}
}
.detail_time{
display: flex;
overflow-x: scroll;

}
}

.allMounth{
float: left;
20%;
padding-left: 10px;
padding-right: 10px;
p:last-child{
.font18;
color: #222;
margin:30px 0;
font-weight:400;
}
p{
text-align: center;
&.active{
color:#B49C63;
}
}

}

.cell-month{
margin-top: 3%;
background: #fff;
}

.sure_btn{
100%;
height:50px;
display: flex;
justify-content: center;
align-items: center;
background: #B49C63;
color:#fff;
font-size: 20px;
font-weight: 400;
margin-top:10px;
}
</style>

  

原文地址:https://www.cnblogs.com/dashaxiong/p/12167934.html