欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

vue日历/日程提醒/html5本地缓存

程序员文章站 2022-07-21 15:24:43
先上图 功能: 1、上拉日历折叠,展示周 2、左右滑动切换月 2、“今天”回到今天;“+”添加日程 3、localStorage存储日程 index,html

先上图

vue日历/日程提醒/html5本地缓存

 

功能:

1、上拉日历折叠,展示周

2、左右滑动切换月

2、“今天”回到今天;“+”添加日程

3、localstorage存储日程

 

index,html

<body>
  <div id="app" v-cloak @mousedown="down" @mouseup="heightchange">
    <!--日历-->
    <div id="calendar">
      <!-- 年份 月份 -->
      <div class="year-month">
        <span class="add" @click="eventadd">+</span>
        <span class="choose-yearmonth" >{{ currentyear }}-{{currentmonth}}</span>
        <span class="today" @click="backtoday">今天</span>
      </div>
      <div class="clear"></div>


      <!-- 星期 -->
      <ul class="weekdays">
        <li style="color:red">日</li>
        <li>一</li>
        <li>二</li>
        <li>三</li>
        <li>四</li>
        <li>五</li>
        <li style="color:red">六</li>
      </ul>


      <!-- 日期 -->
      <ul class="days" ref="daysbox">

        <!--展示月-->
        <li :style="{'display':showmonth==true?'block':'none'}" @touchstart="down" @touchend="move" v-for="day in days"> //移动端点击方法,可切换pc端点击方法,见下
          <!--非本月日期,灰色字体-->
          <span v-if="day.getmonth()+1 != currentmonth" class="other-month">{{ day.getdate() }}</span>

          <!--本月日期,正常显示-->
          <span v-else>
            <!--今天,特殊标示-->
            <span v-if="day.getfullyear() == new date().getfullyear() && day.getmonth() == new date().getmonth() && day.getdate() == new date().getdate()" class="active">{{ day.getdate() }}</span>

            <!--非今天,正常显示-->
            <span v-else>{{ day.getdate() }}</span>
          </span>
        </li>

        <!--展示周-->
        <li :style="{'display':showmonth==true?'none':'block'}" @mousedown="down" @mouseup="move_week" v-for="day in week_day"> //pc端点击方法,可切换移动端点击方法,见上
          <span v-if="day.getmonth()+1 != currentmonth" class="other-month">{{ day.getdate() }}</span>
          <span v-else>
            <!--今天-->
            <span v-if="day.getfullyear() == new date().getfullyear() && day.getmonth() == new date().getmonth() && day.getdate() == new date().getdate()" class="active">{{ day.getdate() }}</span>
            <span v-else>{{ day.getdate() }}</span>
          </span>
        </li>
        <li><i class="mui-icon mui-icon-arrowdown"></i></li>
     </ul>
  </div>

  <!-- 添加日程 -->
  <div id="content" v-if="show">
    <div class="nav">
      <span class="back" @click="eventadd_false">返回</span>
      <span class="finish" @click="eventadd_true(id)">完成</span>
    </div>
    <div class="mui-input-row">
      <input type="text" placeholder="日程内容" ref="eventname"/>
      <input type="text" placeholder="备注信息" ref="eventinfo"/>
      <input type="text" list="cars" placeholder="担任角色" ref="eventrole"/>
      <datalist id="cars">
        <option value="经办人">
        <option value="交办人">
        <option value="其他">
      </datalist>
      <input type="text" v-model="getremindtime" placeholder="设置提醒时间" @click="timeadd"/>
    </div>

    <div class="overlay" v-if="selecttime">
      <div id="curtain">
        <div class="icon-shell">
          <div class="icon-false" @click="settime_false">x</div>
          <div class="icon-true" @click="settime_true"></div>
        </div>
        <div class="clear"></div>
        <label >日
          <input type="number" v-model="currentday" min="0" />
        </label>
        <label >时
          <input type="number" v-model="currenthour" min="0" />
        </label>
        <label >分
          <input type="number" v-model="currentminute" min="0" />
        </label>
      </div>
    </div>
  </div>

  <!--选项卡-->
  <div id="box">
    <ul class="ul1">
      <li v-for="(item,index) in tabtit" v-bind:class="{active:index == num}" @click="tab(index)">
        {{item}}
      </li>
    </ul>
    <ul class="ul2">
      <li v-for="(main,index) in tabmain" v-show="index == num">
        <div v-for="(date,index) in main">
          <div class="clear"></div>
          <div>{{date.eventname}}</div> <div class="keep-right">{{date.eventtime}}</div>
          <div class="clear"></div>
          <div>{{date.eventinfo}}</div>
          <div class="clear"></div>
          <div>{{date.eventrole}}</div> <div class="keep-right" @click="select(index)">...</div>
          <div class="clear"></div>
          <div class="overlay" v-if="index==selectindex" @click="closediv"></div>
          <div v-if="index==selectindex" class="select-p">
            <p>修改</p>
            <p>...</p>
            <p>...</p>
            <p>...</p>
            <p>...</p>
          </div>
        </div>
      </li>
    </ul>
  </div>

  <!--mui框架下底部选项卡

  <nav class="mui-bar mui-bar-tab">
  <a class="mui-tab-item">
  <span class="mui-icon mui-icon-home"></span>
  <span class="mui-tab-label">工作</span>
  </a>
  <a class="mui-tab-item">
  <span class="mui-icon mui-icon-phone"></span>
  <span class="mui-tab-label">角色</span>
  </a>
  <a class="mui-tab-item">
  <span class="mui-icon mui-icon-email"></span>
  <span class="mui-tab-label">事项圈</span>
  <a class="mui-tab-item">
  <span class="mui-icon mui-icon-gear"></span>
  <span class="mui-tab-label">同事</span>
  </a>
  <a class="mui-tab-item mui-active">
  <span class="mui-icon mui-icon-gear"></span>
  <span class="mui-tab-label">日历</span>
  </a>
  </nav>-->
  </div>
</body>

style.css

* {
box-sizing: border-box;
margin:0;
padding:0;
list-style:none;
}
a{
text-decoration: none;
}
ul {
list-style-type: none;
}

body {
font-family: verdana, sans-serif;
background: #e8f0f3;
}
#calendar,#box{
width:100%;
margin: 0 auto;
box-shadow: 0 2px 2px 0 rgba(0,0,0,0.14), 0 3px 1px -2px rgba(0,0,0,0.1), 0 1px 5px 0 rgba(0,0,0,0.12);
}
[v-cloak] {
display:none;
}
.year-month {
position: fixed;
width: 100%;
height:50px;
padding: 15px 0px;
background: #262626;
}
.add{
width: 15%;
float: left;
text-align: center;
color: white;
}

.choose-yearmonth{
position: absolute;
width: 70%;
float: left;
text-align: center;
color: white;
}

.today{
width: 15%;
text-align: center;
float: right;
color: white;
}

.choose-month {
text-align: center;
font-size: 1rem;
}

.arrow {
padding: 30px;
}

.arrow:hover {
background: rgba(100, 2, 12, 0.1);
}

.month ul li {
color: white;
font-size: 20px;
text-transform: uppercase;
letter-spacing: 3px;
}

.weekdays {
padding-top:55px;
background-color: #ffffff;
display: flex;
flex-wrap: wrap;
color: #949494;
justify-content: space-around;
}
.weekdays2 {
width: 100%;
padding-top:55px;
background-color: #ffffff;
display: flex;
position: fixed;
flex-wrap: wrap;
color: #949494;
justify-content: space-around;
}
.weekdays li {
display: inline-block;
width: 13.6%;
text-align: center;
}
.weekdays2 li {
display: inline-block;
width: 13.6%;
text-align: center;
}

.days {
padding: 0;
background: #ffffff;
margin: 0;
display: flex;
flex-wrap: wrap;
justify-content: space-around;
}
.days2 {
width: 100%;
position: fixed;
padding: 0;
background: #ffffff;
margin: 0;
display: flex;
flex-wrap: wrap;
justify-content: space-around;
}

.days li {
list-style-type: none;
display: inline-block;
width: 14.2%;
text-align: center;
padding-bottom: 10px;
padding-top: 10px;
font-size: 1rem;
color: #000;
}

.days li .active {
padding: 6px 10px;
border-radius: 50%;
background: #00b8ec;
color: #fff;
}

.days li .other-month {
padding: 5px;
color: gainsboro;
}

.days li:hover {
background: #e1e1e1;
}
.li-hidden{
display:none;
}
.li-show{
display:block;
}
.ul1 {
overflow:hidden;

}
.ul1 li {
float:left;
margin:10px;
cursor:pointer;
width: calc(79%/3);
text-align: center;
}
.ul1 li:hover {
color:#00b8ec;
}
.ul2 {
width: 90%;
margin: 0 auto;
}
.ul2 li {
border:1px solid #ccc;
padding:10px;
width:100%;
height:1000px;
}
.keep-right{
float: right;
}
.select-p{
/* border: 1px solid black; */
line-height: 30px;
padding: 10px;
width: 50%;
position: absolute;
right: 6%;
background-color: white;
z-index: 3;
}
.select-p p:hover{
background-color: #e6e6fa;
}
.
.active {
color:#00b8ec;
}


/* 添加日程样式 */
#content{
height:80%;
position: absolute;
top: 0;
right: 10%;
bottom: 0;
left: 10%;
margin: auto;
background-color: wheat;
}
.nav{
width: 100%;
height:50px;
margin-bottom: 20px;
padding:20px;
}
.back{
width:15%;
height:30px;
line-height:30px;
text-align: center;
background-color: gray;
border-radius: 25px;
float: left;
color: white;
}
.finish{
width: 15%;
height:30px;
line-height:30px;
background-color: red;
border-radius: 25px;
text-align: center;
float: right;
color: white;
}
.overlay{
position:fixed;
width:100%;
height:100%;
top:0;
left:0;
background-color:rgba(0,0,0,0.2);
z-index:2;
}
#curtain{
width:80%;
position: absolute;
right: 10%;
left: 10%;
margin: auto;

background-color:#fff;
border-radius:2px;
box-shadow: 0 0 8px rgba(0,0,0,0.2);
position:fixed;
bottom: 10%;
text-align:center;
}
.icon-shell{
width:80%;
margin: 0 auto;
}
.icon-true{
float: right;
width: 20px;
height: 30px;
border-bottom: 3px solid #00b8ec;
border-right:3px solid #00b8ec;
margin: 10px auto;
transform: rotate(45deg);
-webkit-transform: rotate(45deg);
-moz-transform: rotate(45deg);
-ms-transform: rotate(45deg);
}
.icon-true:hover{
opacity: 0.5;
}
.icon-false{
float: left;
padding-top: 18px;
font-size: 1.8em;
color: red;
}
.icon-false:hover{
opacity: 0.5;
}
#curtain label{
text-transform: uppercase;
background-color: #f4f4f4;
width: 30%;
height: 40%;
font-size: 1em;
display: inline-block;
padding: 10px;
margin: 10% 0;
}

#curtain input{
display: block;
border: 0;
font: inherit;
font-size: 1em;
padding: 6px;
outline: none;
text-align: center;
width: 100%;
margin: 10px auto;
background-color:#fff;
}


.clear{
clear: both;
}

 

 time.js

new vue({
el: '#app',
data: {
//日历
currentyear: 2019,//
lockyear:2019,//返回当前年
currentmonth: 1,//
lockmonth:1,//返回当前月
currentday: 1,//
lockday:1,//返回当前日
setday:1,//取月份默认从一号开始取
currentweek: 2,//周几
setweek:1,
days: [],//每月天数
week_day:[],//每周天数
today_key:1,//取today所在week为第一个week_day
scroll:0,//滚动高度
dayscrolltop:0,//日历需要隐藏的高度
showmonth:true,//上下拉切换月和周

//日历滑动换月
startx:0,//触摸点
endx:0,//松开点
starty:0,
endy:0,

//添加提醒设置时间
currenthour:0,
currentminute:0,
getremindtime:null,
eventid:1,

//点击显示
show:false,
selecttime:false,

//选项卡
tabtit: ["已设置提醒", "创建时间", "最后发言时间"],
tabmain: [new array(), new array(), new array()],
num: 0,
selectindex:-1,
},
created() {
this.initdata(null);
},
watch: { //渲染完后,获取高度
days(){
this.$nexttick(function(){

/* console.log(this.$refs.daysbox.offsetheight,this.$refs.daysbox.offsettop); */
var daysboxheight=this.$refs.daysbox.offsetheight;
var daysboxhidden=daysboxheight/6*3;
var daystop=this.$refs.daysbox.offsettop;
this.dayscrolltop=daystop+daysboxhidden;
});
},
},
methods: {
initdata(cur) {
var date;
if (cur) {
date = new date(cur);
}
else {
date = new date();
this.lockyear = date.getfullyear();
this.lockmonth = date.getmonth()+1 < 10 ? '0'+(date.getmonth()+1) : date.getmonth()+1;
this.lockday = date.getdate() <10?'0'+date.getdate():date.getdate();
}

this.currentday = date.getdate() <10?'0'+date.getdate():date.getdate();//showmonth=false
this.currentweek = date.getday();
date.setdate(1);
this.currentyear = date.getfullyear();
this.currentmonth = date.getmonth()+1 < 10 ? '0'+(date.getmonth()+1) : date.getmonth()+1;
/*this.currentweek = date.getday(); // 1...6,0*/
this.setweek=date.getday();
this.currenthour = date.gethours() < 10 ? "0" + date.gethours() : date.gethours();
this.currentminute = date.getminutes() < 10 ? "0" + date.getminutes() : date.getminutes();
var str=this.formatdate(this.currentyear , this.currentmonth, this.currentday);
var set_str = this.formatdate(this.currentyear , this.currentmonth, 1);
/*console.log("today:" + str + "," + this.currentweek);*/
this.days.length = 0;
this.week_day.length=0;
// 默认1号,从一号开始计算,负数代表上个月天数,超过本月天数为下月天数
for (var i = this.setweek; i >= 0; i--) {
var d = new date(set_str);
d.setdate(d.getdate() - i);
/* console.log(d); */
this.days.push(d);
}
for (var i = 1; i <= 35 - this.setweek-1 ; i++) {
var d = new date(set_str);
d.setdate(d.getdate() + i);
/* console.log(d); */
this.days.push(d);
}
for (var i = this.currentweek; i >= 0; i--) {
var d = new date(str);
d.setdate(d.getdate() - i);
/* console.log(d); */
this.week_day.push(d);
}
for (var i = 1; i <= 7 - this.currentweek-1; i++) {
var d = new date(str);
d.setdate(d.getdate() + i);
/* console.log(d); */
this.week_day.push(d);
}
this.tabmain[0].length=0;
for(var i=0;i<localstorage.length-1;i++){
var key=localstorage.key(i);
var key_value=json.parse(localstorage.getitem(key));
/* console.log(key,key_value); */


this.tabmain[0].push(key_value);
/* console.log(this.tabmain[0].length); */
}


},

eventadd(){
this.show=true;
},
timeadd(){
this.selecttime=true;
},
backtoday(){
this.initdata(null);
},

pickpre(year=this.currentyear, month=this.currentmonth) {
// setdate(0); 上月最后一天
// setdate(35) date后35天,保证为下个月
var d = new date(this.formatdate(year , month , 1));
d.setdate(0);
/*console.log(d);*/
this.initdata(this.formatdate(d.getfullyear(),d.getmonth() + 1,1));
this.currentyear=d.getfullyear();
this.currentmonth=d.getmonth() + 1;
},
picknext(year=this.currentyear, month=this.currentmonth) {
var d = new date(this.formatdate(year , month , 1));
d.setdate(35);
/*console.log(d);*/
this.initdata(this.formatdate(d.getfullyear(),d.getmonth() + 1,1));
this.currentyear=d.getfullyear();
this.currentmonth=d.getmonth() + 1;
},
pickpre_week(year=this.currentyear, month=this.currentmonth,day=this.currentday) {
// setdate(0); 上月最后一天
// setdate(35) date后35天,保证为下个月
var d = new date(this.formatdate(year , month , day));
d.setdate(d.getdate()-7);
/*console.log(d);*/
this.initdata(this.formatdate(d.getfullyear(),d.getmonth() + 1,d.getdate()));
this.currentyear=d.getfullyear();
this.currentmonth=d.getmonth() + 1;
this.currentday=d.getdate();
},
picknext_week(year=this.currentyear, month=this.currentmonth,day=this.currentday) {
var d = new date(this.formatdate(year , month , day));
d.setdate(d.getdate()+7);
console.log(d);
this.initdata(this.formatdate(d.getfullyear(),d.getmonth()+1,d.getdate()));
this.currentyear=d.getfullyear();
this.currentmonth=d.getmonth()+1;
this.currentday=d.getdate();
console.log(this.currentyear,this.currentmonth,this.currentday);
},

down(event){
this.startx=event.clientx;
this.starty=event.clienty;
},
move(event){
this.endx=event.clientx;
if((this.startx-this.endx)>0){
console.log('zuohua');
this.picknext(this.currentyear, this.currentmonth);
}
if((this.startx-this.endx)<0){
this.pickpre(this.currentyear, this.currentmonth);
console.log('youhua');
}
/*alert('滑动成功');*/
},
move_week(event){

this.endx=event.clientx;
if((this.startx-this.endx)>0){
this.picknext_week(this.currentyear, this.currentmonth);
}
if((this.startx-this.endx)<0){
this.pickpre_week(this.currentyear, this.currentmonth);
}
},
heightchange(){
this.endy=event.clienty;
if(this.scroll>0){
this.showmonth=false;
this.scroll=0;
}
if(this.scroll<0){
this.showmonth=true;
}

},

// 返回 类似 yyyy-mm-dd 格式的字符串
formatdate(year,month,day){
var y = year;
var m = month;
if(m<10) {
m = "0" + m;
}
var d = day;
if(d<10) {
d = "0" + d;
}
return y+"-"+m+"-"+d
},

eventadd_false(){
this.show=false;
},
eventadd_true(id=this.eventid){
/* var id = localstorage.getitem(this.eventid); */
var name=this.$refs.eventname.value;
var info=this.$refs.eventinfo.value;
var role=this.$refs.eventrole.value;
var time=this.getremindtime;
if(name && info && role &&time){
var event={"eventname":name,"eventinfo":info,"eventrol":role,"eventtime":time}
localstorage.setitem(id,json.stringify(event));
/* console.log(localstorage.length); */
this.eventid++;
this.tabmain[0].push(event);
this.show=false;
/* alert('name'+':'+name +'info'+':'+info +'role'+':'+role +'time'+':'+time + '设置成功'); */
}
else{
alert('输入不能为空');
}
/* console.log(localstorage.getitem("eventid")); */
},

settime_false(){
this.selecttime=false;
},
settime_true(){
this.selecttime=false;
this.getremindtime=this.currentyear + "-" +this.currentmonth + "-" +this.currentday + " " +this.currenthour + ":" +this.currentminute + ":00";
},

tab(index) {
this.num = index;
},
select(index){
this.selectindex=index;
},
closediv(){

this.selectindex=-1;
},
menu() {
this.scroll = document.documentelement.scrolltop || document.body.scrolltop;

/* console.log(this.scroll,this.dayscrolltop); */


/* if (document.documentelement.scrolltop > 200) {
alert('页面高度大于200执行操作')
} else {
alert('页面高度xiao于200执行操作')
} */
/* console.log(document.getelementsbyclassname('days').offsetheight);
console.log(document.documentelement.scrolltop) */
/* console.log(this.$refs.elements.value); */
},
eventscroll(){
if(this.scroll-this.dayscrolltop>0){
var date = new date();
this.currentyear=date.getfullyear();
this.currentmonth = date.getmonth()+1 < 10 ? '0'+(date.getmonth()+1) : date.getmonth()+1;
this.currentweek=date.getday();
for (var i = this.currentweek; i >= 0; i--) {
date.setdate(date.getdate() - i);
/* console.log(d); */
this.week_day.push(date);
}
this.showmonth=false;
/* alert('ok'); */
}
else{

}
}
},//methods

mounted() {
window.addeventlistener('scroll', this.menu);
},

destroyed () {
window.removeeventlistener('scroll', this.menu)
},

});///new vue