uniApp实现公农日历相互转换、公历、农历、阳历、阴历、calendar

news2024/12/23 17:49:35

文章目录

  • 效果图
  • 1、组件
    • 1.1、html部分
    • 1.2、JavaScript部分
    • 1.3、style部分
  • 2、使用组件
  • 3、总结


效果图

图1

图2


1、组件

1.1、html部分

<template>
    <view v-if="isCalendar" class="calendar_box">
        <view v-show="!isTime" class="btn_calendar_box">
            <view class="btn_box">
                <view class="cancel" @click="cancel">取消</view>
                <view class="tab_bar_box">
                    <view class="tab_bar_item" :class="[calendarType === 'solar' ? 'activation_tab_bar' : '']"
                        @click="tabBar('solar')">公历</view>
                    <view class="tab_bar_item" :class="[calendarType === 'lunar' ? 'activation_tab_bar' : '']"
                        @click="tabBar('lunar')">农历</view>
                </view>
                <view class="confirm" @click="confirm">确认</view>
            </view>

            <picker-view :indicator-style="indicatorStyle" :value="value" @change="bindChange"
                style="width:750upx; height: 400upx;">
                <picker-view-column>
                    <view class="picker_item" v-for="item in years" :key="item.id">{{ calendarType === 'solar' ?
                        item.lYear
                        : item.l_gz_Year }}
                    </view>
                </picker-view-column>

                <picker-view-column>
                    <view class="picker_item" v-for="item in months" :key="item.id">{{ calendarType === 'solar' ?
                        item.cMonth
                        : item.IMonthCn }}</view>
                </picker-view-column>

                <picker-view-column>
                    <view class="picker_item" v-for="item in days" :key="item.id">{{ calendarType === 'solar' ?
                        item.cDay
                        : item.IDayCn }}</view>
                </picker-view-column>

                <picker-view-column>
                    <view class="picker_item" v-for="item in hours" :key="item.id">{{ item.title }}</view>
                </picker-view-column>
                <picker-view-column>
                    <view class="picker_item" v-for="item in mins" :key="item.id">{{ item.title }}</view>
                </picker-view-column>
            </picker-view>
        </view>

        <view v-show="isTime" class="confirm_time_box">
            <view class="confirm_time_title">确认时间</view>
            <view class="input_time">请确认输入的时间是否正确</view>
            <view>
                <view class="value_box">
                    公(阳)历:{{ year.lYear }}{{ month.cMonth }}{{ day.cDay }}{{ hour.title }}{{ min.title }}
                </view>
                <view class="value_box">
                    农(阴)历:{{ year.gzYear }}{{ month.IMonthCn }}{{ day.IDayCn }}{{ hour.title }}{{ min.title }}
                </view>
            </view>

            <view class="back_correct_btn_box">
                <view class="back_edit" @click="backEdit">返回修改</view>
                <view class="correct" @click="alreadyCorrect">确认正确</view>
            </view>
        </view>
    </view>
</template>

1.2、JavaScript部分

需要在当前组件文件夹中下载安装js-calendar-converter模块,在uniApp中不支持使用全局node_modules。这也是uniApp不受欢迎的原因之一,但是项目开发需要也是没办法,总之就是能不用uniApp就不要用。
通过ref打开组件时,组件的生命周期不会被触发。无论是打开时或页面加载时,都不会触发生命周期,这也是uniApp的一个诟病。
alreadyCorrect此方法会返回最终的数据,数据分别有年、月、日、时和分,这些数据是对象类型,对象中包含公历和农历的值。birthdayVal字段返回拼接后的显示数据值,根据公历和农历返回对应值。


// solar2lunar 阳转阴
// lunar2solar 阴转阳
const res = require('js-calendar-converter');
let calendar = res.default;
export default {
    name: 'mjCalendar',
    data() {
        return {
            // lunar 阴历
            // solar 阳历
            calendarType: 'solar',
            value: [23, 4, 0, 16, 16],
            years: [],
            year: {},
            months: [],
            month: {},
            days: [],
            day: {},
            hours: [],
            hour: {},
            mins: [],
            min: {},
            indicatorStyle: undefined,
            dayIndex: 0,
            isTime: false,
            isCalendar: false,
            birthdayVal: ''
        }
    },
    // 页面加载或打开组件时
    // 此生命周期都不会被触发
    onLoad() {
        // this.indicatorStyle = `height: ${Math.round(uni.getSystemInfoSync().screenWidth / (750 / 80))}px;`;
        // this.init();
    },
    methods: {
        // 确认正确
        alreadyCorrect() {
            let year = this.year,
                month = this.month,
                day = this.day,
                hour = this.hour,
                min = this.min,
                birthdayVal = '';

            if (this.calendarType === 'solar') {
                birthdayVal += year.lYear;
                birthdayVal += month.cMonth;
                birthdayVal += day.cDay;
            } else {
                birthdayVal += year.gzYear;
                birthdayVal += month.IMonthCn;
                birthdayVal += day.IDayCn;
            }

            birthdayVal += hour.title;
            birthdayVal += min.title;

            this.birthdayVal = birthdayVal;
            this.isCalendar = false;
            this.isTime = false;

            this.$emit('backData', { year, month, day, hour, min, birthdayVal });
        },
        // 打开日期选择器
        openCalendar() {
            this.indicatorStyle = `height: ${Math.round(uni.getSystemInfoSync().screenWidth / (750 / 80))}px;`;
            this.init();
            this.isCalendar = true;
        },
        // 取消
        cancel() {
            this.isCalendar = false;
            this.birthdayVal = '';
        },
        // 返回修改
        backEdit() {
            this.isTime = false;
        },
        // 确认
        confirm() {
            this.isTime = true;
        },
        // 阴阳历转换
        tabBar(type) {
            this.calendarType = type;
        },
        // 滑动触发
        bindChange(event) {
            let valArr = event.detail.value;

            this.year = this.years[valArr[0]];

            if (this.calendarType === 'lunar') {
                let dayI = valArr[2],
                    isTB = dayI - this.dayIndex,
                    monI = valArr[1];

                if (isTB === 1 && this.days[dayI].IDayCn === '初一') valArr[1] = monI + 1;

                if (isTB === -1 && (['廿八', '廿九', '三十'].includes(this.days[dayI].IDayCn))) valArr[1] = monI - 1;

                this.value = valArr;
                this.dayIndex = dayI;
            }

            this.hour = this.hours[valArr[3]];
            this.min = this.mins[valArr[4]];

            // 根据年份生成月份数据
            this.getMonth(this.year.lYear, valArr[1], valArr[2]);
        },
        // 初始化
        init() {
            let years = [],
                hoursArr = ["未知时辰", "子", "丑", "丑", "寅", "寅", "卯", "卯", "辰", "辰", "巳", "巳", "午", "午", "未", "未", "申", "申", "酉", "酉", "戌", "戌", "亥", "亥", "子"],
                hours = [],
                mins = [],
                valArr = this.value;

            // 生成年份
            for (let i = 2000; i < 2025; i++) {
                let { lYear, gzYear } = calendar.solar2lunar(i, 5, 1);
                years.push({
                    id: `id${i}`,
                    lYear: lYear + '年',
                    gzYear: gzYear + '年',
                    l_gz_Year: lYear + gzYear + '年'
                });
            }
            this.years = years;
            this.year = this.years[valArr[0]];

            // 根据年份生成月份数据
            this.getMonth(this.year.lYear, valArr[1], valArr[2]);

            // 时辰数据
            for (let i = 0; i < 25; i++) {
                hours.push({
                    id: `id_${i + 1}`,
                    title: i !== 0 ? (i - 1) + hoursArr[i] : hoursArr[i],
                    value: i
                });
            }

            // 分钟数据
            for (let i = 0; i < 60; i++) {
                mins.push({
                    id: `id_${i + 1}`,
                    title: i + '分',
                    value: i
                });
            }

            this.hours = hours;
            this.mins = mins;
            this.hour = this.hours[valArr[3]];
            this.min = this.mins[valArr[4]];
        },
        // 日期
        getDay(year, month, i) {
            month = month.replace(/[^\d]/g, "");
            month = Number(month);

            let isZero = year % 4 === 0,
                len = [1, 3, 5, 7, 8, 10, 12].includes(month) ? 31 : [4, 6, 9, 11].includes(month) ? 30 : isZero ? 29 : 28,
                days = [];

            for (let i = 0; i < len; i++) {
                let { IDayCn, cDay } = calendar.solar2lunar(year, month, i + 1);

                days.push({
                    id: `id${i + 1}`,
                    IDayCn: IDayCn,
                    cDay: cDay + '日'
                });
            }
            this.days = days;
            this.day = this.days[i];
        },
        // 月份数据
        getMonth(year, i, j) {
            let months = [];
            for (let i = 0; i < 12; i++) {
                let { IMonthCn, cMonth } = calendar.solar2lunar(year, i + 1, 1);
                months.push({
                    id: `id${i + 1}`,
                    IMonthCn,
                    cMonth: cMonth + '月'
                });
            }
            this.months = months;
            this.month = this.months[i];
            // 根据年份和月份生成日期数据
            this.getDay(this.year.lYear, this.month.cMonth, j);
        }
    }
}

1.3、style部分

.calendar_box {
    position: fixed;
    left: 0;
    top: 0;
    width: 100vw;
    height: calc(100vh - 58px);
    display: flex;
    flex-direction: column-reverse;
    background-color: rgba(200, 200, 200, .8);
    z-index: 6;
}

.btn_calendar_box {
    background-color: #ffffff;
    padding-top: 12upx;
    padding-bottom: 12upx;
    z-index: 7;
}

.btn_box {
    padding: 8upx 16upx;
    display: flex;
    justify-content: space-between;
    align-items: center;
}

.tab_bar_box {
    display: flex;
    justify-content: space-between;
    align-items: center;
    border: 1upx solid rgb(201, 23, 35);
    border-radius: 10upx;
}

.tab_bar_item {
    height: 40upx;
    line-height: 40upx;
    padding: 10upx 30upx;
    color: rgb(201, 23, 35);
    cursor: pointer;
}

.activation_tab_bar {
    background: rgb(201, 23, 35);
    color: #FFFFFF;
}

.cancel {
    color: rgb(153, 153, 153);
    cursor: pointer;
    font-size: 32upx;
}

.confirm {
    color: rgb(201, 23, 35);
    cursor: pointer;
    font-size: 32upx;
}

.picker_item {
    height: 80upx;
    line-height: 80upx;
    text-align: center;
    font-size: 28upx;
}

/* ------------------------------- */
.confirm_time_box {
    background-color: #ffffff;
    padding-top: 12upx;
    padding-bottom: 12upx;
    z-index: 7;
}

.confirm_time_title {
    text-align: center;
    color: rgb(201, 23, 35);
    font-size: 32upx;
    border-bottom: 1upx solid #E8E8E8;
    height: 88upx;
    line-height: 88upx;
}

.input_time {
    text-align: center;
    font-size: 34upx;
    color: #000000;
    height: 48upx;
    line-height: 48upx;
    margin-top: 48upx;
    padding-bottom: 20upx;
}

.value_box {
    text-align: center;
    font-size: 34upx;
    color: rgb(163, 30, 26);
    height: 34upx;
    line-height: 34upx;
    padding: 10upx 0px;
}

.back_correct_btn_box {
    display: flex;
    justify-content: center;
    align-items: center;
    padding: 40upx 0;
    color: #ffffff;
}

.back_edit {
    padding: 20upx 40upx;
    border-radius: 10upx;
    background-color: #DDDDDD;
}

.correct {
    padding: 20upx 40upx;
    margin-left: 40upx;
    border-radius: 10upx;
    background-color: rgb(163, 30, 26);
}

2、使用组件

html部分

<view class="open_calendar">
	<text>生辰</text>
	<input class="input" :value="birthdayVal" placeholder="请选择生辰" disabled @click="openCalendar" />
</view>

<mj-calendar ref="refMjCalendar" @backData="backData"></mj-calendar>

style部分

.open_calendar {
	display: flex;
	justify-content: center;
	align-items: center;
	height: 90upx;
	line-height: 90upx;
}

.input {
	width: 390upx;
	margin-left: 12upx;
}

JavaScript部分

import mjCalendar from '@/components/mj-calendar/index';
export default {
	components: { mjCalendar },
	data() {
		return {
			birthdayVal: ''
		}
	},
	onLoad() { },
	methods: {
		// 接收返回数据
		backData(val) {
			this.birthdayVal = val.birthdayVal;
		},
		// 打开日期选择器
		openCalendar() {
			this.$refs.refMjCalendar.openCalendar();
		}
	}
}

3、总结

1、此组件的功能逻辑基本没啥大的毛病。
2、组件初始值未通过动态设置,目前写死。
3、组件处于农历选项时根据阳历创建数据,可能滑动时有些跳动,但不影响最终的结果,也不会报错。


后续会持续完善,敬请期待!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/503285.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Linux服务器使用supervisorctl命令部署Java服务详解

我们公司采用supervisorctl命令运行Java -jar包&#xff0c;觉得还是很方便的&#xff0c;此篇文章教你如何使用supervisorctl从零部署Java服务 安装jdk 首先肯定是下载安装Java的运行环境 jdk 下载地址&#xff1a;https://www.oracle.com/java/technologies/downloads/#jav…

WindowContainer相关类

WindowContainer类   从WindowContainer类的注释中可以看出该类中定义了一些公共的方法和属性给直接持有窗口的自己或者它的孩子使用&#xff0c;像RootWindowContainer、DisplayContent、DisplayArea、DisplayArea.Tokens、TaskDisplayArea、Task、ActivityRecord、WindowTok…

【话题讨论】-浅谈VR与AR

一、引言 随着ICT基础技术的发展&#xff0c;我们现在社会中的基础ict设施已经逐步完善&#xff0c;从而我们的社会也开始出现科幻片中才会有的场景&#xff0c;比如&#xff1a;我们可以构件一个虚拟3D沙盘。 还有我们熟悉的各类智能眼镜&#xff0c;已经进入到千家万户&…

干货 | Mendeley 的基础使用方法

Hello&#xff0c;大家好&#xff01; 这里是壹脑云科研圈&#xff0c;我是喵君姐姐~ 当阅读的文献越来越多&#xff0c;如何整理文献就成了一个大问题。文献管理软件则减轻了我们文献整理的负担。目前的文献管理软件使用较多的有Endnote、Notepress、Mendeley、Zotero等。 …

边无际首发ChatIoT:AI大模型从数字世界向物理世界迈进

将大模型的能力带到物理世界&#xff0c;除了微软、谷歌&#xff0c;还有一家中国的创业公司。边无际作为专注于物联网开发平台研发的科技公司&#xff0c;紧跟AI大模型带来的生产力变革&#xff0c;首发ChatIoT&#xff0c;率先将大模型的技术应用于物联网领域。 在微软、谷歌…

【高并发】网络模式

I/O 多路复用 多线程创建 服务器的主进程负责监听客户的连接&#xff0c;一旦与客户端连接完成&#xff0c;accept() 函数就会返回一个「已连接 Socket」&#xff0c;这时就通过 fork() 函数创建一个子进程&#xff0c;实际上就把父进程所有相关的东西都复制一份&#xff0c;…

多层感知器Multi-Layer Perception ,MLP

MLP神经网络的结构和原理 神经网络其实是对生物神经元的模拟和简化&#xff0c;生物神经元由树突、细胞体、轴突等部分组成。 生物神经元具有兴奋和抑制两种状态&#xff0c;当接受的刺激高于一定阈值时&#xff0c;则会进入兴奋状态并将神经冲动由轴突传出&#xff0c;反之则…

nginx配置文件nginx.conf的结构、各个指令(元素)的含义以及用法

nginx配置文件nginx.conf的结构、各个指令&#xff08;元素&#xff09;的含义以及用法 默认的nginx.confnginx.conf配置文件官方解释nginx.conf配置文件中每一条指令或指令快的含义是什么&#xff0c;以及用法&#xff08;使用范围&#xff1a;应该配置在什么地方&#xff09;…

今年的面试难度有点大....

大家好&#xff0c;最近有不少小伙伴在后台留言&#xff0c;又得准备面试了&#xff0c;不知道从何下手&#xff01; 不论是跳槽涨薪&#xff0c;还是学习提升&#xff01;先给自己定一个小目标&#xff0c;然后再朝着目标去努力就完事儿了&#xff01; 为了帮大家节约时间&a…

Selenium:利用select模块处理下拉框

目录 一、具体问题 二、解决方案 在UI自动化测试中&#xff0c;有时候会遇到页面元素无法定位的问题&#xff0c;包括xpath等方法都无法定位&#xff0c;是因为前端元素被设置为不可见导致。 这篇博客&#xff0c;介绍下如何通过JavaScript修改页面元素属性来定位的方法。。…

2021年科幻美剧和《人月神话》有啥渊源,书中有个小bug你知道吗

DDD领域驱动设计批评文集>> 《软件方法》强化自测题集>> 《软件方法》各章合集>> 《人月神话》1975版和1995版的封面是这样的&#xff1a; 图1 1975版“The Mythical Man-Month”封面 图2 1995版“The Mythical Man-Month”封面 书中第1章“焦油坑&…

【JS每N日一练】【自动化】gitcode创建子项目并导入git

▒ 目录 ▒ &#x1f6eb; 导读需求 1️⃣ 创建子项目手动操作编写代码 2️⃣ 导入github项目手动操作编写代码 &#x1f6ec; 文章小结&#x1f4d6; 参考资料 &#x1f6eb; 导读 需求 github访问时好时不好的&#xff0c;而且克隆代码及其麻烦&#xff0c;经常失败。所以小…

C语言 | 结构体

C语言 | 结构体 文章目录 C语言 | 结构体C语言结构体详解:1.实例&#xff08;多重嵌套&#xff09;1-1.定义1-2.初始化 2.结构体2-1、结构体2-1-1、结构体的类型定义&#xff1a;2-1-2、结构体变量的定义&#xff1a;2-1-3、结构体变量的初始化&#xff1a;2-1-4、使用&#xf…

【夜莺(Flashcat)V6监控】1初识夜莺:介绍及部署

简介 夜莺&#xff08; Nightingale &#xff09;是一款国产、开源云原生监控分析系统&#xff08;从 v6 版本开始&#xff0c;尝试转型成为统一观测平台&#xff09;&#xff0c;集数据采集、可视化、监控告警、数据分析于一体。于 2020 年 3 月 20 日&#xff0c;在 github …

这就是阿里巴巴月薪20K+测试岗的面试题吗?让我这个3年的测试工程师看的冷汗直流.....

朋友入职已经两周了&#xff0c;整体工作环境还是非常满意的&#xff01;所以这次特意抽空给我写出了这份面试题&#xff0c;而我把它分享给伙伴们&#xff0c;面试&入职的经验&#xff01; 大概是在2月中的时候他告诉我投递了阿里巴巴并且简历已通过&#xff0c;2月23经过…

NPM 包管理器简介

目录 npm 简介 包&#xff08;Packages&#xff09; 更新包 版本控制 运行任务 npm 简介 npm 是 Node.js 的标准包管理器。 npm 的快速指南&#xff0c;强大的包管理器是 Node.js 成功的关键。2017 年 1 月&#xff0c;超过 350000 个软件包被报告在 npm 注册表中列出&a…

java中的Servlet对象生命周期以及过滤器监听器

review: Servlet生命周期中的初始化方法&#xff1a; init() &#xff0c; init(config) public void init(ServletConfig config) throws ServletException { this.config config ; init(); } 因此&#xff0c;如果我们需要在初始化时执行一些自定义的操作&#xff0c;那么我…

简单易用又功能强大,来看看Postman接口测试工具怎么用?

一、Postman介绍 Postman官网上这样介绍它:"Manage all of your organizations APIs in Postman, with the industrys most complete API development environment."看的出来Postman是功能强大的API测试的工具 Postman 提供功能强大的 Web API 和 HTTP 请求的调试&a…

【C++】 类练习---封装链表、人物移动

目录 前言 正文 结构体和类的区别 练习1&#xff1a;封装链表 用类封装链表的注意事项 定义一个链表的节点结构 链表类代码 主函数 运行结果 练习2&#xff1a;人物移动 说明 头文件以及宏 人物类 主函数 运行结果 结语 前言 在学完了【C】 类基础汇总&#x…

Java多线程---线程的创建(Thread类的基本使用)

本文主要介绍Java多线程的相关知识, Thread的创建, 常用方法的介绍和使用, 线程状态等. 文章目录 前言 一. 线程和Thread类 1. 线程和Thread类 1.1 Thread类的构造方法 1.2 启用线程的相关方法 2. 创建第一个Java多线程程序 3. 使用Runnable对象创建线程 4. 使用内部类…