使用APICloud AVM框架封装app日历组件

简介: AVM是APICloud推出的一个跨端的高性能 JavaScript框架,更趋近于原生的编程体验,它提供简洁的模型来分离应用的用户界面、业务逻辑和数据模型,适合高度定制化的项目。

实现的日历效果图


1.png


话不多说,上代码!


2.png


<template>
    <view class="page">
    <safe-area></safe-area>
    <view class="calendar-wrapper">
      <view class="calendar-toolbar">
        <text class="prev" onclick="prevMonth">〈</text>
        <text class="current">{{ currentDateStr }}</text>
        <text class="next" onclick="nextMonth">〉</text>
      </view>
      <view class="calendar-week">
        <text class="week-item" v-for="item of weekList" :key="item">{{ item }}</text>
      </view>
      <view class="calendar-inner">
        <text class="calendar-item" v-for="(item, index) of calendarList" :key="index" :class="this.changestyle(item.disable,item.value)"
        onclick="selDate" :data-val="item.value" :data-status="item.disable" :data-num="item.date">{{ item.date }}</text>
      </view>
    </view>
    </view>
</template>
<script>
  export default {
    name: 'calendar',
    installed(){
      this.setCurrent();
      this.calendarCreator();
    },
    data() {
      return{
        current:{}, 
        weekList:['周日','周一','周二','周三','周四','周五','周六'],
        shareDate: new Date(),
        calendarList: [],
        seldate:'点击选择日期',
        selweek:'待定',
      }
    },
    computed: {
      // 显示当前时间
      currentDateStr() {
        let { year, month } = this.current;
        return `${year}年${this.pad(month + 1)}月`;
      }
    },
    methods: {
      selDate (e){
        // console.log(JSON.stringify(e.currentTarget.dataset.val));
        let status = e.currentTarget.dataset.status;
        let num = e.currentTarget.dataset.num;
        if(status){
          this.data.seldate = e.currentTarget.dataset.val;
          this.getWeek();
          if(num>7){
            this.prevMonth();
          }
          else{
            this.nextMonth();
          }
        }
        else{
          this.data.seldate = e.currentTarget.dataset.val;
          this.getWeek();
          //重新加载一次日历 改变样式
          this.calendarCreator();
        }
        this.fire('clickDate', this.data.seldate);
      },
      changestyle(status,date){
        if(status){
          return 'calendar-item-disabled';
        }
        else{
          if(date == this.data.seldate){
            return 'calendar-item-checked';
          }
          else{
            return 'calendar-item';
          }
        }
      },
      // 判断当前月有多少天
      getDaysByMonth(year, month) {
        // console.log("本月多少天:"+new Date(year, month + 1, 0).getDate());
        return new Date(year, month + 1, 0).getDate();
      },
      getFirstDayByMonths(year, month) {
        // console.log("本月第一天周几:"+new Date(year, month, 1).getDay());
        return new Date(year, month, 1).getDay();
      },
      getLastDayByMonth(year, month) {
        // console.log("本月最后一天周几:"+new Date(year, month + 1, 0).getDay());
        return new Date(year, month + 1, 0).getDay();
      },
      // 对小于 10 的数字,前面补 0
      pad(str) {
        return str < 10 ? `0${str}` : str;
      },
      // 点击上一月
      prevMonth() {
        this.current.month--;
        // 因为 month的变化 会超出 0-11 的范围, 所以需要重新计算
        this.correctCurrent();
        // 生成新日期
        this.calendarCreator();
      },
      // 点击下一月
      nextMonth() {
        this.current.month++;
        // 因为 month的变化 会超出 0-11 的范围, 所以需要重新计算
        this.correctCurrent();
        // 生成新日期
        this.calendarCreator();
      },
      // 格式化时间,与主逻辑无关
      stringify(year, month, date) {
        let str = [year, this.pad(month + 1), this.pad(date)].join('-');
        return str;
      },
      // 设置或初始化 current
      setCurrent(d = new Date()) {
        let year = d.getFullYear();
        let month = d.getMonth();
        let date = d.getDate();
        this.current = {
            year,
            month,
            date
        }
      },
      // 修正 current
      correctCurrent() {
        let { year, month, date } = this.data.current;
        let maxDate = this.getDaysByMonth(year, month);
        // 预防其他月跳转到2月,2月最多只有29天,没有30-31
        date = Math.min(maxDate, date);
        let instance = new Date(year, month, date);
        this.setCurrent(instance);
      },
      // 生成日期
      calendarCreator() {
        // 一天有多少毫秒
        const oneDayMS = 24 * 60 * 60 * 1000;
        let list = [];
        let { year, month } = this.data.current;
        // 当前月份第一天是星期几, 0-6
        let firstDay = this.getFirstDayByMonths(year, month);
        // 填充多少天                         
        let prefixDaysLen = firstDay === 0 ? 7 : firstDay;
        // 毫秒数
        let begin = new Date(year, month, 1).getTime() - oneDayMS * prefixDaysLen;
        // 当前月份最后一天是星期几, 0-6
        let lastDay = this.getLastDayByMonth(year, month);
        // 填充多少天, 和星期的排放顺序有关
        let suffixDaysLen = lastDay === 0 ? 6 : 6 - lastDay;
        // 毫秒数
        let end = new Date(year, month + 1, 0).getTime() + oneDayMS * suffixDaysLen;
        while (begin <= end) {
            // 享元模式,避免重复 new Date
            this.data.shareDate.setTime(begin);
            let year = this.data.shareDate.getFullYear();
            let curMonth = this.data.shareDate.getMonth();
            let date = this.data.shareDate.getDate();
            list.push({
                year: year,
                month: curMonth,
                date: date,
                disable: curMonth !== month,
                value: this.stringify(year, curMonth, date)
            });
            begin += oneDayMS;
        }
        this.data.calendarList = list;      
        // console.log(JSON.stringify(this.data.calendarList));
      },
      //获取选中日期的周几
      getWeek(){
        let index =new Date(this.data.seldate).getDay();
        let weekArr = ['星期天', '星期一', '星期二', '星期三', '星期四', '星期五','星期六'];
        let week = weekArr[index];
        this.data.selweek = week;
      },
    }
  }
</script>
<style>
    .page {
        height: 100%;
    }
  .calendar-wrapper {
    margin: 10px 10px 0 10px;
    background-color:#3c40c6;
    border-top-left-radius: 10px;
    border-top-right-radius: 10px;
    max-height: 400px;
  }
  .calendar-toolbar {
    padding: 10px 10px;
    flex-flow: row nowrap;
    justify-content: space-between;
    align-items: center;    
    border-bottom: 1px solid #fff;
  }
  .prev{
    flex: 1;
    text-align: center;
    color: #fff;
  }
  .current {
    flex: 1;
    text-align: center;
    color: #fff;
  }
  .next{
    flex: 1;
    text-align: center;
    color: #fff;
  }
  .calendar-week {
    padding: 5px 10px;
    flex-flow: row nowrap;
    justify-content: space-around;
    align-items: center;
  }
  .week-item { 
    padding: 5px;
    font-weight: bolder;
    font-size: 12px;
    color: #fff;
  }
  .calendar-inner{
    padding: 10px 10px;
    flex-flow: row wrap;
    justify-content: space-around;
    align-items: center;
  }
  .calendar-item {
    width:14%;
    font-weight: bolder;
    text-align: center;
    font-size: 15px;
    color: #fff;
    padding: 5px;
    background-color: #3c40c6;
  }
  .calendar-item-disabled {
    width:14%;
    font-weight: bolder;
    text-align: center;
    font-size: 15px;
    color: #999;
  }
  .calendar-item-checked {
    width:14%;
    font-weight: bolder;
    text-align: center;
    font-size: 15px;
    color: #000000;
    background-color: #ffffff;
    border-radius: 5px;
  }
</style>

image.gif

其他页面引用

<template>
    <view class="page">
    <calendar onclickDate="getSelDate"></calendar>
    <view>
      <text>当前日期是</text>
      <text>{today}</text>
    </view>
    </view>
</template>
<script>
  import '../../components/calendar.stml'  
  export default {
    name: 'test',
    apiready(){
    },
    data() {
      return{
        today:''
      }
    },
    methods: {
      getSelDate(e){
        console.log(JSON.stringify(e));
        this.data.today = e.detail;
        api.toast({
          msg:'当前选中日期是:'+e.detail
        })
      }
    }
  }
</script>
<style>
    .page {
        height: 100%;
    }
</style>

image.gif

现在,APICloud 官方正在举办 AVM 组件的征集大赛,通过审核就能获得一定的奖金,大家感兴趣的也可以去围观一下。传送门:https://www.apicloud.com/activity2205

目录
打赏
0
0
0
0
0
分享
相关文章
鸿蒙NEXT时代你所不知道的全平台跨端框架:CMP、Kuikly、Lynx、uni-app x等
本篇基于当前各大活跃的跨端框架的现状,对比当前它们的情况和未来的可能,帮助你在选择框架时更好理解它们的特点和差异。
52 0
|
23天前
《仿盒马》app开发技术分享-- 积分页组件新增(64)
上一节我们创建了积分页,给页面添加了标题栏和积分展示的组件。这一节我们继续丰富积分页的内容,添加引导栏,积分明细展示等区域
63 0
【11】flutter进行了聊天页面的开发-增加了即时通讯聊天的整体页面和组件-切换-朋友-陌生人-vip开通详细页面-即时通讯sdk准备-直播sdk准备-即时通讯有无UI集成的区别介绍-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
【11】flutter进行了聊天页面的开发-增加了即时通讯聊天的整体页面和组件-切换-朋友-陌生人-vip开通详细页面-即时通讯sdk准备-直播sdk准备-即时通讯有无UI集成的区别介绍-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
298 90
【11】flutter进行了聊天页面的开发-增加了即时通讯聊天的整体页面和组件-切换-朋友-陌生人-vip开通详细页面-即时通讯sdk准备-直播sdk准备-即时通讯有无UI集成的区别介绍-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
【05】flutter完成注册页面完善样式bug-增加自定义可复用组件widgets-严格规划文件和目录结构-规范入口文件-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草央千澈
【05】flutter完成注册页面完善样式bug-增加自定义可复用组件widgets-严格规划文件和目录结构-规范入口文件-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草央千澈
194 75
【05】flutter完成注册页面完善样式bug-增加自定义可复用组件widgets-严格规划文件和目录结构-规范入口文件-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草央千澈
【一步步开发AI运动APP】四、使用相机组件抽帧
本文介绍了如何使用`ai-camera`组件开发AI运动APP,助力开发者深耕AI运动领域。`ai-camera`是专为AI运动场景设计的相机组件,支持多平台,提供更强的抽帧处理能力和API。文章详细讲解了获取相机上下文、执行抽帧操作以及将帧保存到相册的功能实现,并附有代码示例。无论是AI运动APP还是其他场景,该组件都能满足预览、拍照、抽帧等需求。下篇将聚焦人体识别检测,敬请期待!
仿第八区APP分发下载打包封装系统源码
该系统为仿第八区APP分发下载打包封装系统源码,支持安卓、iOS及EXE程序分发,自动判断并稳定安装。智能提取应用信息,自动生成PLIST文件和图标,提供合理的点数扣除机制。支持企业签名在线提交、专属下载页面生成、云端存储(阿里云、七牛云),并优化签名流程,支持中文包及合并分发,确保高效稳定的下载体验。 [点击查看源码](https://download.csdn.net/download/huayula/90463452)
272 22
MNN-LLM App:在手机上离线运行大模型,阿里巴巴开源基于 MNN-LLM 框架开发的手机 AI 助手应用
MNN-LLM App 是阿里巴巴基于 MNN-LLM 框架开发的 Android 应用,支持多模态交互、多种主流模型选择、离线运行及性能优化。
3574 22
MNN-LLM App:在手机上离线运行大模型,阿里巴巴开源基于 MNN-LLM 框架开发的手机 AI 助手应用
【07】flutter完成主页-完成底部菜单栏并且做自定义组件-完整短视频仿抖音上下滑动页面-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草央千澈
【07】flutter完成主页-完成底部菜单栏并且做自定义组件-完整短视频仿抖音上下滑动页面-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草央千澈
173 18
【07】flutter完成主页-完成底部菜单栏并且做自定义组件-完整短视频仿抖音上下滑动页面-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草央千澈
【入门思路】基于Python+Unittest+Appium+Excel+BeautifulReport的App/移动端UI自动化测试框架搭建思路
本文重点讲解如何搭建App自动化测试框架的思路,而非完整源码。主要内容包括实现目的、框架设计、环境依赖和框架的主要组成部分。适用于初学者,旨在帮助其快速掌握App自动化测试的基本技能。文中详细介绍了从需求分析到技术栈选择,再到具体模块的封装与实现,包括登录、截图、日志、测试报告和邮件服务等。同时提供了运行效果的展示,便于理解和实践。
413 4
【入门思路】基于Python+Unittest+Appium+Excel+BeautifulReport的App/移动端UI自动化测试框架搭建思路
uni-app开发微信小程序时vant组件van-tabs的使用陷阱及解决方案
uni-app开发微信小程序时vant组件van-tabs的使用陷阱及解决方案
615 1

热门文章

最新文章

AI助理

你好,我是AI助理

可以解答问题、推荐解决方案等