| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507 | 
							- <template>
 
- 	<view class="uni-calendar">
 
- 		<view v-if="!insert&&show" class="uni-calendar__mask" :class="{'uni-calendar--mask-show':aniMaskShow}" @click="clean"></view>
 
- 		<view v-if="insert || show" class="uni-calendar__content" :class="{'uni-calendar--fixed':!insert,'uni-calendar--ani-show':aniMaskShow}">
 
- 			<view v-if="!insert" class="uni-calendar__header uni-calendar--fixed-top">
 
- 				<view class="uni-calendar__header-btn-box" @click="close">
 
- 					<text class="uni-calendar__header-text uni-calendar--fixed-width">取消</text>
 
- 				</view>
 
- 				<view class="uni-calendar__header-btn-box" @click="confirm">
 
- 					<text class="uni-calendar__header-text uni-calendar--fixed-width">确定</text>
 
- 				</view>
 
- 			</view>
 
- 			<view class="uni-calendar__header">
 
- 				<view class="uni-calendar__header-btn-box" @click.stop="pre">
 
- 					<view class="uni-calendar__header-btn uni-calendar--left"></view>
 
- 				</view>
 
- 				<picker mode="date" :value="date" fields="month" @change="bindDateChange">
 
- 					<text class="uni-calendar__header-text">{{ (nowDate.year||'') +'年'+( nowDate.month||'') +'月'}}</text>
 
- 				</picker>
 
- 				<view class="uni-calendar__header-btn-box" @click.stop="next">
 
- 					<view class="uni-calendar__header-btn uni-calendar--right"></view>
 
- 				</view>
 
- 				<text class="uni-calendar__backtoday" @click="backtoday">回到今天</text>
 
- 			</view>
 
- 			<view class="uni-calendar__box">
 
- 				<view v-if="showMonth" class="uni-calendar__box-bg">
 
- 					<text class="uni-calendar__box-bg-text">{{nowDate.month}}</text>
 
- 				</view>
 
- 				<view class="uni-calendar__weeks">
 
- 					<view class="uni-calendar__weeks-day">
 
- 						<text class="uni-calendar__weeks-day-text">日</text>
 
- 					</view>
 
- 					<view class="uni-calendar__weeks-day">
 
- 						<text class="uni-calendar__weeks-day-text">一</text>
 
- 					</view>
 
- 					<view class="uni-calendar__weeks-day">
 
- 						<text class="uni-calendar__weeks-day-text">二</text>
 
- 					</view>
 
- 					<view class="uni-calendar__weeks-day">
 
- 						<text class="uni-calendar__weeks-day-text">三</text>
 
- 					</view>
 
- 					<view class="uni-calendar__weeks-day">
 
- 						<text class="uni-calendar__weeks-day-text">四</text>
 
- 					</view>
 
- 					<view class="uni-calendar__weeks-day">
 
- 						<text class="uni-calendar__weeks-day-text">五</text>
 
- 					</view>
 
- 					<view class="uni-calendar__weeks-day">
 
- 						<text class="uni-calendar__weeks-day-text">六</text>
 
- 					</view>
 
- 				</view>
 
- 				<view class="uni-calendar__weeks" v-for="(item,weekIndex) in weeks" :key="weekIndex">
 
- 					<view class="uni-calendar__weeks-item" v-for="(weeks,weeksIndex) in item" :key="weeksIndex">
 
- 						<calendar-item :weeks="weeks" :calendar="calendar" :selected="selected" :lunar="lunar" @change="choiceDate"></calendar-item>
 
- 					</view>
 
- 				</view>
 
- 			</view>
 
- 		</view>
 
- 	</view>
 
- </template>
 
- <script>
 
- 	import Calendar from './util.js';
 
- 	import calendarItem from './uni-calendar-item.vue'
 
- 	/**
 
- 	 * Calendar 日历
 
- 	 * @description 日历组件可以查看日期,选择任意范围内的日期,打点操作。常用场景如:酒店日期预订、火车机票选择购买日期、上下班打卡等
 
- 	 * @tutorial https://ext.dcloud.net.cn/plugin?id=56
 
- 	 * @property {String} date 自定义当前时间,默认为今天
 
- 	 * @property {Boolean} lunar 显示农历
 
- 	 * @property {String} startDate 日期选择范围-开始日期
 
- 	 * @property {String} endDate 日期选择范围-结束日期
 
- 	 * @property {Boolean} range 范围选择
 
- 	 * @property {Boolean} insert = [true|false] 插入模式,默认为false
 
- 	 * 	@value true 弹窗模式
 
- 	 * 	@value false 插入模式
 
- 	 * @property {Boolean} clearDate = [true|false] 弹窗模式是否清空上次选择内容
 
- 	 * @property {Array} selected 打点,期待格式[{date: '2019-06-27', info: '签到', data: { custom: '自定义信息', name: '自定义消息头',xxx:xxx... }}]
 
- 	 * @property {Boolean} showMonth 是否选择月份为背景
 
- 	 * @event {Function} change 日期改变,`insert :ture` 时生效
 
- 	 * @event {Function} confirm 确认选择`insert :false` 时生效
 
- 	 * @event {Function} monthSwitch 切换月份时触发
 
- 	 * @example <uni-calendar :insert="true":lunar="true" :start-date="'2019-3-2'":end-date="'2019-5-20'"@change="change" />
 
- 	 */
 
- 	export default {
 
- 		components: {
 
- 			calendarItem
 
- 		},
 
- 		props: {
 
- 			date: {
 
- 				type: String,
 
- 				default: ''
 
- 			},
 
- 			selected: {
 
- 				type: Array,
 
- 				default () {
 
- 					return []
 
- 				}
 
- 			},
 
- 			lunar: {
 
- 				type: Boolean,
 
- 				default: false
 
- 			},
 
- 			startDate: {
 
- 				type: String,
 
- 				default: ''
 
- 			},
 
- 			endDate: {
 
- 				type: String,
 
- 				default: ''
 
- 			},
 
- 			range: {
 
- 				type: Boolean,
 
- 				default: false
 
- 			},
 
- 			insert: {
 
- 				type: Boolean,
 
- 				default: true
 
- 			},
 
- 			showMonth: {
 
- 				type: Boolean,
 
- 				default: true
 
- 			},
 
- 			clearDate: {
 
- 				type: Boolean,
 
- 				default: true
 
- 			}
 
- 		},
 
- 		data() {
 
- 			return {
 
- 				show: false,
 
- 				weeks: [],
 
- 				calendar: {},
 
- 				nowDate: '',
 
- 				aniMaskShow: false
 
- 			}
 
- 		},
 
- 		watch: {
 
- 			date(newVal) {
 
- 				this.cale.setDate(newVal)
 
- 				this.init(this.cale.selectDate.fullDate)
 
- 			},
 
- 			startDate(val){
 
- 				this.cale.resetSatrtDate(val)
 
- 			},
 
- 			endDate(val){
 
- 				this.cale.resetEndDate(val)
 
- 			},
 
- 			selected(newVal) {
 
- 				this.cale.setSelectInfo(this.nowDate.fullDate, newVal)
 
- 				this.weeks = this.cale.weeks
 
- 			}
 
- 		},
 
- 		created() {
 
- 			// 获取日历方法实例
 
- 			this.cale = new Calendar({
 
- 				// date: new Date(),
 
- 				selected: this.selected,
 
- 				startDate: this.startDate,
 
- 				endDate: this.endDate,
 
- 				range: this.range,
 
- 			})
 
- 			// 选中某一天
 
- 			this.cale.setDate(this.date)
 
- 			this.init(this.cale.selectDate.fullDate)
 
- 			// this.setDay
 
- 		},
 
- 		methods: {
 
- 			// 取消穿透
 
- 			clean() {},
 
- 			bindDateChange(e) {
 
- 				const value = e.detail.value + '-1'
 
- 				// console.log(this.cale.getDate(value));
 
- 				this.cale.setDate(value)
 
- 				this.init(value)
 
- 			},
 
- 			/**
 
- 			 * 初始化日期显示
 
- 			 * @param {Object} date
 
- 			 */
 
- 			init(date) {
 
- 				this.weeks = this.cale.weeks
 
- 				this.nowDate = this.calendar = this.cale.getInfo(date)
 
- 			},
 
- 			/**
 
- 			 * 打开日历弹窗
 
- 			 */
 
- 			open() {
 
- 				// 弹窗模式并且清理数据
 
- 				if (this.clearDate && !this.insert) {
 
- 					this.cale.cleanMultipleStatus()
 
- 					this.cale.setDate(this.date)
 
- 					this.init(this.cale.selectDate.fullDate)
 
- 				}
 
- 				this.show = true
 
- 				this.$nextTick(() => {
 
- 					setTimeout(() => {
 
- 						this.aniMaskShow = true
 
- 					}, 50)
 
- 				})
 
- 			},
 
- 			/**
 
- 			 * 关闭日历弹窗
 
- 			 */
 
- 			close() {
 
- 				this.aniMaskShow = false
 
- 				this.$nextTick(() => {
 
- 					setTimeout(() => {
 
- 						this.show = false
 
- 						this.$emit('close')
 
- 					}, 300)
 
- 				})
 
- 			},
 
- 			/**
 
- 			 * 确认按钮
 
- 			 */
 
- 			confirm() {
 
- 				this.setEmit('confirm')
 
- 				this.close()
 
- 			},
 
- 			/**
 
- 			 * 变化触发
 
- 			 */
 
- 			change() {
 
- 				if (!this.insert) return
 
- 				this.setEmit('change')
 
- 			},
 
- 			/**
 
- 			 * 选择月份触发
 
- 			 */
 
- 			monthSwitch() {
 
- 				let {
 
- 					year,
 
- 					month
 
- 				} = this.nowDate
 
- 				this.$emit('monthSwitch', {
 
- 					year,
 
- 					month: Number(month)
 
- 				})
 
- 			},
 
- 			/**
 
- 			 * 派发事件
 
- 			 * @param {Object} name
 
- 			 */
 
- 			setEmit(name) {
 
- 				let {
 
- 					year,
 
- 					month,
 
- 					date,
 
- 					fullDate,
 
- 					lunar,
 
- 					extraInfo
 
- 				} = this.calendar
 
- 				this.$emit(name, {
 
- 					range: this.cale.multipleStatus,
 
- 					year,
 
- 					month,
 
- 					date,
 
- 					fulldate: fullDate,
 
- 					lunar,
 
- 					extraInfo: extraInfo || {}
 
- 				})
 
- 			},
 
- 			/**
 
- 			 * 选择天触发
 
- 			 * @param {Object} weeks
 
- 			 */
 
- 			choiceDate(weeks) {
 
- 				if (weeks.disable) return
 
- 				this.calendar = weeks
 
- 				
 
- 				// 设置多选
 
- 				this.cale.setMultiple(this.calendar.fullDate)
 
- 				
 
- 				this.weeks = this.cale.weeks
 
- 				this.change()
 
- 			},
 
- 			/**
 
- 			 * 回到今天
 
- 			 */
 
- 			backtoday() {
 
- 				// console.log(this.cale.getDate(new Date()).fullDate);
 
- 				let date = this.cale.getDate(new Date()).fullDate
 
- 				this.cale.setDate(date)
 
- 				this.init(date)
 
- 				this.change()
 
- 			},
 
- 			/**
 
- 			 * 上个月
 
- 			 */
 
- 			pre() {
 
- 				const preDate = this.cale.getDate(this.nowDate.fullDate, -1, 'month').fullDate
 
- 				this.setDate(preDate)
 
- 				this.monthSwitch()
 
- 			},
 
- 			/**
 
- 			 * 下个月
 
- 			 */
 
- 			next() {
 
- 				const nextDate = this.cale.getDate(this.nowDate.fullDate, +1, 'month').fullDate
 
- 				this.setDate(nextDate)
 
- 				this.monthSwitch()
 
- 			},
 
- 			/**
 
- 			 * 设置日期
 
- 			 * @param {Object} date
 
- 			 */
 
- 			setDate(date) {
 
- 				this.cale.setDate(date)
 
- 				this.weeks = this.cale.weeks
 
- 				this.nowDate = this.cale.getInfo(date)
 
- 			}
 
- 		}
 
- 	}
 
- </script>
 
- <style lang="scss" scoped>
 
- 	.uni-calendar {
 
- 		/* #ifndef APP-NVUE */
 
- 		display: flex;
 
- 		/* #endif */
 
- 		flex-direction: column;
 
- 	}
 
- 	.uni-calendar__mask {
 
- 		position: fixed;
 
- 		bottom: 0;
 
- 		top: 0;
 
- 		left: 0;
 
- 		right: 0;
 
- 		background-color: $uni-bg-color-mask;
 
- 		transition-property: opacity;
 
- 		transition-duration: 0.3s;
 
- 		opacity: 0;
 
- 		/* #ifndef APP-NVUE */
 
- 		z-index: 99;
 
- 		/* #endif */
 
- 	}
 
- 	.uni-calendar--mask-show {
 
- 		opacity: 1
 
- 	}
 
- 	.uni-calendar--fixed {
 
- 		position: fixed;
 
- 		bottom: 0;
 
- 		left: 0;
 
- 		right: 0;
 
- 		transition-property: transform;
 
- 		transition-duration: 0.3s;
 
- 		transform: translateY(460px);
 
- 		/* #ifndef APP-NVUE */
 
- 		z-index: 99;
 
- 		/* #endif */
 
- 	}
 
- 	.uni-calendar--ani-show {
 
- 		transform: translateY(0);
 
- 	}
 
- 	.uni-calendar__content {
 
- 		background-color: #fff;
 
- 	}
 
- 	.uni-calendar__header {
 
- 		position: relative;
 
- 		/* #ifndef APP-NVUE */
 
- 		display: flex;
 
- 		/* #endif */
 
- 		flex-direction: row;
 
- 		justify-content: center;
 
- 		align-items: center;
 
- 		height: 50px;
 
- 		border-bottom-color: $uni-border-color;
 
- 		border-bottom-style: solid;
 
- 		border-bottom-width: 1px;
 
- 	}
 
- 	.uni-calendar--fixed-top {
 
- 		/* #ifndef APP-NVUE */
 
- 		display: flex;
 
- 		/* #endif */
 
- 		flex-direction: row;
 
- 		justify-content: space-between;
 
- 		border-top-color: $uni-border-color;
 
- 		border-top-style: solid;
 
- 		border-top-width: 1px;
 
- 	}
 
- 	.uni-calendar--fixed-width {
 
- 		width: 50px;
 
- 		// padding: 0 15px;
 
- 	}
 
- 	.uni-calendar__backtoday {
 
- 		position: absolute;
 
- 		right: 0;
 
- 		top: 25rpx;
 
- 		padding: 0 5px;
 
- 		padding-left: 10px;
 
- 		height: 25px;
 
- 		line-height: 25px;
 
- 		font-size: 12px;
 
- 		border-top-left-radius: 25px;
 
- 		border-bottom-left-radius: 25px;
 
- 		color: $uni-text-color;
 
- 		background-color: $uni-bg-color-hover;
 
- 	}
 
- 	.uni-calendar__header-text {
 
- 		text-align: center;
 
- 		width: 100px;
 
- 		font-size: $uni-font-size-base;
 
- 		color: $uni-text-color;
 
- 	}
 
- 	.uni-calendar__header-btn-box {
 
- 		/* #ifndef APP-NVUE */
 
- 		display: flex;
 
- 		/* #endif */
 
- 		flex-direction: row;
 
- 		align-items: center;
 
- 		justify-content: center;
 
- 		width: 50px;
 
- 		height: 50px;
 
- 	}
 
- 	.uni-calendar__header-btn {
 
- 		width: 10px;
 
- 		height: 10px;
 
- 		border-left-color: $uni-text-color-placeholder;
 
- 		border-left-style: solid;
 
- 		border-left-width: 2px;
 
- 		border-top-color: $uni-color-subtitle;
 
- 		border-top-style: solid;
 
- 		border-top-width: 2px;
 
- 	}
 
- 	.uni-calendar--left {
 
- 		transform: rotate(-45deg);
 
- 	}
 
- 	.uni-calendar--right {
 
- 		transform: rotate(135deg);
 
- 	}
 
- 	.uni-calendar__weeks {
 
- 		position: relative;
 
- 		/* #ifndef APP-NVUE */
 
- 		display: flex;
 
- 		/* #endif */
 
- 		flex-direction: row;
 
- 	}
 
- 	.uni-calendar__weeks-item {
 
- 		flex: 1;
 
- 	}
 
- 	.uni-calendar__weeks-day {
 
- 		flex: 1;
 
- 		/* #ifndef APP-NVUE */
 
- 		display: flex;
 
- 		/* #endif */
 
- 		flex-direction: column;
 
- 		justify-content: center;
 
- 		align-items: center;
 
- 		height: 45px;
 
- 		border-bottom-color: #F5F5F5;
 
- 		border-bottom-style: solid;
 
- 		border-bottom-width: 1px;
 
- 	}
 
- 	.uni-calendar__weeks-day-text {
 
- 		font-size: 14px;
 
- 	}
 
- 	.uni-calendar__box {
 
- 		position: relative;
 
- 	}
 
- 	.uni-calendar__box-bg {
 
- 		/* #ifndef APP-NVUE */
 
- 		display: flex;
 
- 		/* #endif */
 
- 		justify-content: center;
 
- 		align-items: center;
 
- 		position: absolute;
 
- 		top: 0;
 
- 		left: 0;
 
- 		right: 0;
 
- 		bottom: 0;
 
- 	}
 
- 	.uni-calendar__box-bg-text {
 
- 		font-size: 200px;
 
- 		font-weight: bold;
 
- 		color: $uni-text-color-grey;
 
- 		opacity: 0.1;
 
- 		text-align: center;
 
- 		/* #ifndef APP-NVUE */
 
- 		line-height: 1;
 
- 		/* #endif */
 
- 	}
 
- </style>
 
 
  |