广告
返回顶部
首页 > 资讯 > 精选 >Vue如何实现移动端日历
  • 365
分享到

Vue如何实现移动端日历

2023-07-05 22:07:48 365人浏览 泡泡鱼
摘要

本篇内容介绍了“Vue如何实现移动端日历”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!先看看UI给的设计图和,需求是有数据的日期做标记,可以

本篇内容介绍了“Vue如何实现移动端日历”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!

先看看UI给的设计图和,需求是有数据的日期做标记,可以查看某一周/某一月的数据,周数据不用自定义,就按照日历上的周数据截取.

Vue如何实现移动端日历

实现效果

Vue如何实现移动端日历

规划dom部分区块划分

Vue如何实现移动端日历

页面实现

选择月份和选择年份与日期做了条件渲染,切换方式是点击顶部时间切换选项

<template>  <div class="calendar">    <div class="date-top">      <div class="left" @click="dateOperate('down')">        <div></div>      </div>      <div class="time" @click="selectDate">{{ date.join("/") }}</div>      <div class="right" @click="dateOperate('up')">        <div></div>      </div>    </div>    <!-- 日期列表 -->    <div class="date-list" v-if="show === 'date'">      <div class="date-content">        <!-- 日历头 -->        <div v-for="item in header" :key="item">          {{ item }}        </div>        <!-- 日列表 -->        <div          v-for="(s, k) in dayList"          :class="[            'date-item',            s.month !== date[1] ? 'other-day' : '',            s.day === date[2] && s.month === date[1] ? 'today' : '',          ]"          :key="s + '-' + k"          @click="selectDay(s)"        >          {{ s.day }}          <div            :class="[              'check',              haveList.includes(`${s.year}-${s.month}-${s.day}`) ? 'have' : '',            ]"          ></div>        </div>      </div>      <!-- 操作栏 -->      <div class="date-btn">        <div          class="btn-item"          v-for="k in weeks + 1"          :key="k"          @click="weekReport(k)"        >          {{ k === 1 ? "" : "看周报" }}        </div>      </div>    </div>    <!-- 月份列表 -->    <div class="month-list" v-else-if="show === 'month'">      <div        :class="date[1] == i ? 'month-item active' : 'month-item'"        v-for="i in 12"        :key="i"        @click="selectMonth(i)"      >        {{ i }}月      </div>    </div>    <!-- 年份列表 -->    <div      class="year-list"      v-else      @touchmove="touchMove"      @touchstart="touchStart"    >      <div        :class="date[0] === i ? 'month-item active' : 'month-item'"        v-for="i in yearList"        :key="i"        @click="selectYear(i)"      >        {{ i }}      </div>    </div>    <!-- 底部操作栏 -->    <div class="date-bottom">      <div class="b-left">        <div class="tab"></div>        <div class="totip">代表有睡眠报告</div>      </div>      <div class="b-right">        <div class="cancel" @click="cancel">取消</div>        <div class="m-report" @click="changeReport">看月报</div>      </div>    </div>  </div></template>

CSS部分

<style lang="scss" scoped>.calendar {  width: 100%;  background-color: #fff;  .date-top {    width: 100%;    padding: 20px;    display: flex;    justify-content: space-around;    align-items: center;    .left,    .right {      width: 100px;      height: 100%;      display: flex;      flex-direction: column;      justify-content: center;      align-items: center;      div {        width: 20px;        height: 20px;        background-color: #00b7ae;      }    }    .left > div {      clip-path: polyGon(0% 50%, 100% 0%, 100% 100%);    }    .right > div {      clip-path: polygon(0% 0%, 100% 50%, 0% 100%);    }    .time {      font-size: 38px;      font-weight: 500;      color: #333333;    }  }  .date-list,  .year-list,  .month-list {    width: 100%;    padding: 30px;    height: 540px;  }  .month-list,  .year-list {    display: grid;    grid-template-columns: 1fr 1fr 1fr;    grid-template-rows: auto;    .month-item {      text-align: center;      display: flex;      justify-content: center;      align-items: center;      font-size: 30px;      height: 122px;    }    .month-item:active {      background-color: #eee;    }    .active {      background-color: #dcf4f3;    }  }  .date-list {    padding-top: 0;    display: flex;    .date-content {      flex: 1;      height: 100%;      display: grid;      grid-template-columns: 1fr 1fr 1fr 1fr 1fr 1fr 1fr;      grid-template-rows: auto;      grid-gap: 20px 20px;      div {        height: 100%;        display: flex;        flex-direction: column;        justify-content: center;        align-items: center;        border-radius: 10px;      }      .other-day {        color: rgba($color: #363636, $alpha: 0.6) !important;      }      .today {        background-color: #dcf4f3;      }      .date-item {        font-size: 28px;        font-weight: 400;        color: #363636;        .check {          width: 10px;          height: 10px;          margin-top: 6px;          border-radius: 50%;          background-color: #00b7ae;          opacity: 0;        }        .have {          opacity: 1;        }      }    }    .date-btn {      height: 100%;      width: 80px;      font-size: 22px;      color: #4eb9f5;      display: grid;      grid-template-columns: 1fr;      grid-template-rows: auto;      grid-gap: 20px 20px;      margin-left: 20px;      .btn-item {        display: flex;        justify-content: center;        align-items: center;        height: 100%;      }    }  }  .date-bottom {    width: calc(100% - 80px);    display: flex;    justify-content: space-between;    align-content: center;    padding: 20px;    margin: 0 auto;    border-top: 1px solid #eee;    .b-left,    .b-right {      display: flex;      align-items: center;    }    .b-left {      .tab {        width: 27px;        height: 26px;        background: #dcf4f3;        border-radius: 13px;      }      .totip {        font-size: 24px;        font-weight: 400;        color: #363636;        margin-left: 20px;      }    }    .b-right {      .cancel {        font-size: 26px;        font-weight: 500;        color: rgba($color: #000000, $alpha: 0.5);      }      .m-report {        width: 195px;        line-height: 70px;        color: #fff;        font-size: 26px;        background: linear-gradient(196deg, #50dcdc, #18b6b7);        border-radius: 20px;        margin-left: 50px;        text-align: center;      }    }  }}</style>

接下来是逻辑处理部分 日数据的显示一共42条数据,先获取当前月的总天数,将每个月的天数保存在一个数组里,然后根据传入的参数返回相应的天数, 因为有闰年的存在,2月会是29天,所以做了闰年的判断.然后获取每周的第一天是周几,使用new Date().getDay()获取某一天是周几,返回的是0-7,这里为了方便使用将日历表头用数组保存起来返回的数字刚好是日里头对应的下标,然后根据第一天是周几计算出需要补上个月的几天数据,通过new Date(y,m,0)可以获取到上个月最后一天的,然后向日数据中添加上个月最后几天的数据,补充下个月开始的几天数据,直接使用42减去当月的天数和补充的上个月的天数得到的就是需要补充的下月天数.

月数据的切换显示,前后翻动切换年数据,每年固定都是12月所以就直接写固定值12然后v-for遍历生成dom

年数据的切换显示,每页显示12条数据,保存每页数据的第一条和最后一条用于前后翻页计算显示的数据+12或者-12.

校验选择的月份和已选择的日期是否匹配,因为选择日期后再切换月份有可能切换到的月份没有选择的日期如31日30日29日,所以需要验证是否正确,若是没有的话就当前月的最后一天.

手势操作没有写完整,只写了年份选择的滑动事件逻辑.

为了方便js部分的代码每行都有写详细的注释

自定月选择日期范围只需要修改日期点击事件的逻辑,新增一个参数判断是单日期选择还是选择一个日期范围,在事件处理里面记录点击的两个日期并计算中间的日期保存返回.

import { fORMatTime } from "@/utils/format";export default {  name: "calendar",  props: {    haveList: {      type: Array,      default: [],    },  },  data() {    return {      // 切换日期选择      show: "date",      // 日历头      header: ["日", "一", "二", "三", "四", "五", "六"],      // 选择日期      date: [],      // 年列表      yearList: [],      // 天列表      dayList: [],      // 定时器      timer: null,      // 手势操作数据      move: {        pageX: 0,        fNum: null,        lNum: null,      },      // 第一天是周几      weeks: 0,    };  },  created() {},  mounted() {    let time = new Date();    this.date.push(      time.getFullYear(),      formatTime(time.getMonth() + 1),      formatTime(time.getDate())    );    this.countDay();  },  methods: {    // 计算显示的天数据    countDay() {      console.log("chufa");      let [y, m, d] = this.date;      // 获取第一天是周几      let week = new Date(`${y}/${m}/1`).getDay(),        // 获取当前月的上个月多少天        lastDays = this.getDays(y, m - 1),        // 获取这个月有多少天        days = this.getDays(y, m);      // 计算这个月有多少周      this.weeks = Math.ceil((days - (7 - week)) / 7) + 1;      // 将当前月份的天数生成数组      this.dayList = Array.from({ length: this.getDays(y, m) }, (v, k) => {        return {          day: formatTime(k + 1),          month: m,          year: y,        };      });      // 将本月1日前的数据补齐      for (let i = lastDays; i > lastDays - week; i--) {        this.dayList.unshift({          day: i,          // 如果当前日期是1月补齐的是去年12月的数据          month: +m - 1 === 0 ? 12 : formatTime(+m - 1),          year: +m - 1 === 0 ? y - 1 : y,        });      }      // 计算需要补齐多少天      let length = this.weeks * 7 - this.dayList.length;      console.log("length", week, lastDays, days, this.weeks);      // 将本月最后一天的数据补齐      for (let i = 1; i <= length; i++) {        this.dayList.push({          day: i,          // 如果当前日期是12月补齐的是明年年1月的数据          month: +m + 1 > 12 ? 1 : formatTime(+m + 1),          year: +m + 1 > 12 ? y + 1 : y,        });      }      console.log(this.dayList);    },    // 顶部时间点击事件    selectDate() {      let type = {        month: "year",        date: "month",      };      // 判断点击事件选择月份还是年份      if (this.show !== "year") {        this.show = type[this.show];      }      // 如果是月份就计算dateList数据      if (this.show === "month") {        // 清空每页显示的年份数据        this.yearList.length = 0;        // 计算页面显示的年份数据 每页显示12条数据        for (let i = this.date[0] - 4; i <= this.date[0] + 7; i++) {          this.yearList.push(i);        }      }    },    // 屏幕点击事件    touchStart(val) {      // 获取按下屏幕的x轴坐标      this.move.pageX = val.touches[0].pageX;    },    // 左右滑动切换事件    touchMove(val) {      // 获取按下屏幕移动结束的x轴坐标      let move = val.touches[0].pageX;      clearTimeout(this.timer);      // 判断往左滑动还是往右滑动      // 滑动结束x轴坐标减去最初按下坐标为负数就是往左滑动,翻看当前日期以后的年份      if (move - this.move.pageX < -20) {        console.log("右滑", this.move.lNum);        // 定时器防抖        this.timer = setTimeout(this.changeYear("right"), 100);      }      // 滑动结束x轴坐标减去最初按下坐标为正数就是往右滑动,翻看当前日期以前的年份      if (move - this.move.pageX > 20) {        // 定时器防抖        this.timer = setTimeout(this.changeYear("left"), 100);      }    },    // 年份选择切换    changeYear(type) {      // 清空每页显示的年份数据      this.yearList.length = 0;      if (type === "right") {        // 计算页面显示的年份数据 每页显示12条数据        for (let i = this.move.lNum + 1; i < this.move.lNum + 13; i++) {          this.yearList.push(i);        }      } else {        for (let i = this.move.fNum - 12; i < this.move.fNum; i++) {          this.yearList.push(i);        }      }    },    // 年份点击事件    selectYear(val) {      this.date[0] = val;      this.show = "month";    },    // 月份点击事件    selectMonth(val) {      this.date[1] = val;      this.show = "date";      this.countDay();      this.checkDay();    },    // 校验选择的月份和已选择的日期是否匹配    checkDay() {      // 获取选择的年月有多少天 防止这年不是闰年 就将日期跳转到28号,或者有的月份没有31号就跳到30号      let num = this.getDays(this.date[0], this.date[1]);      if (num < this.date[2]) {        this.date.splice(2, 1, num);      }    },    // 日期点击事件    selectDay(val) {      let oVal = this.date[1];      this.date.splice(1, 2, val.month, val.day);      if (val.month !== oVal) {        this.countDay();      }      this.$emit("change", this.date.join("-"));    },    // 获取某个月有多少天    getDays(year, month) {      // 一年中每个月的天数      let days = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];      // 判断是不是闰年 2月29天      if (year % 4 === 0 && (year % 100 !== 0 || year % 400 === 0)) {        days[1] = 29;      }      return days[month - 1];    },    //左右按钮点击事件    dateOperate(type) {      let [y, m, d] = this.date;      // 如果是向后翻      if (type === "up") {        // 日期向后翻 切换月份        if (this.show === "date") {          if (+m === 12) {            this.date.splice(0, 1, y + 1);            this.date.splice(1, 1, "01");          } else {            this.date.splice(1, 1, formatTime(+m + 1));          }          // 月份向后翻 切换年份        } else if (this.show === "month") {          this.date.splice(0, 1, y + 1);          // 年份向后翻 重组数据        } else {          this.changeYear("right");        }        // 如果是前后翻      } else {        // 日期向前翻 切换月份        if (this.show === "date") {          if (+m === 1) {            this.date.splice(0, 1, y - 1);            this.date.splice(1, 1, 12);          } else {            this.date.splice(1, 1, formatTime(+m - 1));          }          // 月份向前翻 切换年份        } else if (this.show === "month") {          this.date.splice(0, 1, y - 1);          // 年份向前翻 重组数据        } else {          this.changeYear("left");        }      }      this.countDay();      this.checkDay();    },    // 右侧按钮点击事件    weekReport(i) {      if (i === 1) return;      let arr = [],        // 选择一周的数据 开始        s = 7 * (i - 1) - 7,        // 结束        e = 7 * (i - 1);      // 遍历日数据 截取选择的周数据      for (let k = s; k < e; k++) {        arr.push(          `${this.dayList[k].year}-${this.dayList[k].month}-${this.dayList[k].day}`        );      }      this.$emit("weekReport", arr);    },    // 看月报事件    changeReport() {      let [y, m, d] = this.date;      this.$emit("changeReport", `${y}-${m}`);    },    // 取消事件    cancel() {      this.$emit("cancel");    },  },  computed: {},  watch: {    yearList(nVal, oVal) {      // 记录每一页显示的数据第一位和最后一位 用于计算下一页或者上一页的数据      this.move.fNum = nVal[0];      this.move.lNum = nVal[11];    },    deep: true,    immediate: true,  },};

formatTime是给月份和日期小于10的前面加0的方法

“Vue如何实现移动端日历”的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识可以关注编程网网站,小编将为大家输出更多高质量的实用文章!

--结束END--

本文标题: Vue如何实现移动端日历

本文链接: https://www.lsjlt.com/news/356088.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • Vue如何实现移动端日历
    本篇内容介绍了“Vue如何实现移动端日历”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!先看看UI给的设计图和,需求是有数据的日期做标记,可以...
    99+
    2023-07-05
  • Vue实现移动端日历的示例代码
    工作中遇到一个需求是根据日历查看某一天/某一周/某一月的睡眠报告,但是找了好多日历组件都不是很符合需求,只好自己手写一个日历组件,顺便记录一下。 先看看UI给的设计图和,需求是有数据...
    99+
    2023-05-14
    Vue实现移动端日历 Vue实现日历 Vue日历
  • Vue如何实现日历
    这篇文章主要介绍了Vue如何实现日历,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。组件(component)是Vue最强大的功能之一。组件可...
    99+
    2022-10-19
  • 如何实现vue日历组件
    这篇文章主要介绍了如何实现vue日历组件,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。1. 前言最近做项目遇到一个需求,需要制作一个定制化的日历组件(项目使用的UI框架不能满...
    99+
    2023-06-29
  • js如何实现前端日历控件
    这篇文章主要介绍js如何实现前端日历控件,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!首先说下控件的依赖包,加载控件的时候必须先加载jQuery, jQuqery.UI, 另外jqu...
    99+
    2022-10-19
  • vue中如何实现移动端的scroll滚动
    这篇文章主要为大家展示了“vue中如何实现移动端的scroll滚动”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“vue中如何实现移动端的scroll滚动”这篇文...
    99+
    2022-10-19
  • vue2.0如何实现移动端滑动事件vue-touch
    这篇文章主要介绍vue2.0如何实现移动端滑动事件vue-touch,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!Vue-touch的使用有时候我们不止需要有返回键,也要有手势滑动切...
    99+
    2022-10-19
  • vue实现垂直无限滑动日历组件
    用vue做了一个垂直无限滑动日历,在这里记录一下实现。 效果 组件 verticalCalendar.vue <template>   <div ref="con...
    99+
    2022-11-13
  • vue实现移动端div拖动效果
    本文实例为大家分享了vue实现移动端div拖动的具体代码,供大家参考,具体内容如下 手机上会偶尔用到拖动div的效果,虽然我自己还没遇到,先写一个以防万一,需要注明的是,具体实现代码...
    99+
    2022-11-13
  • Angularjs如何实现日历
    这篇文章主要介绍了Angularjs如何实现日历,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。效果:Html:<div cl...
    99+
    2022-10-19
  • php如何实现日历
    这篇文章主要介绍“php如何实现日历”,在日常操作中,相信很多人在php如何实现日历问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”php如何实现日历”的疑惑有所帮助!接下来,请跟着小编一起来学习吧!php实现...
    99+
    2023-06-25
  • vue移动端实现手指滑动效果
    本文实例为大家分享了vue移动端实现手指滑动效果的具体代码,供大家参考,具体内容如下 滑动时候黄色块宽度跟着变化 通过touch点击实现 目前感觉宽度变化有点问题,还在思考中 下...
    99+
    2022-11-12
  • vue如何实现移动端拖拽悬浮按钮
    这篇文章主要讲解了“vue如何实现移动端拖拽悬浮按钮”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“vue如何实现移动端拖拽悬浮按钮”吧!功能介绍:在移动端开发中,实现悬浮按钮在侧边显示,为不...
    99+
    2023-07-02
  • 移动端如何实现内滚动
    这篇文章主要为大家展示了“移动端如何实现内滚动”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“移动端如何实现内滚动”这篇文章吧。发现需求如果在一个区域内只允许部分区域产生滚动的效果,而其余部分不能...
    99+
    2023-06-08
  • vue怎么实现垂直无限滑动日历组件
    这篇文章主要介绍“vue怎么实现垂直无限滑动日历组件”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“vue怎么实现垂直无限滑动日历组件”文章能帮助大家解决问题。效果组件verticalCalendar...
    99+
    2023-06-30
  • 如何在web端实现一个有日历的报表
    如何在web端实现一个有日历的报表,很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。简单要一个日历控件来选择日期查询,可以直接用报表工具自带的控件或者也有一些开源的...
    99+
    2023-06-03
  • vue实现移动端touch拖拽排序
    目录功能介绍:大致需求:整体思路:简单效果展示:具体实现:一、display:flex+v-for布局:二、touch事件绑定:三、卡片移动:四、获取手指所在位置:五、操作数组(删除...
    99+
    2022-09-27
  • vue实现移动端的开关按钮
    本文实例为大家分享了vue实现移动端的开关按钮的具体代码,供大家参考,具体内容如下 逻辑: 1.写一个椭圆形的div 2.动态改变这个椭圆形的div的背景颜色 3.写一个圆点,这个圆...
    99+
    2022-11-13
  • vue实现移动端多格输入框
    近来公司提出需求,完成如下图h5页面操作。 网上没什么轮子可以使用,就自己徒手撸了一个。不多废话,直接上代码。 <div class="verify-tel"> ...
    99+
    2022-11-12
  • vue怎么实现移动端div拖动效果
    本文小编为大家详细介绍“vue怎么实现移动端div拖动效果”,内容详细,步骤清晰,细节处理妥当,希望这篇“vue怎么实现移动端div拖动效果”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧。1、分享代码html代码&...
    99+
    2023-06-29
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作