Vue 日历组件

(1) 简介

该日历组件是一个应用于移动端的日历组件采用了rem(文末附有rem.js)

(2) template
<template>
	<div class="calendar">
		<div class="calendar-year">
			<span @click="chooseYear">{{showDate.year}}</span>
			<svg  xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="14px" height="7px">
				<path fill-rule="evenodd"  fill="#1e80d7" d="M7.000,7.001 L-0.001,-0.000 L14.001,-0.000 L7.000,7.001 Z"/>
			</svg>
		</div>
		<div class="calendar-month">
			<div class="month-left" @click="prevMonth">
				<svg  xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="12px" height="18px">
					<path fill-rule="evenodd"  fill="rgb(30, 128, 215)" d="M1.084,10.100 C3.906,12.628 6.728,15.155 9.551,17.680 C10.713,18.721 12.445,17.031 11.279,15.987 C8.767,13.739 6.255,11.491 3.744,9.242 C6.268,6.915 8.792,4.587 11.316,2.259 C12.466,1.200 10.734,-0.491 9.588,0.567 C6.753,3.180 3.918,5.793 1.084,8.407 C0.614,8.841 0.603,9.671 1.084,10.100 Z"/>
				</svg>
			</div>
			<div class="month-center">
				<div class="month-content">
					<transition :name="fadeDateType">
						<span :key="showDate.month">{{showDate.month}}月</span>
					</transition>
				</div>
			</div>
			<div class="month-right" @click="nextMonth">
				<svg  xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="12px" height="18px">
					<path fill-rule="evenodd"  fill="rgb(30, 128, 215)" d="M10.916,10.100 C8.093,12.628 5.272,15.155 2.449,17.680 C1.287,18.721 -0.445,17.031 0.721,15.987 C3.233,13.739 5.745,11.491 8.256,9.242 C5.732,6.915 3.208,4.587 0.683,2.259 C-0.467,1.200 1.266,-0.491 2.412,0.567 C5.247,3.180 8.081,5.793 10.916,8.407 C11.385,8.841 11.397,9.671 10.916,10.100 Z"/>
				</svg>
			</div>
		</div>
		<div class="calendar-content">
			<!--星期-->
			<div class="calendar-day">
				<ul>
					<li>日</li>
					<li>一</li>
					<li>二</li>
					<li>三</li>
					<li>四</li>
					<li>五</li>
					<li>六</li>
				</ul>
			</div>
			<!--时间-->
			<div class="calendar-dayDate">
				<transition :name="fadeDateType">
					<ul class="calendar-date" v-swipeleft="nextMonth" v-swiperight="prevMonth">
						<li v-for="item in showDate.allDate" :class="{'calendar-now-month': item.nowMonth,'calendar-can-click': item.canClick,'isNowDay': item.isNowDay}">
							<span v-if="item.canClick" @click="dealClick(item.intactDate)">{{item.dayDate}}</span>
							<span v-if="!item.canClick">{{item.dayDate}}</span>
						</li>
					</ul>
				</transition>
			</div>
		</div>
		<!--弹出框-->
		<div class="calendar-mask" v-if="showMask" @click="closeMask" @touchmove.prevent></div>
		<div class="calendar-box" :style="{height:b_height}">
			<div class="year-title">
				<button type="button" class="year-list-cancel"><span @click="closeMask">取消</span></button>
				<button type="button" class="year-list-ok"><span @click="okYear">确定</span></button>
			</div>
			<div class="year-list">
				<transition :name="fadeUlType">
					<div class="show-ul" v-swipeup="nextYear" v-swipedown="prevYear">
						<ul :style="{'top':b_top + 'rem'}">
							<li v-for="item in showYearMonth" :class="{'active': item.activeYear}" :key="item.year" @click="dealClickYear(item)">{{item.year}}</li>
						</ul>
					</div>
				</transition>
				<div class="center-line"></div>
			</div>
		</div>
	</div>
</template>
(3) script
<script>
	// 初始化星期
	const weekJson = {
		0: "日",
		1: "一",
		2: "二",
		3: "三",
		4: "四",
		5: "五",
		6: "六"
	}
	// 初始化月份 -- 兼容ie
	const monthJson = {
		"01": "一",
		"02": "二",
		"03": "三",
		"04": "四",
		"05": "五",
		"06": "六",
		"07": "七",
		"08": "八",
		"09": "九",
		"10": "十",
		"11": "十一",
		"12": "十二"
	}
	
	// 闰年月份判断
	const leapYeareMonth = [31,29,31,30,31,30,31,31,30,31,30,31]
	// 平年月份判断
	const commonYearMonth = [31,28,31,30,31,30,31,31,30,31,30,31]
	
	// 用于touch事件
	function vueTouch(el,binding,type,vnode){
		let _this = this;
		this.obj = el;
		this.binding = binding;
		this.touchType = type;
		this.vueTouches = {x: 0,y: 0};
		this.vueMoves = true;
		this.vueLeave = true;
		this.longTouch = true;
		this.vueCallBack = typeof(binding.value) == "object" ? binding.value.fn : binding.value;
		this.obj.addEventListener("touchstart",function(e){
			_this.start(e);
		});
		this.obj.addEventListener("touchend",function(e){
			_this.end(e);
		});
		this.obj.addEventListener("touchmove",function(e){
			e.preventDefault();
			_this.move(e);
		});
		vnode.key = this.randomString();
	}
	
	vueTouch.prototype={
		start(e){
			this.vueMoves = true;
			this.vueLeave = true;
			this.longTouch = true;
			this.vueTouches = {x: e.changedTouches[0].pageX,y: e.changedTouches[0].pageY};
			this.time = setTimeout(function(){
				if(this.vueLeave && this.vueMoves){
					this.touchType == "longtap" && this.vueCallBack(this.binding.value,e);
					this.longTouch = false;
				};
			}.bind(this),1000);
		},
		end(e){
			var disX = e.changedTouches[0].pageX-this.vueTouches.x;
			var disY = e.changedTouches[0].pageY-this.vueTouches.y;
			clearTimeout(this.time);
			if(Math.abs(disX) > 10 || Math.abs(disY)>10){
				this.touchType == "swipe" && this.vueCallBack(this.binding.value,e);
				if(Math.abs(disX) > Math.abs(disY)){
					if(disX > 10){
						this.touchType == "swiperight" && this.vueCallBack(this.binding.value,e);
					};
					if(disX < -10){
						this.touchType == "swipeleft" && this.vueCallBack(this.binding.value,e);
					};
				}else{
					if(disY > 10){
						this.touchType == "swipedown" && this.vueCallBack(this.binding.value,e);
					};
					if(disY < -10){
						this.touchType == "swipeup" && this.vueCallBack(this.binding.value,e);
					};	
				};
			}else{
				if(this.longTouch && this.vueMoves){
					this.touchType == "tap" && this.vueCallBack(this.binding.value,e);
					this.vueLeave = false;
				};
			};
		},
		move(e){
			this.vueMoves = false;
		},
		randomString(){
			var len = 10;
		   var $chars = 'ABCDEFGHJKMNPQRSTWXYZabcdefhijkmnprstwxyz2345678';
		   var maxPos = $chars.length;
		   var pwd = '';
		   for (var i = 0; i < len; i++) {
				pwd += $chars.charAt(Math.floor(Math.random() * maxPos));
		   }
		   return pwd;
		}
	}
	
	export default{
		data:() => ({
			fadeDateType: "", // 动画的name
			showYearMonth: [], // 存放显示年份区间及月份
			showDefaultDate: "",
			startDate: "",
			endDate: "",
			showDate: {
				date: "", // 完整的日期显示 -- 默认日期
				year: "", // 年
				month: "", // 月 -- 中文
				allDate: [] // 需要显示的日期
				/*
					{
						intactDate: "",  // 完整的时间 -- 2018-06-11
						dayDate: "",     // 日期,默认显示 "12"
						nowMonth: false, // 是否为显示月
						canClick: false, // 是否有比赛
						isNowDay: false, // 是否是今天
						activeDay: false // 是否被点击
					}
				*/
			},
			// 弹出框
			showMask: false,
			showBox: false,
			b_height:"0", // 初始化弹出框的高
			b_top: 0, // 弹出框中ul的top值
			fadeUlType: "" // 执行动画的名
		}),
		props:{
			// 日期最小值 -- 必填
			minDate: {
				type: String,
				required: true
			},
			// 日期最大值 -- 必填
			maxDate: {
				type: String,
				required: true
			},
			// 设置默认时间 -- 选填
			defaultDate: {
				type: String
			},
			// 显示区域比赛日 -- 数据格式 "2018-07-11"
			gameDate: {
				type: Array // 可设置所有天数可点 -- >设置数组首位为All ["all"]
			}
		},
		created(){
			// 初始化时间
			this.showDefaultDate = this.defaultDate ? this.defaultDate : "";
			this.initDate();
		},
		watch:{
			showMask: function(){
				this.forbidScroll(this.showMask);
			}
		},
		methods:{
			// 初始化日期
			initDate(){
				this.startDate = this.minDate.split("-"); //开始时间
				this.endDate = this.maxDate.split("-"); // 结束时间
				this.dealMonthDate();
				this.dealYearMonth();
			},
			// 总年份处理,总月份处理
			dealYearMonth(){
				let allMonth = ["01","02","03","04","05","06","07","08","09","10","11","12"];
				let num = this.endDate[0] - this.startDate[0];
				if(num == 0){
					// 只有一年
					let item = {
						year: this.startDate[0],
						month: allMonth.slice(allMonth.indexOf(this.startDate[1]),allMonth.indexOf(this.endDate[1]) + 1),
						activeYear: true
					}
					this.showYearMonth.push(item);
				}else if(num == 1){
					// 只有开始和结束两年
					let itemStart = {
						year: this.startDate[0],
						month: allMonth.slice(allMonth.indexOf(this.startDate[1])),
						activeYear: false
					}
					let itemEnd = {
						year: this.endDate[0],
						month: allMonth.slice(0,allMonth.indexOf(this.endDate[1]) + 1),
						activeYear: false
					}
					this.showYearMonth.push(itemStart);
					this.showYearMonth.push(itemEnd);
				}else{
					// 有多年
					let itemStart = {
						year: this.startDate[0],
						month: allMonth.slice(allMonth.indexOf(this.startDate[1])),
						activeYear: false
					}
					let itemEnd = {
						year: this.endDate[0],
						month: allMonth.slice(0,allMonth.indexOf(this.endDate[1]) + 1),
						activeYear: false
					}
					this.showYearMonth.push(itemStart);
					for(let i = 0; i < this.endDate[0] - this.startDate[0] - 1; i++){
						let item = {
							year: Number(this.startDate[0]) + 1 + i,
							month: allMonth,
							activeYear: false
						}
						this.showYearMonth.push(item);
					}
					this.showYearMonth.push(itemEnd);
				}
				this.amendActiveYear();
			},
			// 处理所有年份中的焦点年份 -- 修改activeYear
			amendActiveYear(){
				for(let i = 0; i < this.showYearMonth.length; i++){
					let item = this.showYearMonth[i];
					item.activeYear = item.year == this.showDate.date[0] ? true : false;
				}
			},
			// 处理显示天数
			dealMonthDate(){
				this.showDate.allDate = [];
				// 获取当前时间
				let date1 = new Date();
				let nowDate = [date1.getFullYear(),((date1.getMonth() + 1) > 9 ? (date1.getMonth() + 1) : "0" + (date1.getMonth() + 1)),(date1.getDate() > 9 ? date1.getDate() : "0" + date1.getDate())];
				// 如果没有设置默认时间,默认为当天 -- > 当月  -- > 当年
				this.showDate.date = this.showDefaultDate ? this.showDefaultDate.split("-") : nowDate;
				this.showDate.year = this.showDate.date[0];
				this.showDate.month = monthJson[this.showDate.date[1]];
				// 设置总显示天数
				let showDayNum = 0;
				let numDay = this.judgeYear(this.showDate.date[0],Number(this.showDate.date[1])); // 显示月天数
				showDayNum += numDay;
				// 获取显示年月
				let showDateFirstDay = this.showDate.date[0] + "-" + this.showDate.date[1] + "-" + "01"; // 显示月开始
				let showDateEndDay = this.showDate.date[0] + "-" + this.showDate.date[1] + "-" + numDay; // 显示月结束
				// 判断星期 , 获取显示区域第一天
				let date = new Date(showDateFirstDay);
				let _firstDay = date.getDay();
				showDayNum = showDayNum + date.getDay() + (6 -new Date(showDateEndDay).getDay());
				date.setDate(date.getDate() - date.getDay());
				for(let i = 0; i < showDayNum; i++){
					let _date = date.getFullYear() + "-" + ((date.getMonth() + 1) > 9 ? (date.getMonth() + 1) : "0" + (date.getMonth() + 1)) + "-" + (date.getDate() > 9 ? date.getDate() : "0" + date.getDate());
					let _dateMsg = {
						intactDate: _date,
						dayDate: date.getDate(),
						nowMonth: false,
						canClick: this.dateCanClick(_date),
						isNowDay: this.judgeNowDay(_date)
					}
					if(i >= _firstDay && i < numDay + _firstDay){
						_dateMsg.nowMonth = true;
					}
					this.showDate.allDate.push(_dateMsg);
					// 设置下一天
					date.setDate(date.getDate() + 1);
				}
			},
			// 检测是否可点 -- 用于判断当天是否有比赛
			dateCanClick(date){
				if(this.gameDate == undefined){
					return false;
				}else{
					if(this.gameDate.indexOf(date) > -1){
						return true;
					}else{
						return false;
					}
				}
			},
			// 判断是否是今天
			judgeNowDay(date){
				let date1 = new Date();
				let _date = date1.getFullYear() + "-" + ((date1.getMonth() + 1) > 9 ? (date1.getMonth() + 1) : "0" + (date1.getMonth() + 1)) + "-" + (date1.getDate() > 9 ? date1.getDate() : "0" + date1.getDate());
				if(_date == date){
					return true;
				}else{
					return false;
				}
			},
			// 判断闰平年
			judgeYear(year,month){
				if(year % 4 == 0 && year % 100 != 0){
					// 闰年
					return leapYeareMonth[month - 1];
				}else if(year % 400 == 0){
					// 闰年
					return leapYeareMonth[month - 1];
				}else{
					// 平年
					return commonYearMonth[month - 1];
				}
			},
			// 上一月
			prevMonth(){
				if(this.judgeBorder("prev")){
					return;
				}
				this.fadeDateType = "fadeDatePrev";
				let showDate = this.showDate.date[0] + "-" + this.showDate.date[1] + "-" + "01";
				let date = new Date(showDate);
				date.setMonth(date.getMonth() - 1, 1);
				this.showDefaultDate = date.getFullYear() + "-" + ((date.getMonth() + 1) > 9 ? (date.getMonth() + 1) : "0" + (date.getMonth() + 1)) + "-" + (date.getDate() > 9 ? date.getDate() : "0" + date.getDate());
				this.dealMonthDate();
			},
			// 下一月
			nextMonth(){
				if(this.judgeBorder("next")){
					return;
				}
				this.fadeDateType = "fadeDateNext";
				let showDate = this.showDate.date[0] + "-" + this.showDate.date[1] + "-" + "01";
				let date = new Date(showDate);
				date.setMonth(date.getMonth() + 1, 1);
				this.showDefaultDate = date.getFullYear() + "-" + ((date.getMonth() + 1) > 9 ? (date.getMonth() + 1) : "0" + (date.getMonth() + 1)) + "-" + (date.getDate() > 9 ? date.getDate() : "0" + date.getDate());
				this.dealMonthDate();
			},
			// 边界判断
			judgeBorder(ele){
				let borderYear = [this.minDate.split("-")[0],this.maxDate.split("-")[0]];
				let borderMonth = [this.minDate.split("-")[1],this.maxDate.split("-")[1]];
				let nowYear = this.showDate.date[0];
				let nowMonth = this.showDate.date[1];
				let monthFlag = 0;
				let returnFlag = true;
				if(ele == "prev"){
					// 上一月
					monthFlag = -1;
				}else{
					// 下一月
					monthFlag = 1;
				}
				// 设定时间 
				let date = new Date((nowYear + "-" + nowMonth + "-" + "01"));
				date.setMonth(date.getMonth() + monthFlag,"01");
				for(let i = 0; i < this.showYearMonth.length; i++){
					let item = this.showYearMonth[i];
					if(item.year == date.getFullYear()){
						let _month = date.getMonth() + 1 > 9 ? (date.getMonth() + 1) + "" : "0" + (date.getMonth() + 1);
						if(item.month.indexOf(_month) > -1){
							returnFlag = false;
							break;
						}
					}
				}
				return returnFlag;
			},
			// 点击选择年份、月份
			chooseYear(){
				this.fadeDateType = "";
				this.showMask = true;
				this.b_height = "5rem";
				this.calculateUlTop();
			},
			// 计算当前显示的ul top
			calculateUlTop(){
				for(let i = 0; i < this.showYearMonth.length; i++){
					if(this.showYearMonth[i].activeYear){
						this.b_top = 2 * 0.6 - i * 0.6;
						return;
					}
				}
			},
			// 年份上滑
			nextYear(){
				if(this.showYearMonth[this.showYearMonth.length - 1].year == Number(this.showDate.date[0])) return;
				this.fadeUlType = "fadeUlPrev";
				this.showDate.date[0] = Number(this.showDate.date[0]) + 1;
				this.amendActiveYear();
				this.calculateUlTop();
			},
			// 年份下滑
			prevYear(){
				if(this.showYearMonth[0].year == Number(this.showDate.date[0])) return;
				this.fadeUlType = "fadeUlNext";
				this.showDate.date[0] = Number(this.showDate.date[0]) - 1;
				this.amendActiveYear();
				this.calculateUlTop();
			},
			// 点击某一年
			dealClickYear(item){
				if(!item.activeYear) return;
				this.showDefaultDate = item.year + "-" + this.showDate.date[1] + "-" + this.showDate.date[2];
				this.dealMonthDate();
				// 关闭弹出框
				this.closeMask();
			},
			// 点击确认按钮
			okYear(){
				// 获取当前的activeYear
				console.log(this.showYearMonth)
				for(let i = 0; i < this.showYearMonth.length; i++){
					let item = this.showYearMonth[i];
					if(item.activeYear){
						this.dealClickYear(item);
						break;
					}
				}
			},
			// 处理点击某一天
			dealClick(date){
				// 传递当前日期给父组件
				this.$emit("clickDate",date);
			},
			// 关闭弹出框
			closeMask(){
				this.showMask = false;
				this.b_height = "0";
			},
			// 禁止滚动事件
			forbidScroll(isPin){
				if(isPin){
			        document.body.style.height = '100vh';
			        document.body.style['overflow-y'] = 'hidden';
			    }else{
			        document.body.style.height = 'unset';
			        document.body.style['overflow-y'] = 'auto';
			    }
			}
		},
		directives:{
			// 轻点
			"tap":{
				bind(el,binding,vnode){
					new vueTouch(el,binding,"tap",vnode);
				}
			},
			// 左滑
			"swipeleft":{
				bind(el,binding,vnode){
					new vueTouch(el,binding,"swipeleft",vnode);
				}
			},
			// 右滑
			"swiperight":{
				bind(el,binding,vnode){
					new vueTouch(el,binding,"swiperight",vnode);
				}
			},
			// 上滑
			"swipeup":{
				bind(el,binding,vnode){
					new vueTouch(el,binding,"swipeup",vnode);
				}
			},
			// 下滑
			"swipedown":{
				bind(el,binding,vnode){
					new vueTouch(el,binding,"swipedown",vnode);
				}
			}
		}
	}
</script>
(4) style
<style>
	.calendar{
		5.68rem;
		height:5.74rem;
		margin:0 auto;
		box-sizing:border-box;
		padding:0.18rem;
		overflow:hidden;
	}
	.calendar .calendar-year{
		5.32rem;
		height:0.68rem;
		line-height:0.68rem;
		text-align:center;
		font-size:0.32rem;
		color:#1e80d7;
	}
	.calendar .calendar-month{
		5.32rem;
		height:0.5rem;
		text-align:center;
		line-height:0.5rem;
		font-size:0.26rem;
		color:#1e80d7;
		overflow:hidden;
	}
	.calendar .calendar-month .month-left{
		0.76rem;
		height:0.5rem;
		float:left;
	}
	.calendar .calendar-month .month-center{
		3.8rem;
		height:0.5rem;
		float:left;
	}
	.calendar .month-center .month-content{
		position:relative;
		1rem;
		height:100%;
		margin:0 auto;
		text-align:center;
	}
	.calendar .month-content span{
		display:block;
		position:absolute;
		top:0;
		left:0;
		100%;
		height:100%;
	}
	.calendar .calendar-month .month-right{
		0.76rem;
		height:0.5rem;
		float:left;
	}
	.calendar .calendar-content{
		5.32rem;
		box-sizing:border-box;
		font-size:0.22rem;
	}
	.calendar .calendar-content .calendar-dayDate{
		position:relative;
		100%;
		height:3.6rem;
	}
	.calendar .calendar-content ul{
		100%;
		overflow:hidden;
	}
	.calendar .calendar-content .calendar-dayDate ul{
		position:absolute;
		100%;
		height:100%;
	}
	.calendar .calendar-content li{
		0.76rem;
		height:0.6rem;
		text-align:center;
		line-height:0.6rem;
		box-sizing:border-box;
		float:left;
	}
	.calendar .calendar-content li span{
		display:block;
		0.4rem;
		height:0.4rem;
		margin:0.1rem auto;
		line-height: 0.4rem;
		border-radius:50%;
		box-sizing:border-box;
	}
	.calendar .calendar-content .calendar-day{
		color:#1e80d7;
	}
	.calendar-date{
		color:#a8a8a8;
	}
	.calendar-now-month{
		color:#62676B;
	}
	.calendar-can-click span{
		border:1px solid #EBEBEB;
	}
	.calendar-can-click span.click-active{
		border:1px solid #1e80d7;
	}
	.isNowDay span{
		background:#1E80D7;
		color:#fff;
	}
	/*====日历动画====*/
	/*prevMonth*/
	.fadeDatePrev-enter-active,.fadeDatePrev-leave-active{
		transition: all .3s ease-in-out;
	}
	.fadeDatePrev-enter{
		transform: translateX(-3rem);
    	opacity: 0;
	}
	.fadeDatePrev-leave-active{
		transform: translateX(3rem);
    	opacity: 0;
	}
	/*nextMonth*/
	.fadeDateNext-enter-active,.fadeDateNext-leave-active{
		transition: all .3s ease-in-out;
	}
	.fadeDateNext-enter{
		transform: translateX(3rem);
    	opacity: 0;
	}
	.fadeDateNext-leave-active{
		transform: translateX(-3rem);
    	opacity: 0;
	}
	
	/*==== 弹出框 ====*/
	.calendar-mask{
		position:fixed;
		left:0;
		top:0;
		100%;
		height:100%;
		z-index:100;
		background:rgba(0,0,0,.25);
	}
	.calendar-box{
		position:fixed;
		left:0;
		bottom:0;
		100%;
		height:0;
		overflow:hidden;
		background:#fff;
		z-index:101;
		transition:height .5s ease;
	}
	.calendar-box .year-title{
		100%;
		height:0.78rem;
		background:#F9F9F9;
		overflow:hidden;
		box-shadow: 1px 1px 10px rgba(0,0,0,.2);
	}
	.calendar-box .year-title button{
		display:block;
		height:100%;
		1.1rem;
		text-align:center;
		line-height:0.8rem;
		font-size:0.24rem;
		background:rgba(0,0,0,0);
		outline:none;
	}
	.calendar-box .year-title .year-list-cancel{
		float:left;
	}
	.calendar-box .year-title .year-list-ok{
		float:right;
	}
	.year-list{
		position: relative;
		margin:0.6rem 0;
    	height: 3rem;
    	overflow:hidden;
	}
	.year-list .center-line{
	    position: absolute;
	    top: 50%;
	    left: 0;
	     100%;
	    margin-top: -0.3rem;
	    height: .6rem;
	    border-top: 1px solid #E6E6E6;
	    border-bottom: 1px solid #E6E6E6;
	    z-index:1;
	}
	.year-list .show-ul{
		100%;
		height:100%;
		position:relative;
		z-index:2;
	}
	.year-list ul{
		position: absolute;
	    top: 0;
	    left: 0;
	     100%;
	    text-align: center;
	    transition: all .5s ease;
	}
	.year-list li{
		100%;
		height: .6rem;
   		line-height: .6rem;
		font-size:0.25rem;
		color:#555;
	}
	.year-list li.active{
		font-size:0.28rem;
		color:#000;
	}
	.fadeUlPrev-enter-active,.fadeUlPrev-leave-active{
		transition: all .1s ease-in-out;
	}
	.fadeUlPrev-enter{
		opacity:0;
    	transform: translateY(0.6rem);
	}
	.fadeUlPrev-leave-active{
		opacity:0;
    	transform: translateY(-0.6rem);
	}
	.fadeUlNext-enter-active,.fadeUlNext-leave-active{
		transition: all .1s ease-in-out;
	}
	.fadeUlNext-enter{
		opacity:0;
    	transform: translateY(-0.6rem);
	}
	.fadeUlNext-leave-active{
		opacity:0;
    	transform: translateY(0.6rem);
	}
</style>
(5) rem.js
;(function(doc, win) {
	var docEl = doc.documentElement,
		resizeEvt = 'orientationchange' in window ? 'orientationchange' : 'resize',
		recalc = function() {
			var clientWidth = docEl.clientWidth;
			if(!clientWidth) return;
			docEl.style.fontSize = 100 * (clientWidth / 640) + 'px';
			console.log(docEl.style.fontSize)
		};
	if(!doc.addEventListener) return;
	win.addEventListener(resizeEvt, recalc, false);
	doc.addEventListener('DOMContentLoaded', recalc, false);
})(document, window);

自用,持续更新中...

原文地址:https://www.cnblogs.com/ylp0617/p/9233089.html