问题描述
HMS需要实现产品的一个日期选择器。要求如下,小于等于7天的日期范围显示横向滑动的日期栏,大于7天的日期范围则要在日期栏右侧固定显示一个日历icon,点击显示日历,且日期上显示有无号的标志(可认为是该日期的一个特殊标识)
完整实例
https://github.com/yapeee/vue_points
效果展示1:
效果展示2:
重难点实现
1.日期tab栏的实现
采用vant的Tab组件,通过自定义样式实现。
<van-tabs v-model="active" @click="chooseDate">
<van-tab v-for="(item,index) in dateList"
:key="item.dateStr1"
:name="index"
>
<!--自定义样式-->
<div slot="title" class="date-item" :class="item.dateStr === selectDate.dateStr ? 'active' : ''">
<div class="week">
{{item.dateStr1 === today ? '今日' : item.week}}
<span :class="item.state === 'yes'? 'hasNum' : ''">{{item.state === 'yes'? '有' : '无'}}</span>
</div>
<div class="date">{{item.dateStr}}</div>
</div>
</van-tab>
</van-tabs>
2.日历弹出框的实现
采用vant的ActionSheet组件实现弹出框效果,然后嵌入vux的InlineCalendar日历组件,实现日历弹出框。
<van-action-sheet v-model="show" title="日历">
<inline-calendar
v-model="value"
:start-date="today"
:end-date="lastDay"
:return-six-rows="false"
:render-function="buildSlotFn"
@on-change="chooseCalendarDay"
></inline-calendar>
</van-action-sheet>
3.自定义日历日期
// 日历组件
this.buildSlotFn = (line, index, data) => {
return this.stateList[data.formatedDate] === 'yes' ? '<div style="font-size:12px;text-align:center;"><span style="display:inline-block;width:5px;height:5px;background-color:red;border-radius:50%;"></span></div>' : '<div style="height:19px;"></div>'
}
4.日历选择器联动日期tab栏
给日历组件添加@on-change事件,获取到选中日期后,清空数组,重新给数组赋值。(tips:注意先清空tab栏数组,然后异步更新数组)
chooseCalendarDay (day) { // 选择日历日期
this.show = false
this.active = 0
this.dateList = []
this.$nextTick(() => {
let date = new Date(day)
this.dateList = this.getDateItems(date)
this.chooseDate(this.active)
})
},
5.传值父组件
chooseDate (name) { // 选择日期
this.selectDate = this.dateList[name]
this.$emit('getDate', this.selectDate)
},
其他
有时间尝试全部使用vux实现上述页面。
欢迎star&issue
---------201907031更新------------
增加自定义日历日期实现方式