之前自己写了一个vue的日历demo,那时直接引入cdn的vue.js完成的,功能简单,样式简单,代码还写得乱起八糟,所有现在用vue-cli搭建一个vue项目来重新开发一次,vue--cli搭建vue开发环境可参考https://www.jianshu.com/p/3d44f8269b47
1,新建日历组件
引入reset.css,在assets里新建styles文件夹,将reset.css文件放在styles目录下。
在main.js文件里添加:import './assets/styles/reset.css'
记得删除app.vue里的logo
然后新建calender.vue。在router文件夹下的index.js改写路由
import Vue from 'vue'
import Router from 'vue-router'
import calender from '@/components/calender'
Vue.use(Router)
export default new Router({
routes: [
{
path: '/',
name: 'calender',
component: calender
}
]
})
calender.vue
<template>
<div class="calender">
<h5>开始开发</h5>
</div>
</template>
<script>
export default {
name: 'calender',
data () {
return {
}
}
}
</script>
<style scoped>
</style>
然后在:http://localhost:8081,下就可以看到项目效果
2,实现日历组件的样式
仿照其他日历组件的样式:
我自己写的样式附代码
<template>
<div class="calender">
<div class="top">
<div class="top_date">
2019年7月
</div>
<div class="btn_wrap">
<ul>
<li>
下个月
</li>
<li>
今天
</li>
<li>
上个月
</li>
</ul>
</div>
</div>
<div class="date_wrap">
<ul class="week">
<li>
一
</li>
<li>
二
</li>
<li>
三
</li>
<li>
四
</li>
<li>
五
</li>
<li>
六
</li>
<li>
日
</li>
</ul>
<ul class="day">
<li v-for="item in 42" :key=item>
{{item}}
</li>
</ul>
</div>
</div>
</template>
<script>
export default {
name: 'calender',
data () {
return {
}
}
}
</script>
<style scoped>
.calender{
width: 600px;
position: relative;
margin: 0 auto;
margin-top: 50px;
border: 1px solid #ddd;
padding: 20px;
}
.top{
width: 100%;
position: relative;
display: flex;
border-bottom: 1px solid #ddd;
padding-bottom: 20px;
}
.top_date{
width: 100px;
text-align: left;
line-height: 42px;
}
.btn_wrap{
flex: 1;
text-align: right
}
.btn_wrap ul{
display: flex;
flex-direction: row-reverse
}
.btn_wrap ul li{
padding: 10px 20px;
border: 1px solid #ddd;
font-size: 14px;
line-height: 20px;
cursor: pointer
}
.btn_wrap ul li:first-child{
border-left: none;
}
.btn_wrap ul li:last-child{
border-right: none;
}
.date_wrap{
position: relative;
}
.week{
display: flex;
flex-direction: row;
padding: 20px;
font-size: 16px;
}
.week li{
width: 14.28%;
}
.day{
display: flex;
flex-direction: row;
padding: 20px;
font-size: 16px;
flex-wrap: wrap;
}
.day li{
width: 14.28%;
padding: 20px;
box-sizing: border-box;
border: 1px solid #ddd
}
.day li:nth-child(n+8){
border-top:none;
}
.day li:nth-child(n+1){
border-right: none;
}
.day li:nth-child(7n){
border-right: 1px solid #ddd
}
</style>
3,逻辑和功能实现
得到当前date,获取年份,月份,日期,周几,控制选择日期,代码说明看注释
<template>
<div class="calender">
<div class="top">
<div class="top_date">
{{year}}年{{month}}月
</div>
<div class="btn_wrap">
<ul>
<li @click="handleShowNextMonth">
下个月
</li>
<li @click="handleShowToday">
今天
</li>
<li @click="handleShowLastMonth">
上个月
</li>
</ul>
</div>
</div>
<div class="date_wrap">
<ul class="week">
<li>
日
</li>
<li>
一
</li>
<li>
二
</li>
<li>
三
</li>
<li>
四
</li>
<li>
五
</li>
<li>
六
</li>
</ul>
<ul class="day">
<li v-for="(item,index) in days" :key=index>
{{item}}
</li>
</ul>
</div>
</div>
</template>
<script>
export default {
name: 'calender',
data () {
return {
year:'',
month:'',
days:[]
}
},
methods:{
//得到当前年这个月分有多少天
getDays(Y,M){
let day = new Date(Y, M, 0).getDate()
return day;
},
//得到当前年,这个月的一号是周几
getWeek(Y,M){
let now = new Date()
now.setFullYear(this.year)
now.setMonth(this.month-1)
now.setDate(1);
let week = now.getDay();
return week;
},
pushDays(){
//将这个月多少天加入数组days
for(let i = 1; i<=this.getDays(this.year,this.month);i++){
this.days.push(i)
}
//将下个月要显示的天数加入days
for(let i = 1;i<=42-this.getDays(this.year,this.month)-this.getWeek(this.year,this.month);i++){
this.days.push(i)
}
//将上个月要显示的天数加入days
for(let i=0;i<this.getWeek(this.year,this.month);i++){
var lastMonthDays=this.getDays(this.year,this.month-1)
this.days.unshift(lastMonthDays-i)
}s
console.log(this.days)
console.log(this.getWeek(this.year,this.month))
},
getDate(){
let now = new Date();
this.year = now.getFullYear();
this.month = now.getMonth()+1;
this.pushDays();
},
changeDate(){
},
handleShowNextMonth(){
this.days=[];
if(this.month<12){
this.month=this.month+1;
this.pushDays();
}else{
this.month= this.month=1;
this.year=this.year+1;
this.pushDays();
}
},
handleShowToday(){
this.days=[];
let now = new Date();
this.year=now.getFullYear();
this.month=now.getMonth()+1;
this.pushDays();
},
handleShowLastMonth(){
this.days=[];
if(this.month>1){
this.month=this.month-1;
this.pushDays();
}else if( this.year>1970){
this.month=12;
this.year=this.year-1;
this.pushDays();
}else{
alert("不能查找更远的日期")
}
}
},
mounted(){
this.getDate();
}
}
</script>
<style scoped>
.calender{
width: 600px;
position: relative;
margin: 0 auto;
margin-top: 50px;
border: 1px solid #ddd;
padding: 20px;
}
.top{
width: 100%;
position: relative;
display: flex;
border-bottom: 1px solid #ddd;
padding-bottom: 20px;
}
.top_date{
width: 100px;
text-align: left;
line-height: 42px;
}
.btn_wrap{
flex: 1;
text-align: right
}
.btn_wrap ul{
display: flex;
flex-direction: row-reverse
}
.btn_wrap ul li{
padding: 10px 20px;
border: 1px solid #ddd;
font-size: 14px;
line-height: 20px;
cursor: pointer
}
.btn_wrap ul li:first-child{
border-left: none;
}
.btn_wrap ul li:last-child{
border-right: none;
}
.date_wrap{
position: relative;
}
.week{
display: flex;
flex-direction: row;
padding: 20px;
font-size: 16px;
}
.week li{
width: 14.28%;
}
.day{
display: flex;
flex-direction: row;
padding: 20px;
font-size: 16px;
flex-wrap: wrap;
}
.day li{
width: 14.28%;
padding: 20px;
box-sizing: border-box;
border: 1px solid #ddd
}
.day li:nth-child(n+8){
border-top:none;
}
.day li:nth-child(n+1){
border-right: none;
}
.day li:nth-child(7n){
border-right: 1px solid #ddd
}
</style>
4,至此,一个日历组件基本完成,最后给当前日期加一个特殊样式
通过 :class="{now:nowLi==year.toString()+month.toString()+item}" 来判断是否是当前日期
nowLi是在methods方法中加以下方法实现,在mounted方法中就要使用该法方法。
//控制当前日期显示特殊样式
handleShowDateStyle(){
let now = new Date()
this.nowLi=now.getFullYear().toString()+(now.getMonth()+1).toString()+now.getDate().toString()
console.log(this.nowLi)
},
然后给now加css:
.now{
background: #f2f8fe;
color:#1989fa;
}
最后的日历组件完成了: