美文网首页Vue前端开发
vue 写一个日历组件

vue 写一个日历组件

作者: 果粒橙没有粒 | 来源:发表于2019-07-23 15:42 被阅读115次

    之前自己写了一个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'

    0

    记得删除app.vue里的logo

    1

    然后新建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,实现日历组件的样式

    仿照其他日历组件的样式:

    2

    我自己写的样式附代码

    3

    <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;

    }

    最后的日历组件完成了:

    3

    附上项目地址:https://gitee.com/cheng1225/calender

    相关文章

      网友评论

        本文标题:vue 写一个日历组件

        本文链接:https://www.haomeiwen.com/subject/fxtolctx.html