使用vue实现日历组件的封装

前言

因项目的需要,而且当前组件库并不支持业务,所以,重新对日历组件进行封装。该篇博客就对实现日历的思路进行存档,方便以后的查阅。
先上图:UI小哥哥的原型图。接下来的思路都是根据该图进行解说

逻辑

  • 1.组件的拆分,分出哪些是业务,哪些是基础组件。
    整体来说,这就是在日历的基础上添加业务,所以日历组件应该是基础组件,而业务应该是通过插槽插入进去的。那么,右上方的分入分出合计以及每个日历中的分入,分出都是需要插入的。其余的均是日历本身的功能。
  • 2.那么接下来,我们先完成日历组件的封装,首先,我们要清楚,日历组件都需要完成哪些功能。功能如下
    • 确定每个月1号对应的是周几,需要上个月补充几天,以及下个月补充几天。
    • 当切换上个月,或者下个月的时候,日历面板能够重新渲染。
      emmm...好像就没啥了 ,重点就是日期的渲染,没有很大的逻辑问题。也不知道为啥当初看到这个组件的时候 就是不太愿意?

      实现步骤

  • 日历的头部渲染,即日历的周一-周日渲染出来。这里使用flex布局即可。
  • 日历的内容渲染,一个面板上应该是42个元素,包括上个月部分数据,当月整月数据,以及下个月部分数据。需要确定当月1号所在的位置,这样子,才能知道上个月以及下个月需要补充的天数,
    • 页面的还原
    <div class="calendar_main">
    <!-- {{test}} -->
    <!-- 星期一~星期日的展示头,列表渲染固定的7个block -->
    <div class="main_block-head">
    <div v-for="(column, col) in weekList" :key="col" class="weak-item">
      {{column.label}}
    </div>
    </div>
    <!-- 相应的月份的日期展示区域,列表渲染 -->
    <div class="main_block">
    <div v-for="(item, index) in totalDayList"
    :key="index"
    class="day-item"
    :class="item.className">
      <div  class="main-block_date" >
        <!-- 日期 -->
        {{item.day}}
      </div>
      <div>
        <template>
          <slot name="content" :data="item"></slot>
        </template>
      </div>
    </div>
    </div>
    </div>
    • 接下来定义每个月对应天数的数组,以及周一-周日日历头部的数组。
      props: {
      showYear: {
        type: Number,
        default: ''
      },
      showMonth: {
        type: Number,
        default: ''
      }
    },
      data() {
      return {
         // 定义每个月对应的天数的数组
          daysInMonth: [31, 28, 31,30 , 31, 30, 31,31, 30, 31, 30,31],
          // 星期的板块
          weekList:[{
            label: '周一',
            value: 1,
          }, {
            label: '周二',
            value: 2,
          }, {
            label: '周三',
            value: 3,
          }, {
            label: '周四',
            value: 4,
          }, {
            label: '周五',
            value: 5,
          },{
            label: '周六',
            value: 6,
          }, {
            label: '周日',
            value: 7,
          }]
      }
    
    • 下面就需要对日历面板的数组进行操作了。年,月是从父组件传入的,当年,月发生改变的时候,日历面板的数据也随之发生改变。所以,日历面板的list通过计算属性来进行其变更以及页面的渲染。
    totalDayList(val) {
       let list = [];
       // 定位找到选中月份初始的星期几
       let {showMonth, showYear, daysInMonth} = val;
       // 判断当前是否是闰年
       if(showYear%4 ===0 && showYear %100 === 0|| showYear%400 ===0) {
         this.daysInMonth[1] =29;
       };
       // 对月份赋值
       let month = showMonth;
       // 对年份赋值
       let year = showYear;
       // 将日期进行拼接,拼接成每月1号的数据
       let dateValue = year + '-' + month + '-' + '1';
       // 确定当前日期在周几-0代表的是周日,1代表的是周一。。。。
       let currentWeek = new Date(Date.parse(dateValue.replace(/-/g, '/'))).getDay();
       // 根据当前日期,判定需要在前面补充几个日期,在后面补充几个日期
       // 目的是补位:将前一个月的数据进行填充
       // 获取上一个月的天数
       let preList = this.preData(month, year,list, currentWeek, daysInMonth);
       // 将本月的数据进行渲染
       let currentList = this.currentData(daysInMonth, year,month, list);
       // 目的是补充后面的位置,保证当前面板的数据完整
       let nextList = this.nextData(list, year, month);
       list = [...nextList]
       return list
     }
    • 上个月的数据的渲染
    preData(month, year,list, currentWeek, daysInMonth) {
        // 获取上一个月,存在跨年的情况,当当前月份是1月份的时候,上个月是去年的12月
        let preMonth = month>1 ? month-1 :12;
        // 获取年份
        year = month>1?year:year-1;
        // 获取上个月的天数
        let preDays = daysInMonth[preMonth-1];
        // 存放的每周对应需要补的天数
        let fillNum = [6,0,1,2,3,4,5]
        // currentWeek=0,代表是周日,需要上个月补6天
        // currentWeek=1, 代表是周一,需要上个月补0天
        // currentWeek=2, 代表是周二,需要上个月补1天
        // currentWeek=3. 代表是周三,需要上个月补2天
        // currentWeek=4, 代表是周四,需要上个月补3天
        // currentWeek=5, 代表是周五,需要上个月补4天
        // currentWeek=6, 代表是周六,需要上个月补5天
        for(let i = preDays; i>preDays-fillNum[currentWeek]; i--) {
          let obj = {
            type: 'prev',
            year,
            month: preMonth,
            day:i,
            className: 'pre_day'
          }
          list.push(obj);
        }
        list =list.reverse();
        return list;
      },
    • 当月的数据渲染
    currentData(daysInMonth, year,month, list ) {
         // 将本月的数据进行渲染
        for(let i=0; i<daysInMonth[month-1];i++) {
          let obj = {
            year,
            day:i+1,
            type: 'current',
            className: 'current_day',
            month,
          }
          list.push(obj)
        }
        return list;
      },
    • 下个月的数据渲染
    nextData(list, year, month) {
        // 该日历面板又42个模块
        let nextNum = 42-list.length;
        if(nextNum>0) {
          for(let i=0; i<nextNum;i++) {
            let obj = {
              year,
              day: i+1,
              type: 'next',
              className: 'next_day',
              month: month+1
            }
            list.push(obj)
          }
        }
        return list
      }

    总结:

    日历的逻辑需要注意确定当月1号的位置,以及填充上个月,下个月的数据。记录一下 自己的逻辑思路。

原文地址:https://www.cnblogs.com/mn6364/p/12196969.html

时间: 2024-11-08 12:44:22

使用vue实现日历组件的封装的相关文章

Vue自定义日历组件

今天给大家介绍Vue的日历组件,可自定义样式.日历类型及支持扩展,可自定义事件回调.Props数据传输. 线上demo效果 示例 Template: <Calendar :sundayStart="true" :calendarType="1" :markDate="markDate" :markDateClass="markDateClass" :agoDayPrevent="agoDayPrevent&qu

vue初学实践之路——vue简单日历组件

---恢复内容开始--- 最近做的项目有一个需求,需要有一个日历组件供预定功能使用,之前的代码过于繁琐复杂,所以我采用vue重写了这个组件. npm.vue等等安装. 只是一个简单的日历组件,所以并不需要用到node服务器,只需要一个Html文件即可. 项目基本目录 首先在引入 vue.js <script src="https://unpkg.com/vue/dist/vue.js"></script> 贴上最主要的html和js代码 <div id=&

【vue】-----js组件的封装--------

在js组件网站上,查看那个组件好看就用,把他们结构和样式分别写在  组件文件内.loading.vue组件 做一下组件的测试/引用 运行的效果 封装完好的,js组件 loading  HTML和css样式 1 <template> 2 <div class="loader" v-if="flag"> 3 <div class="loader-inner"> 4 <div class="loade

vue2.0项目 calendar.js(日历组件封装)

最近一直闲来无事,便寻思着做一下自己的个人项目,也想说能使用现在比较流行的一些mvvm框架来做,于是就选用了这样的一个技术栈vue2.0+vue-router+vuex+webpack来做,做得也是多页面应用,使用vue-router,也是想说把多个功能模块化,单个模块spa,实现更高的效果.当然现在还在做的过程中,如果感兴趣可以过来star一下,哈哈,https://github.com/xiaobinwu/Wuji,git clone下来看看. 今天要说的是在做这个项目的过程中,自己想加一个

vue之手把手教你写日历组件

---恢复内容开始--- 1.日历组件 1.分析功能:日历基本功能,点击事件改变日期,样式的改变 1.结构分析:html 1.分为上下两个部分 2.上面分为左按钮,中间内容展示,右按钮 下面分为周几展示和日期展示 3.基本结构页面html书写 <template>    <div class="calender2">        <div class="date-header">            <div class

Vue.js说说组件

什么是组件:组件是Vue.js最强大的功能之一.组件可以扩展HTML元素,封装可重用的代码.在较高层面上,组件是自定义的元素,Vue.js的编译器为它添加特殊功能.在有些情况下,组件也可以是原生HTML元素的形式,以is特性扩展. 如何注册组件? 需要使用Vue.extend方法创建一个组件,然后使用Vue.component方法注册组件.Vue.extend方法格式如下: var MyComponent = Vue.extend({ // 选项...后面再介绍 }) 如果想要其他地方使用这个创

javascript动手写日历组件(2)——优化UI和添加交互(by vczero)

一.优化UI 继上一篇,http://www.cnblogs.com/vczero/p/js_ui_1.html.开始优化UI,主要优化的部分有: (1)增加星期行.(2)字体设置.(3)日期垂直居中.(4)将单元格->底部线条.(5)修改文本的颜色对比.(6)将内部调用的函数加前缀_,如_addHeader()._addWeekday(). 修改的后基本效果如下图: 整个代码做了小修小改: 1 var Calendar = function(div){ 2 this.div = documen

组件化封装开发Android App实战

详情请交流  QQ  709639943 01.组件化封装开发Android App实战 02.Kotlin系统入门与进阶 03.Node.js入门到企业Web开发中的应用 04.精通高级RxJava 2响应式编程思想 05.Java秒杀系统方案优化 高性能高并发实战 06.Java深入微服务原理改造房产销售平台 07.快速上手Linux 玩转典型应用 08.快速上手Ionic3 多平台开发企业级问答社区 09.Java Spring Security开发安全的REST服务 10.深入Java虚

Vue.js的组件化思想--上

Vue.js的组件化思想--上 一.Vue中的组件 Vue视图层的灵魂 -  组件化 组件(Component)是 Vue.js 最强大的功能之一: 组件可以扩展 HTML 元素,封装可重用的代码: 在较高层面上,组件是自定义元素, Vue.js 的编译器为它添加特殊功能.在有些情况下,组件也可以是原生 HTML 元素的形式,以 is 特性扩展. 二.全局组件的创建和注册  全局组件-步骤:1.创建组件Vue.extend(),指定组件的名称--2.注册组件Vue.component()--3.