vue自定义日历:根据日期展示商品当天的价格

责编:menVScode 2020-10-12 15:40 阅读(62)

需求内容:根据不同时间段展示不同价格的日历。

后端返回的数据结构如下:


前端效果如下:


========

开始前我们先了解下获取日期的几个必要的知识点

(1) 现在是12月,通过getMonth()获得的就是11,获取其它时间节点即是对应的数据


(2) 获取指定日期的第一天和最后一天,知道上面的获取月份,现在我们想要获取4月份的第一天和最后一天:


========

封装插件

封装公共组件calendar.vue,这里就包含了日历及其所需功能

<template>
  <div>
    <div class="dateClass">
      <div v-if="datePickerShow" class="date-picker-container">
        <p style="padding: 10px 0;">
          <span class="showDate">
            <!-- 这里用了element的左箭头图标用于点击上个月按钮 -->
            <button @click.stop="lastMonth" class="monthBtn">
              <i class="el-icon-arrow-left"></i>
            </button>
            <!-- 以下为展示当前年月 -->
            <span>{{currentDate.year}}</span>
            <span>{{month}}</span>
            <!-- 下个月按钮 -->
            <button @click.stop="nextMonth" class="monthBtn">
              <i class="el-icon-arrow-right"></i>
            </button>
          </span>
          <!-- 关闭日历弹窗按钮 -->
          <button @click.stop="closePicker" class="closebtn">
            <i class="el-icon-close"></i>
          </button>
        </p>
        <!-- 日历周展示 -->
        <div class="week">
          <div v-for="(item, index) in week" :key="index">{{item}}</div>
        </div>
        <!-- 日及其对应价格展示 -->
        <div class="dates">
          <div v-for="(item, index) in priceDates" :class="{today: item.isPrice, noblank: true}"
            @click.stop="pickDate(item.date, item.price)" :key="index">
            <span>{{item.date}}</span><br>
            <span style="height:17px;display:inline-block">{{item.price}}</span>
          </div>
        </div>
      </div>
    </div>
  </div>
</template>
<script>
export default {
  name: 'myCalendar',
  props: {
    // 接收父组件传递是否展示日历弹窗
    datePickerShow: {
      type: Boolean,
      default: false
    },
    // 接收父组件传递日期价格数据
    feeProps: {
      type: Object,
      default: function () {
        return {}
      }
    }
  },
  data: function () {
    return {
      pickedDate: '',
      price: '',
      week: ['日', '一', '二', '三', '四', '五', '六'],
      priceDates: [],
      currentDate: {
        year: '',
        month: 0,
        date: ''
      }
    }
  },
  computed: {
    // 计算并展示选择的月份
    month: function () {
      const months = ['一', '二', '三', '四', '五', '六', '七', '八', '九', '十', '十一', '十二']
      return months[this.currentDate.month] + '月'
    }
  },
  methods: {
    // 默认日期显示
    openPicker: function (feeLis) {
      this.priceDates = []
      const now = new Date()
      this.currentDate.year = now.getFullYear()
      this.currentDate.month = now.getMonth()
      this.currentDate.date = now.getDate()
      now.setDate(1)
      // now已经变为当月第一天
      const firstDay = now.getDay() // 当月第一天是星期几
      // 当月最后一天是几号
      const lastDate = now.setFullYear(this.currentDate.year, this.currentDate.month + 1, 0).getDate()
      // 空出1号是星期几前面的那几天:例如日期从周日排到周一,1号是周二,则前面会空出周日和周一两个空日期
      for (let i = 0; i < firstDay; i++) {
        this.priceDates.push({ date: '', price: '', isPrice: false })
      }
      // 当月日期往后排
      for (let i = 1; i < lastDate + 1; i++) {
        this.priceDates.push({
          date: '' + i,
          price: '',
          isPrice: false
        })
        // 循环日期费用,判断年月日与当前是否相等,相等则显示价格与对应样式
        for (let key in feeLis) {
          let dateArr = key.split('-')
          if (dateArr[0] === (this.currentDate.year + '') && dateArr[1] - (this.currentDate.month + 1 + '') === 0 && dateArr[2] - (i + '') === 0) {
            this.priceDates[i - 1 + firstDay].price = '¥' + feeLis[key]
            this.priceDates[i - 1 + firstDay].isPrice = true
          }
        }
      }
    },
    // 上个月
    lastMonth: function () {
      if (this.currentDate.month !== 0) {
        this.currentDate.month--
      } else {
        this.currentDate.month = 11
        this.currentDate.year--
      }
      const now = new Date()
      now.setFullYear(this.currentDate.year, this.currentDate.month, 1)
      const firstDay = now.getDay() // 当月第一天是星期几
      now.setFullYear(this.currentDate.year, this.currentDate.month + 1, 0)
      const lastDate = now.getDate() // 当月最后一天是几号
      this.priceDates = []
      // 下面同理
      for (let i = 0; i < firstDay; i++) {
        this.priceDates.push({ date: '', price: '', isPrice: false })
      }
      for (let i = 1; i < lastDate + 1; i++) {
        this.priceDates.push({
          date: '' + i,
          price: ' ',
          isPrice: false
        })
        for (let key in this.feeProps) {
          let dateArr = key.split('-')
          if (dateArr[0] === (this.currentDate.year + '') && (parseInt(dateArr[1]) + '') - (this.currentDate.month + 1 + '') === 0 && (parseInt(dateArr[2]) + '') - (i + '') === 0) {
            this.priceDates[i - 1 + firstDay].price = '¥' + this.feeProps[key]
            this.priceDates[i - 1 + firstDay].isPrice = true
          }
        }
      }
    },
    // 下个月
    nextMonth: function () {
      if (this.currentDate.month !== 11) {
        this.currentDate.month++
      } else {
        this.currentDate.month = 0
        this.currentDate.year++
      }
      const now = new Date()
      now.setFullYear(this.currentDate.year, this.currentDate.month, 1)
      const firstDay = now.getDay() // 当月第一天是星期几
      now.setFullYear(this.currentDate.year, this.currentDate.month + 1, 0)
      const lastDate = now.getDate() // 当月最后一天是几号
      this.priceDates = []
      for (let i = 0; i < firstDay; i++) {
        this.priceDates.push({ date: '', price: '', isPrice: false })
      }
      for (let i = 1; i < lastDate + 1; i++) {
        this.priceDates.push({
          date: '' + i,
          price: ' ',
          isPrice: false
        })
        for (let key in this.feeProps) {
          let dateArr = key.split('-')
          if (dateArr[0] === (this.currentDate.year + '') && (parseInt(dateArr[1]) + '') - (this.currentDate.month + 1 + '') === 0 && (parseInt(dateArr[2]) + '') - (i + '') === 0) {
            this.priceDates[i - 1 + firstDay].price = '¥' + this.feeProps[key]
            this.priceDates[i - 1 + firstDay].isPrice = true
          }
        }
      }
    },
    // 关闭弹窗发布事件
    closePicker: function () {
      this.$emit('feeClose', false)
    },
    // 记录点击的日期,根据是否需要使用
    pickDate: function (date, price) {
      this.pickedDate = this.currentDate.year + '-' + (this.currentDate.month + 1) + '-' + date
      this.price = price
    }
  },
  watch: {
    // 监听接口传值,收到即赋值展示
    feeProps (feeLis) {
      if (JSON.stringfy(feeLis) !== '{}') this.openPicker(feeLis)
    }
  }
}
</script>

<style lang="less" scoped>
.dateClass {
  position: absolute;
  top: 16px;
  left: 0;
  z-index: 999999;
  .date-picker-container {
    width: 370px;
    border: solid #eee 1px;
    box-shadow: rgba(0, 0, 0, 0.5) 0px 5px 15px;
    padding: 0 8px;
    background-color: #fff;
    color: rgb(96, 98, 102);
    position: relative;
    .showDate {
      border: 1px solid #ebeef5;
      display: inline-block;
      width: 234px;
      line-height: 24px;
    }
    .monthBtn,
    .closebtn {
      background-color: #fff;
      cursor: pointer;
      padding: 0 30px;
    }
    .closebtn {
      position: absolute;
      padding-left: 10px;
      top: 10px;
      right: 5px;
    }
    .week {
      width: 370px;
      height: 20px;
      div {
        width: 50px;
        height: 20px;
        line-height: 20px;
        float: left;
        text-align: center;
        word-spacing: 0;
        border: 1px solid #ebeef5;
      }
    }
    .dates {
      padding: 0 0 10px;
      width: 370px;
      overflow: hidden;
      & > div {
        width: 50px;
        height: 31px;
        float: left;
        text-align: center;
      }
      .today {
        color: #fff;
        background-color: #25b7aa;
      }
      .noblank {
        cursor: pointer;
        border: 1px solid #ebeef5;
        &:hover {
          background-color: #92dbd4;
        }
      }
    }
  }
}
</style>

使用:

在父组件引用并使用:

<template>
  <div>
  	<button @click="showPicker">点击查看</button>
  	<Calendar :datePickerShow="datePickerShow" :feeProps="feeProps" @feeClose="closeFee</Calendar>
  </div>
<template/>
<script>
  export default {
    // ...
    data () {
      datePickerShow: false,
      feeProps: {}
    },
    methods: {
      closeFee () {
        this.datePickerShow = false
      },
      getFeeProps () {
        // this.feeProps = {xxx}
      },
      showPicker () {
      	this.feeProps = {
          '2020-03-30': 11,
          '2020-04-01': 11,
          '2020-04-02': 11
      	}
      	this.datePickerShow = true
      }
    }
  }
<script/>

原址:https://blog.csdn.net/weixin_42204698/article/details/103761289

标签: 日历 vue
前端交流群: MVC前端网(menvscode.com)-qq交流群:551903636

邮箱快速注册

忘记密码