年至年的选择仿elementui的样式

news2024/11/25 18:42:15

在这里插入图片描述

组件:
<!--
 * @Author: liuyu liuyu@xizhengtech.com
 * @Date: 2023-02-01 16:57:27
 * @LastEditors: wangping wangping@xizhengtech.com
 * @LastEditTime: 2023-06-30 17:25:14
 * @Description: 时间选择年 --->
<template>
  <div class="yearPicker" ref="yearPicker" :width="width">
    <input class="_inner" ref="inputLeft" v-model="startShowYear" @focus="onFocus" @blur="onBlur" type="text" name="yearInput" @keyup="checkStartInput($event)" placeholder="开始年份" />
    <span>{{ sp }}</span>
    <input class="_inner" ref="inputRight" v-model="endShowYear" @focus="onFocus" @blur="onBlur" type="text" name="yearInput" @keyup="checkEndInput($event)" placeholder="结束年份" />
    <!-- <i class="dateIcon el-icon-date"></i> 按照自己标准库里面的图标设置-->
    <!-- <span class="_inner labelText"></span> -->
    <i class="_inner labelText el-icon-date"></i>
    <div class="_inner floatPanel" v-if="showPanel">
      <div class="_inner leftPanel">
        <div class="_inner panelHead">
          <i class="_inner el-icon-d-arrow-left" @click="onClickLeft"></i>
          {{ leftYearList[0] + " - " + leftYearList[9] }}
        </div>
        <div class="_inner panelContent">
          <div :class="{
              oneSelected: item === startYear && oneSelected,
              startSelected: item === startYear,
              endSelected: item === endYear,
              betweenSelected: item > startYear && item < endYear,
            }" v-for="item in leftYearList" :key="item">
            <a :class="{
                cell: true,
                _inner: true,
                selected: item === startYear || item === endYear,
              }" @click="onClickItem(item)" @mouseover="onHoverItem(item)">
              {{ item }}
            </a>
          </div>
        </div>
      </div>
      <div class="line"></div>
      <div class="_inner rightPanel">
        <div class="_inner panelHead">
          <i class="_inner el-icon-d-arrow-right" @click="onClickRight"></i>
          {{ rightYearList[0] + " - " + rightYearList[9] }}
        </div>
        <div class="_inner panelContent">
          <div :class="{
              startSelected: item === startYear,
              endSelected: item === endYear,
              betweenSelected: item > startYear && item < endYear,
            }" v-for="item in rightYearList" :key="item">
            <a :class="{
                cell: true,
                _inner: true,
                selected: item === endYear || item === startYear,
              }" @click="onClickItem(item)" @mouseover="onHoverItem(item)">
              {{ item }}
            </a>
          </div>
        </div>
      </div>
    </div>
  </div>
</template>
 
<script>
import moment from "moment";
const SELECT_STATE = {
  unselect: 0,
  selecting: 1,
  selected: 2,
};
export default {
  name: "yearPicker",
  computed: {
    oneSelected() {
      return (
        this.curState === SELECT_STATE.selecting &&
        (this.startYear === this.endYear || this.endYear == null)
      );
    },
    startDate() {
      return this.startYear;
    },
    leftYearList() {
      return this.yearList.slice(0, 10);
    },
    rightYearList() {
      return this.yearList.slice(10, 20);
    },
    startYearFormat() {
      if (this._.isNil(this.startYear)) {
        return null;
      }
      return moment(this.startYear).startOf("year").format("yyyy");
    },
    endYearFormat() {
      if (this._.isNil(this.endYear)) {
        return null;
      }
      return moment(this.endYear).endOf("year").format("yyyy");
    },
  },
  props: {
    width: {
      default: 200,
    },
    labelWidth: {
      default: 40,
    },
    sp: {
      default: "至",
    },
    initYear: {
      default: null,
    },
  },
  data() {
    return {
      itemBg: {},
      startShowYear: null,
      endShowYear: null,
      yearList: [],
      showPanel: false,
      startYear: null,
      endYear: null,
      curYear: 0,
      curSelectedYear: 0,
      curState: SELECT_STATE.unselect,
    };
  },
  methods: {
    checkStartInput(event) {
      if (isNaN(this.startShowYear)) {
        this.startShowYear = this.startYear;
      } else {
        this.startYear = this.startShowYear * 1;
        this.changeYear();
      }
    },

    checkEndInput() {
      if (isNaN(this.endShowYear)) {
        this.endShowYear = this.endYear;
      } else {
        this.endYear = this.endShowYear * 1;
        this.changeYear();
      }
    },
    changeYear() {
      if (this.startYear > this.endYear) {
        let tmp = this.endYear;
        this.endYear = this.startYear;
        this.startYear = tmp;
        this.startShowYear = this.startYear;
        this.endShowYear = this.endYear;
      }
      if (this.startYear && this.endYear) {
        this.$emit("updateTimeRange", {
          startYear: moment(this.startYear + "")
            .startOf("year")
            .valueOf(),
          endYear:
            moment(this.endYear + "")
              .endOf("year")
              .valueOf() + 1,
        });
      } else {
        console.warn("WARN:年份不合法", this.startYear, this.endYear);
      }
    },
    onHoverItem(iYear) {
      if (this.curState === SELECT_STATE.selecting) {
        let tmpStart = this.curSelectedYear;
        this.endYear = Math.max(tmpStart, iYear);
        this.startYear = Math.min(tmpStart, iYear);
      }
    },
    onClickItem(iYear) {
      if (
        this.curState === SELECT_STATE.unselect ||
        this.curState === SELECT_STATE.selected
      ) {
        this.startYear = iYear;
        this.curSelectedYear = iYear;
        this.endYear = null;
        this.curState = SELECT_STATE.selecting;
      } else if (this.curState === SELECT_STATE.selecting) {
        this.endShowYear = this.endYear;
        this.startShowYear = this.startYear;
        this.curState = SELECT_STATE.selected;
        this.$emit("updateTimeRange", {
          startYear: moment(this.startYear + "")
            .startOf("year")
            .valueOf(),
          endYear:
            moment(this.endYear + "")
              .endOf("year")
              .valueOf() + 1,
        });

        setTimeout(() => {
          //为动画留的时间,可优化
          this.showPanel = false;
        }, 300);
      }
    },
    onFocus() {
      this.$nextTick(() => {
        this.showPanel = true;
      });
    },
    onBlur() {
      //   this.showPanel = false;
    },
    updateYearList() {
      let iStart = Math.floor(this.curYear / 10) * 10 - 10;
      iStart = iStart < 0 ? 0 : iStart;
      this.yearList = [];
      for (let index = 0; index < 20; index++) {
        this.yearList.push(iStart + index);
      }
    },
    closePanel(e) {
      if (!this.showPanel) {
        return;
      }
      if (typeof e.target.className !== "string") {
        this.$nextTick(() => {
          this.showPanel = false;
        });
        return;
      }
      if (
        e.target.className.indexOf("_inner") === -1 ||
        (e.target.name === "yearInput" &&
          e.target !== this.$refs.inputLeft &&
          e.target !== this.$refs.inputRight)
      ) {
        this.$nextTick(() => {
          this.showPanel = false;
        });
      }

      e.stopPropagation();
      return false;
    },
    onClickLeft() {
      this.curYear = this.curYear * 1 - 10;
      this.updateYearList();
    },
    onClickRight() {
      this.curYear = this.curYear * 1 + 10;
      this.updateYearList();
    },

    //------------------对外接口------------------------
    //直接传时间戳
    setYear(startYearStamp, endYearStamp) {
      if (!isNaN(startYearStamp) && !isNaN(endYearStamp)) {
        let startYear = moment(startYearStamp).format("yyyy");
        let endYear = moment(endYearStamp).format("yyyy");
        this.startYear = startYear * 1;
        this.endYear = endYear * 1;
        this.endShowYear = endYear * 1;
        this.startShowYear = startYear * 1;
      }
    },
  },

  created() {
    this.curYear = moment().format("yyyy");
    this.updateYearList();
  },
  beforeUnmount() {
    document.removeEventListener("click", this.closePanel.bind(this));
  },

  mounted() {
    this.$refs.yearPicker.style = "padding-left:" + this.labelWidth + "px";
    document.addEventListener("click", this.closePanel.bind(this));
  },
};
</script>
<style lang="scss" scoped>
.yearPicker {
  font-size: 14px;
  display: flex;
  position: relative;
  transition: all 0.3s;
  input:first-child {
    text-align: center;
  }
  .labelText {
    position: absolute;
    left: 10px;
    top: 10px;
    color: #c4c6d1;
  }
  background-color: #fff;
  span {
    padding: 0 8px;
    height: 36px;
    line-height: 36px;
  }
  border: 1px solid #eff1f3;
  height: 36px;
  line-height: 36px;
  border-radius: 4px;
  padding: 0 28px 0 8px;
  box-sizing: border-box;
  .floatPanel {
    > div {
      width: 50%;
    }
    // padding: 16px;
    position: absolute;
    display: flex;
    background-color: #fff;
    z-index: 9999 !important;
    border-radius: 4px;
    // width: 650px;
    height: 252px;
    top: 50px;
    left: 0px;
    box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
    border: 1px solid #dfe4ed;
    .panelContent {
      display: grid;
      grid-template-columns: 25% 25% 25% 25%;
      // flex-wrap: wrap;
      width: 100%;
      height: calc(100% - 15px);
      margin-top: 8px;
      .oneSelected {
        border-top-right-radius: 24px;
        border-bottom-right-radius: 24px;
      }
      .startSelected {
        background-color: #f2f6fc;
        border-top-left-radius: 24px;
        border-bottom-left-radius: 24px;
      }
      .endSelected {
        background-color: #f2f6fc;
        border-top-right-radius: 24px;
        border-bottom-right-radius: 24px;
      }
      .betweenSelected {
        background-color: #f2f6fc;
      }
      > div {
        width: 75px;
        height: 48px;
        line-height: 48px;
        margin: 6px 0;
        // border-radius: 24px;
        text-align: center;
        a {
          display: inline-block;
          width: 60px;
          height: 36px;
          cursor: pointer;
          line-height: 36px;
          border-radius: 18px;
          color: #606266;
        }
        .selected {
          background-color: #1890ff;
          color: #fff;
        }
      }
    }
    .panelHead {
      height: 38px;
      line-height: 38px;
      position: relative;
      text-align: center;
      font-size: 16px;
      border-bottom: 1px solid #dfe4ed;
      i {
        position: absolute;
        cursor: pointer;
        &:hover {
          color: #1890ff;
        }
      }
    }
    .rightPanel {
      // padding-left: 8px;
      margin: 16px;
      display: flex;
      flex-direction: column;
    }
    .line {
      width: 1px;
      height: 100%;
      background: #dfe4ed;
    }
    .leftPanel {
      margin: 16px;
      display: flex;
      flex-direction: column;
    }
    .leftPanel .panelHead i {
      left: 0px;
      top: 10px;
      font-size: 14px;
      color: #717273;
    }
    .rightPanel .panelHead i {
      right: 0px;
      top: 8px;
    }
    .leftPanel .panelHead i:hover,
    .rightPanel .panelHead i:hover {
      cursor: pointer;
    }
  }
  .floatPanel::before {
    content: "";
    border-bottom: 6.5px solid #797979;
    border-left: 6.5px solid transparent;
    border-right: 6.5px solid transparent;
    position: absolute;
    left: 44px;
    -webkit-transform: translateX(-50%);
    transform: translateX(-50%);
    top: -5.5px;
    border-radius: 5px;
  }
  .floatPanel::after {
    content: "";
    border-bottom: 8px solid #fff;
    border-left: 8px solid transparent;
    border-right: 8px solid transparent;
    position: absolute;
    left: 44px;
    -webkit-transform: translateX(-50%);
    transform: translateX(-50%);
    top: -5px;
    border-radius: 5px;
  }
}
input {
  width: 60px;
  border: none;
  height: 37px;
  line-height: 37px;
  box-sizing: border-box;
  background-color: transparent;
  text-align: center;
  color: #606266;
}
input:focus {
  outline: none;
  background-color: transparent;
}
.yearPicker:hover {
  border-color: #1890ff;
}
.dateIcon {
  position: absolute;
  right: 16px;
  top: 9px;
  color: #adb2bc;
}
</style>
使用:
<YearYear1 style="width:300px" :initYear="dateValue2" @updateTimeRange="updateStatisticYear" />

dateValue2: [],

updateStatisticYear(val) {
 console.log("年", val);
},

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

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

相关文章

轻松批量自定义重命名,为文件夹加上个性化编号!

在日常生活和工作中&#xff0c;我们经常需要对大量的文件夹进行重命名&#xff0c;以更好地管理和整理文件。然而&#xff0c;手动逐个修改文件夹名称费时费力&#xff0c;效率低下。现在&#xff0c;我们为您推荐一款简单易用的工具&#xff0c;可以帮助您快速批量自定义重命…

Unity-UGUI优化策略

界面出栈规则&#xff1a; 界面目录导航、策划界面回退需求造成界面套娃问题&#xff0c;夹带一系列层级问题&#xff0c;应该和策划进行友好沟通&#xff0c;避免界面不合理的出栈入栈规则 overdraw&#xff1a; 尽量减少同屏 半透明物体渲染 Unity 之 UGUI优化&#xff08;…

C++入门--string类的实现

目录 1.string类常用函数实现&#xff08;1&#xff09;string类成员变量定义&#xff08;2&#xff09; string类默认构造函数实现&#xff08;3&#xff09; string类拷贝构造函数实现&#xff08;4&#xff09;string类析构函数&#xff08;5&#xff09;string类c_str()函数…

linux umask:文件访问权限控制预设值

1. umask 定义 在 linux 系统中&#xff0c;umask 被定义在 /etc/profile 配置文件中&#xff0c;有一段 shell 脚本对 umask 是这么定义的。在 shell 会话输入命令&#xff1a; $ cat /etc/profile # 查看 /etc/profile 配置文件的内容 if [ $UID -gt 199 ] &&…

七夕送什么比较好?适合七夕节送的礼物

七夕将至&#xff0c;这是中国传统节日中最浪漫的一天&#xff0c;也是许多情侣们表达爱意的特殊时刻。在这个美好的节日里&#xff0c;送上一份特别的礼物&#xff0c;不仅能让心爱的人感受到你的深情厚意&#xff0c;还能为你们的爱情故事添上浓墨重彩的一笔。还不知道七夕要…

ElasticSearch:项目实战(1)

es环境搭建参考&#xff1a;ElasticSearch&#xff1a;环境搭建步骤_Success___的博客-CSDN博客 需求&#xff1a; 用户输入关键可搜索文章列表 关键词高亮显示 文章列表展示与home展示一样&#xff0c;当用户点击某一篇文章&#xff0c;可查看文章详情 思路&#xff1a; …

【腾讯云 Cloud Studio 实战训练营】深度体验 | 使用腾讯云 Cloud Studio 快速构建 Vue + Vite 完成律师 H5 页面

【腾讯云 Cloud Studio 实战训练营】深度体验 | 使用腾讯云 Cloud Studio 快速构建 Vue Vite 完成律师 H5 页面 写在前面的话一、腾讯云 Cloud Studio 介绍1.1 Cloud Studio 应用场景1.2 Cloud Studio 开发优势 二、沉浸式体验开发快速构建 H5 页面2.1 注册与登录 Cloud Studi…

第7章 通过内网本机IP获取微信code值及其对code值的回调。

在第5章中讲述了怎样通过内网穿透外外网从而获取微信code值&#xff0c;实际上微信测试帐号管理页中也支持通过内网本机IP获取微信code值。 1 重构launchSettings.json "https": { "commandName": "Project", "dotnetRunMessages": t…

代码随想录—力扣算法题:59螺旋矩阵II.Java版(示例代码与导图详解)

版本说明 当前版本号[20230810]。 版本修改说明20230810初版 目录 文章目录 版本说明目录59.螺旋矩阵II思路左闭右开方法左闭右闭方法两种方法的区别总结 59.螺旋矩阵II 力扣题目链接 更多内容可点击此处跳转到代码随想录&#xff0c;看原版文件 给定一个正整数 n&#xf…

BDA初级分析——数据收集、清洗和整理

一、认识数据 什么是数据&#xff1f; 数据是对客观世界的记录&#xff0c;用来记载事物的性质、状态、相互关系等。 有哪些常见的数据类型&#xff1f; 什么是数据集&#xff1f; 数据集&#xff1a;数据的集合&#xff0c;通常以表格形式出现。 二、收集数据 我们都会从哪里…

优思学院|6sigma合格率计算公式

概述 在现代竞争激烈的商业环境中&#xff0c;质量控制对于制造业和服务业都至关重要。其中&#xff0c;一个强大的方法是采用6sigma&#xff08;也称为6σ&#xff09;方法来提高质量和降低缺陷率。本文将深入探讨6sigma合格率计算公式&#xff0c;解释其在质量管理中的应用&…

20款奔驰C260 L(W206)更换内饰最全发光套件,提升车内氛围

原厂1:1设计&#xff0c;免编程匹配&#xff0c;无损安装&#xff0c;可升级项目&#xff1a; 1、碳纤维中控氛围灯&#xff08;阿凡达水滴款&#xff09; 2、发光前风口&#xff1b; 3、发光后风口&#xff1b; 4、发光座椅背气氛灯&#xff1b; 5、中音发光盖板 6、主动…

企业有VR全景拍摄的需求吗?能带来哪些好处?

在传统图文和平面视频逐渐疲软的当下&#xff0c;企业商家如何做才能让远在千里之外的客户更深入、更直接的详细了解企业品牌和实力呢&#xff1f;千篇一律的纸质材料已经过时了&#xff0c;即使制作的再精美&#xff0c;大家也会审美疲劳&#xff1b;但是你让客户远隔千里&…

网络编程基础:Linux网络I/O模型、JavaI/O模型、Netty

文章目录 一、Linux网络I/O模型简介0.文件描述符和系统调用1. 阻塞I/O模型2. 非阻塞I/O模型&#xff08;轮询&#xff09;3. I/O复用模型&#xff08;轮询、事件驱动&#xff09; 二、Java的I/O演进1.BIO&#xff08;阻塞&#xff09;&#xff08;1&#xff09;套接字&#xff…

安达发|疫情影响下的APS排程可以给制造业解决哪些问题

随着市场需求的不断变化&#xff0c;特别是对柔性、小单量多批次的需求日益增长&#xff0c;再加上疫情的影响&#xff0c;企业随时可能面临延期交货的风险。这使得行业供应链管理的复杂性不断加剧&#xff0c;企业对于生产管理高效性的需求也日益显著。 同时&#xff0c;我们…

vm workstation pro安装centos7

官网下载vm workstation pro&#xff0c;参考上一篇文章&#xff1a;https://editor.csdn.net/md/?articleId132208423安装centos7 官网下载的vm&#xff0c;是有一个镜像iso文件的 完成后稍等&#xff1a; 这一步很重要&#xff0c;别急着点开始安装&#xff0c;看到有感叹…

.NET 8 Preview 6 中推出 .NET MAUI: 欢迎使用 VS Code 和 VS for Mac

作者&#xff1a;David Ortinau 排版&#xff1a;Alan Wang .NET 8 Preview 6 推出了.NET MAUI&#xff0c;同时修复了 23 个关键问题&#xff0c;并引入了适用于 iOS 的 Native AOT。此外&#xff0c;您现在可以在 .NET 8 中使用 .NET MAUI&#xff0c;只要安装 Visual Studio…

excel将主信息和明细信息整理为多对多(每隔几行空白如何填充)

excel导出的数据是主信息和明细信息形式。 原始数据图&#xff1a; 最终效果:

UML之四种事物

目录 结构事物 行为事物 分组事物&#xff1a; 注释事物 结构事物 1.类(Class) -类是对一组具有相同属性、方法、关系和语义的对象的描述。一个类实现一个或多个接口 2.接口(interface) -接口描述 了一个类或构件的一个服务的操作集。接口仅仅是定义了一组操作的规范&…

23、springboot日志使用入门-- SLF4J+Logback 实现(springboot默认的日志实现),日志打印到控制台及日志输出到指定文件

springboot日志使用入门 ★ 典型的Spring Boot日志依赖&#xff1a; spring-boot-start.jar -- spring-boot-starter-logging.jar (Spring Boot的日志包&#xff09;-- logback&#xff08;core、classic&#xff09;-- log4j-to-slf4j.jar-- jul-to-slf4j.jar就是springboo…