写点什么

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

作者:APICloud
  • 2022 年 4 月 06 日
  • 本文字数:5080 字

    阅读完需:约 17 分钟

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


实现的日历效果图



话不多说,上代码!



<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>
复制代码


其他页面引用

<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>
复制代码


发布于: 刚刚阅读数: 2
用户头像

APICloud

关注

一次编码多端运行,移动应用低代码开发平台 2020.12.22 加入

用友YonBuilder移动端低代码开发平台,快速构建高性能多端应用

评论

发布
暂无评论
使用APICloud AVM框架封装app日历组件_前端开发_APICloud_InfoQ写作平台