基于quasar,只选择年度与月份的组件

news2025/1/24 22:38:49

为什么要做

quasar是个基于vue的强大的UI开发库,它提供了非常多的组件,比如日期选择。但是有些时候只需要选择到月份就可以了,quasar中没有,所以自己动手写了一个。因为对界面编程我不熟悉,所以,如果你有更好的想法,请不吝赐教。源码在gitcode、gitee、github的至简网格/企业服务上都有,以Apache License协议开源,gitcode连接如下:

assets/file/v3/components/month_input.js · master · 至简网格 / 企业服务 · GitCode

用法:

1)先引入

import MonthInput from "path_to_components/month_input.js"

2)再注册

组件中注册:components:{"month-input":MonthInput}

或全局注册:app.component('month-input', MonthInput);  app是使用Vue.createApp创建的。

3)最后使用

<month-input class="justify-center text-primary" min="-5" max="cur" @update:modelValue="f"></month-input>

属性

min、max、monthName(默认为“月”)

min、max接受以下几种格式:cur当前月份、-x当前年度减x年,+x当前年度加x年,yyyy/MM、yyyy-MM或yyyy.MM具体的月份;不设置则不限制。

update:modelValue触发回调时传递一个对象,其中包括{year:年份,month:月份(从1开始),num:年份*12+月份-1}

操作

没有点击时显示如下:

点击左右箭头前移一个月或后移一个月;点击中间的年/月,显示一个弹窗,在min、max指定范围之外的年月显示为灰色,如果选中的年份不在当前年份列表页中,月份全部显示灰色。点击左右箭头前移或后移12年。先选择年份,然后选择月份就可以了触发update:modelValue,同时隐藏弹窗。

源码

//月份选择组件month-input
export default{
data(){return {
    maxMonth:0,
    minMonth:0,
    year:'',
    month:'',
    num:0,//year*12+month-1
    startYear:0,
    years:[],
    months:[],
    old:{y:0,m:0}
}},
props: {
    modelValue:{type:String},
    min:{type:String,default:''}, //年份
    max:{type:String,default:''},
    monthName:{type:String, default:"月"}
},
emits: ['update:modelValue'],
created(){
    var m=this.parse(this.max,{y:9999,m:1});
    this.maxMonth=m.y*12+m.m-1;
    m=this.parse(this.min,{y:0,m:1});
    this.minMonth=m.y*12+m.m-1;
    var dt=new Date();
    m=this.parse(this.modelValue,{y:dt.getFullYear(),m:dt.getMonth()+1})
    this.old={year:m.y, month:m.m};
    this.year=m.y;
    this.month=m.m;
    this.num=this.year*12+this.month-1;
    this.startYear=this.year-4;
    this.set_array();
},
methods:{
set_array() {
    var month;
    var list=[];
    var chked=false;
    var v=this.startYear;
    var yMax=Math.floor(this.maxMonth/12);
    var yMin=Math.floor(this.minMonth/12);

    for(var i=0;i<4;i++) {
        var yy=[];
        for(var j=0;j<3;j++) {
            var y={v:v,cls:"col text-center"};
            if(v>yMax||v<yMin) {
                y.cls+=" text-grey";
            } else if(v==this.year) {
                y.cls+=" bg-primary text-white";
                chked=true;
            }
            yy.push(y);
            v++;
        }
        list.push(yy);
    }
    this.years=list;
    
    v=1;
    list=[];
    for(var i=0;i<4;i++) {
        var mm=[];
        for(var j=0;j<3;j++) {
            var m={v:v,cls:"col text-center"};
            if(chked) {//所选年份可见
                month=this.year*12+v-1;
                if(month>this.maxMonth||month<this.minMonth) {
                    m.cls+=" text-grey";
                } else if(v==this.month) {
                    m.cls+=" bg-primary text-white";
                }
            } else {
                m.cls+=" text-grey";
            }
            mm.push(m);
            v++;
        }
        list.push(mm);
    }    
    this.months=list;
},
parse(s,def) {
    if(!s) {
        return def;
    }
    var cfg=s.trim().toLowerCase();
    var dt=new Date();
    if(cfg=="cur") {
        return {y:dt.getFullYear(),m:dt.getMonth()+1};
    }
    if(cfg.startsWith('-')) {
        var v = parseInt(cfg.substring(1));
        return {y:dt.getFullYear()-v, m:1};
    }
    if(cfg.startsWith('+')) {
        var v = parseInt(cfg.substring(1));
        return {y:dt.getFullYear()+v, m:1};
    }
    var y,m;
    var p=cfg.indexOf('/');
    if(p<0)p=cfg.indexOf('-');
    if(p<0)p=cfg.indexOf('.');
    if(p>0) {
        y=parseInt(cfg.substring(0,p));
        m=parseInt(cfg.substring(p+1));
    } else {
        y=parseInt(cfg);
        m=1;
    }
    return {y:y,m:m};
},
pageUp() {
    this.startYear-=12;
    this.set_array();
},
pageDn() {
    this.startYear+=12;
    this.set_array();
},
fore(){
    if(this.num<=this.minMonth)return;
    
    this.month--;
    if(this.month==0) {
        this.year--;
        this.month=12;
    }
    this.num=this.year*12+this.month-1;
    this.old={year:this.year, month:this.month,num:this.num};
    this.$emit('update:modelValue', this.old);
},
next(){
    if(this.num>=this.maxMonth)return;
    this.month++;
    if(this.month>12) {
        this.year++;
        this.month=1;
    }
    this.num=this.year*12+this.month-1;
    this.old={year:this.year, month:this.month,num:this.num};
    this.$emit('update:modelValue', this.old);
},
set_year(v) {
    var yMax=Math.ceil(this.maxMonth/12);
    var yMin=Math.floor(this.minMonth/12);
    if(v>yMax||v<yMin) {
        return;
    }
    this.month=-1;
    this.year=v;
    this.set_array();
},
set_month(v) {
    if(this.year<this.startYear||this.year>=this.startYear+12) {
        return;//未选择年份
    }
    var m=v-1+this.year*12;
    if(m>this.maxMonth||m<this.minMonth) {
        return; //不在有效范围内
    }
    this.month=v;
    if(v!=this.old.month||this.year!=this.old.year) {
        this.num=this.year*12+this.month-1;
        this.old={year:this.year, month:this.month,num:this.num};
        this.$emit('update:modelValue',this.old);
    }
    this.$refs._my_dlg.hide();
}
},
computed: {
   value: {
      get() {return this.year+'/'+(this.month>9?this.month:('0'+this.month))},
      set(v) {
          var ym=this.parse(v);
          this.year=ym.y;
          this.month=ym.m;
          this.num=this.year*12+this.month-1;
      }
   }
},
template: `
<div class="row">
 <div class="rol q-pr-lg">
  <q-icon name="navigate_before" @click="fore"
   :class="num<=minMonth?'text-grey':''"></q-icon>
 </div>
 <div class="rol" style="cursor:pointer">
 {{year}} / {{month<10?('0'+month):month}}
 <q-popup-proxy cover @before-show="set_array" ref="_my_dlg">
  <div class="row q-pa-sm" style="min-width:20em;">
   <div class="col self-center">
    <q-icon name="navigate_before" @click="pageUp" size="2em" class="q-px-sm"></q-icon>
   </div>
   <div class="col-8">
    <div class="row" v-for="yy in years">
     <div v-for="y in yy" :class="y.cls" @click="set_year(y.v)"
      style="cursor:pointer">{{y.v}}</div>
    </div>
    <q-separator spaced="md"></q-separator>
    <div class="row" v-for="mm in months">
     <div v-for="m in mm" :class="m.cls" @click="set_month(m.v)"
     style="cursor:pointer">{{m.v}}{{monthName}}</div>
    </div>
   </div>
   <div class="col self-center">
    <q-icon name="navigate_next" @click="pageDn" size="2em" class="q-px-sm"></q-icon>
   </div>
  </div>
 </q-popup-proxy>
 </div>
 <div class="rol q-pl-lg">
  <q-icon name="navigate_next" @click="next"
  :class="num>=maxMonth?'text-grey':''"></q-icon>
 </div> 
</div>
`
}

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

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

相关文章

02-3.python入门基础一操作符与表达式

接上章 : 02-2.python入门语法一变量与数据类型2 本文将深入介绍Python中的各种操作符&#xff0c;包括算术操作符、比较操作符、逻辑操作符等&#xff0c;并详细讲解如何使用这些操作符构建表达式。通过丰富的示例与详细的讲解&#xff0c;帮助读者全面掌握这一重要的基础知识…

【自动化】Python SeleniumUtil 工具 开启开发者模式 自动安装油猴用户脚本等

【自动化】Python SeleniumUtil 工具 【Python】使用Selenium 操作浏览器 自动化测试 记录-CSDN博客文章浏览阅读58次。文章浏览阅读42次。【附件】Selenium chromedriver 驱动及浏览器下载。【附件】Selenium chromedriver 驱动及浏览器下载-CSDN博客。3.安装Chrome浏览器驱动…

COMSOL快捷键及内置函数

文章目录 COMSOL快捷键使用COMSOL算子求最大值和最小值COMSOL内置函数3.1 解析函数3.2 插值函数3.3 分段函数3.4 高斯脉冲函数3.5 斜坡函数3.6 矩形函数3.7 波形函数3.8 随机函数3.9 Matlab函数3.10 SWITCH函数 COMSOL快捷键 Ctrl&#xff0b;/ 可快速打开预定义的物理量列表。…

QT绘制同心扇形

void ChartForm::paintEvent(QPaintEvent *) {QPainter painter(this);painter.setRenderHint(QPainter::Antialiasing);// 设置抗锯齿painter.save();// 设置无边框&#xff08;不需要设置QPen&#xff0c;因为默认是不绘制边框的&#xff09;QPen pen(Qt::NoPen);// QPen pen…

最大质因子序列

最大质因子序列 C语言代码C 代码Java代码Python代码 &#x1f490;The Begin&#x1f490;点点关注&#xff0c;收藏不迷路&#x1f490; 任意输入两个正整数m, n (1 < m < n < 5000)&#xff0c;依次输出m到n之间每个数的最大质因子&#xff08;包括m和n&#xff1b;…

ubuntu22.04编译安装Opencv4.8.0+Opencv-contrib4.8.0教程

本章教程,主要记录在Ubuntu22.04版本系统上编译安装安装Opencv4.8.0+Opencv-contrib4.8.0的具体过程。 一、下载opencv和opencv-contrib包 wget https://github.com/opencv/opencv/archive/refs/tags/4.8.0.zip wget https://github.com/opencv/opencv_contrib/archive/refs/…

AI芯片常见概念

文章目录 AI芯片常见概念前言常见概念AI芯片分类按照芯片的技术架构分GPU半定制化的 FPGA全定制化 ASIC神经拟态芯片 按应用场景分训练卡推理卡 按部署位置分国产AI卡资料汇总 封装相关Chiplet技术3DIC三星多芯片集成联盟&#xff08;Samsung Multi-Die Integration Alliance&a…

Fiddler(抓包测试工具)下载安装步骤

目录 介绍 主要功能&#xff1a; 使用场景&#xff1a; 一、下载 二、安装 ​编辑三、测试 介绍 Fiddler 是一个强大的网络调试工具&#xff0c;用于捕获和分析 HTTP/HTTPS 请求与响应。它通过代理服务器捕获流量&#xff0c;帮助开发者调试 Web 应用、API&#xff0c;进…

Elasticsearch-DSL高级查询操作

一、禁用元数据和过滤数据 1、禁用元数据_source GET product/_search {"_source": false, "query": {"match_all": {}} }查询结果不显示元数据 禁用之前: {"took" : 0,"timed_out" : false,"_shards" : {&quo…

gorm源码解析(四):事务,预编译

文章目录 前言事务自己控制事务用 Transaction方法包装事务 预编译事务结合预编译总结 前言 前几篇文章介绍gorm的整体设计&#xff0c;增删改查的具体实现流程。本文将聚焦与事务和预编译部分 事务 自己控制事务 用gorm框架&#xff0c;可以自己控制事务的Begin&#xff0…

什么是双声道立体声环绕声全景声 | 一文讲清楚沉浸式声音基本设定

目录 一、 沉浸式声音基本概念1. 声学上的沉浸式2. 空间音频技术3. 声源位置4. 人耳声音定位&#xff08;水平&垂直方向&#xff09;5. 人耳对声源距离定位的影响因素6. 头部相关传递函数7. 三维声技术8. “双耳”与“立体声”9. 耳机重放与扬声器重放10. 环绕声11. 高度声…

使用C语言库函数格式化输入时格式类型与数据类型不匹配导致程序异常

问题 使用两次sscanf()库函数从两个字符串中按照指定的格式读取数据&#xff0c;执行完毕后发现第一个正常读取的数据被篡改。项目在Ubuntu上使用CMake和Ninja构建项目&#xff0c;编译时没有错误和警告。 复现 为方便调试&#xff0c;在keil中编译stm32工程代替&#xff0c…

车牌识别之三:检测+识别的onnx部署(免费下载高精度onnx模型)

依赖 paddle2onnx1.3.1 onnxruntime-gpu1.14.0 ultralytics8.3.38背景 在车牌识别之一&#xff1a;车牌检测(包含全部免费的数据集、源码和模型下载&#xff09;我们得到了车牌检测模型&#xff1b; 在车牌识别之二&#xff1a;车牌OCR识别(包含全部免费的数据集、源码和模型…

WPF ControlTemplate 控件模板

区别于 DataTemplate 数据模板&#xff0c;ControlTemplate 是控件模板&#xff0c;是为自定义控件的 Template 属性服务的&#xff0c;Template 属性类型就是 ControlTemplate。 演示&#xff0c; 自定义一个控件 MyControl&#xff0c;包含一个字符串类型的依赖属性。 pub…

在IDE中使用Git

我们在开发的时候肯定是经常使用IDE进行开发的&#xff0c;所以在IDE中使用Git也是非常常用的&#xff0c;接下来以IDEA为例&#xff0c;其他的VS code &#xff0c;Pycharm等IDE都是一样的。 在IDEA中配置Git 1.打开IDEA 2.点击setting 3.直接搜索git 如果已经安装了会自…

Excel中如何消除“长短款”

函数微调可以可以实施&#xff0c;简单且易于操作的气球&#x1f388;涨缩更妙。 (笔记模板由python脚本于2024年12月17日 06:19:13创建&#xff0c;本篇笔记适合用Excel操作数据的coder翻阅) 【学习的细节是欢悦的历程】 Python 官网&#xff1a;https://www.python.org/ Fre…

微命令 微指令 微程序 微操作

微命令是计算机控制部件通过控制线向执行部件发出的各种控制命令&#xff0c;它是构成控制序列的最小单位 微命令与微操作是一一对应的关系&#xff0c;微命令是微操作的控制信号&#xff0c;而微操作是微命令的执行过程。在机器的一个CPU周期中&#xff0c;一组实现一定操作功…

Spring 不推荐使用@Autowired

Spring 不推荐使用Autowired 原因&#xff1a;为什么 Spring和IDEA 都不推荐使用 Autowired 注解_autowired为什么不推荐-CSDN博客 解决方法&#xff1a; 使用Resource注解。 使用构造函数注入。缺点显而易见&#xff0c;当成员变量很多时&#xff0c;构造函数代码冗长&#…

6、AI测试辅助-测试报告编写(生成Bug分析柱状图)

AI测试辅助-测试报告编写&#xff08;生成Bug分析柱状图&#xff09; 一、测试报告1. 创建测试报告2. 报告补充优化2.1 Bug图表分析 3. 风险评估 总结 一、测试报告 测试报告内容应该包含&#xff1a; 1、测试结论 2、测试执行情况 3、测试bug结果分析 4、风险评估 5、改进措施…

使用re模块

一、常量 常量说明 re.M re.MULTLINE 多行模式 re.S re.DOTALL 单行模式 re.I re.IGNORECASE 忽略大小写 re.X re.VERBOSE 忽略表达式的空白字符 可以使用|开启多个选项 二、方法 2.1 编译 compile re.compile(pattern,[,falgs]) pattern是正则表达式的字符串 设定falgs&…