首页 > 其他分享 >自定义周选择组件、年选择组件

自定义周选择组件、年选择组件

时间:2024-08-09 17:05:39浏览次数:12  
标签:false 自定义 defaultYear default 选择 year 组件 const type

// 周组件 weekSelect

<!-- 周选择组件 -->
<template>
  <div ref="viYearSelect" class="vi-year-select">
    <ui-input
            v-model="selectVal"
            :placeholder="placeholder"
            :disabled="disabled"
            readonly
      :clearable="clearable"
            @click.native.stop="showSelect"
            :suffix="selectShow ? 'ios-arrow-up' : 'ios-arrow-down'"
    />
    <div class="zTreeSelect" :style="{ width: width }" v-show="selectShow" @click.stop>
        <div class="panel-top">
          <span @click="prevYear">
            <ui-icon type="ios-arrow-back" size="16" color="#001F45" />
          </span>
          <div class="week-info">
            <span>{{defaultYear}}</span>&nbsp;
          </div>
          <span @click="nextYear">
            <ui-icon type="ios-arrow-forward" size="16" color="#001F45" />
          </span>
        </div>
        <div class="panel-info">
          <div class="option"
            v-for="(wItem,wIndex) in this.weekList"
            :key="wIndex"
            :title="wItem[0]+' 至 '+wItem[wItem.length-1]"
            :class="{'disabledCls': disabledCls(defaultYear, wIndex)}"
            @click="selectOption(wItem,wIndex,defaultYear)"
          >
            <span class="option-info">第{{wIndex*1+1*1}}周</span>
          </div>
        </div>
    </div>
  </div>
</template>
<script>
import { weekFormat } from "@/utils/index";
export default {
  name: "viWeekSelect",
  props: {
    model: {
      type: String
    },
    clearable: {
      type: Boolean,
      default: false
    },
    placeholder: {
      type: String,
      default: "请选择",
    },
    disabled: {
      type: Boolean,
      default: false,
    },
    disabledValR: { // 大于当前的值,禁止选择,值格式为: YYYY 第N周
      type: String,
      default: ""
    },
    disabledValL: { // 小于当前的值,禁止选择,值格式为: YYYY 第N周
      type: String,
      default: ""
    },
  },
  // model中:prop代表着我要和props的指定变量(model)相对应,event表示着事件,我触发事件(change)的时候会改变父组件v-model的值
  model: {
    prop: "model",
    event: ""
  },
  watch: {
    model: {
      deep: true,
      immediate: true,
      handler(val) {
        this.selectVal = val;
      }
    }
  },
  computed: {
    // 周,禁止选择项判断
    disabledCls() {
      return function (dyear, wIndex) {
        try {
          dyear = Number(dyear);
          wIndex = Number(wIndex);
          if (this.disabledValR) {
            const year = Number(this.disabledValR.split(" ")[0]);
            const weekStr = this.disabledValR.split(" ")[1];
            const week = Number(weekStr.slice(1, weekStr.length - 1));
            if ((dyear > year) || (dyear == year && week < Number(wIndex * 1 + 1 * 1))) {
              return true;
            } else {
              return false;
            }
          } else if (this.disabledValL) {
            const year = Number(this.disabledValL.split(" ")[0]);
            const weekStr = this.disabledValL.split(" ")[1];
            const week = Number(weekStr.slice(1, weekStr.length - 1));
            if ((dyear < year) || (dyear == year && week > Number(wIndex * 1 + 1 * 1))) {
              return true;
            } else {
              return false;
            }
          } else {
            return false;
          }
        } catch (e) {}
      };
    }
  },
  data() {
    const curY = this.$moment().format("YYYY");// 获取今年
    return {
      selectVal: "",
      selectShow: false,
      width: 0,
      // 年
      defaultYear: curY,
      stepYear: 1,
      weekList: [],
    };
  },
  mounted() {
    this.initYear(this.defaultYear);
    this.initEvent();
  },
  methods: {
    initYear(initY) {
      this.defaultYear = Number(initY);
      this.weekList = weekFormat(initY);
    },
    resetWidth() {
      const width = this.$refs.viYearSelect.offsetWidth;
      this.width = `${width}px`;
    },
    prevYear() {
      this.defaultYear -= 1 * this.stepYear;
      this.initYear(this.defaultYear);
    },
    nextYear() {
      this.defaultYear += 1 * this.stepYear;
      this.initYear(this.defaultYear);
    },
    // 年组件选择
    selectOption(wItem, wIndex, dyear) {
      const bool = this.disabledCls(dyear, wIndex);
      if (bool) {
        // console.log("禁止选择时间段");
        return false;
      }
      this.selectShow = false;
      let rsp = {
        startTime: `${wItem[0]} 00:00:00`,
        endTime: `${wItem[wItem.length - 1]} 23:59:59`
      };
      this.$emit("change", rsp, "week");
      this.selectVal = `${this.defaultYear} 第${wIndex * 1 + 1 * 1}周`;
    },
    showSelect() {
      if (!this.disabled) {
        this.selectShow = !this.selectShow;
        this.resetWidth();
      }
    },
    initEvent() {
      document.addEventListener("click", () => {
        this.selectShow = false;
      });
    },
  },
};
</script>

<style lang="less" scoped>
.vi-year-select {
  position:relative;
}
.search-form .vi-year-select .zTreeSelect {
  position: fixed !important;
}
  .zTreeSelect {
    background-color: #fff;
    height: 220px;
    max-width: 400px;
    overflow: auto;
    position: absolute;
    z-index: 10;
    box-shadow: 0 1px 6px rgba(0, 0, 0, 0.2);
    border-radius: 4px;
    margin-top: 5px;
    z-index: 99;
    .option {
      text-align: center;
      cursor: pointer;
      margin: 0;
      line-height: normal;
      padding: 7px 0px;
      clear: both;
      color: #515a6e;
      font-size: 14px;
      white-space: nowrap;
      list-style: none;
      cursor: pointer;
      transition: background 0.2s ease-in-out;
      width: 50%;
      display: inline-block;
    }
    .option:hover{
        background: #f3f3f3;
    }
    .option.disabledCls {
      color: #AEB8C4;
      cursor: not-allowed;
    }
  }
  .panel-top {
    height: 30px;
    border-bottom: 1px solid #DCDEE2;
    display: flex;
    justify-content: space-around;
    &:last-child, &:first-child {
        cursor: pointer;
    }
  }
  .panel-info {
    height: 190px;
    overflow: auto;
  }
  .month-info {
    font-weight: 600;
  }
  .week-list{
    padding: 2px 0px;
    &:hover{
        background: #f3f3f3;
    }
  }
</style>
// 指定年份,返回,指定年份的周列表
function weekFormat(initY) {
  let weekList = [];
  let weekIdx = 0;
  weekList[weekIdx] = [];
  const monthDay = [31, ((initY % 4) == 0 ? 29 : 28), 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]; // 每年的月份
  for (let i = 1; i <= monthDay.length; i++) {
    let month =  i > 9 ? i : `0${i}`;
    for (let j = 1; j <= monthDay[i - 1]; j++) {
      const day = j > 9 ? j : `0${j}`;
      const monthFirst = `${initY}-${month}-${day}`;
      let weekN = moment(`${monthFirst}`).format("dddd"); // 获取当天星期几
      weekList[weekIdx].push(monthFirst);
      if (weekN == "Sunday") {
        weekIdx++;
        weekList[weekIdx] = [];
      }
    }
  }
  return weekList;
}
View Code

 

 

// 年组件 yearSelect

<template>
  <div ref="viYearSelect" class="vi-year-select">
    <ui-input
            v-model="selectVal"
            :placeholder="placeholder"
            :disabled="disabled"
            readonly
      :clearable="clearable"
            @click.native.stop="showSelect"
            :suffix="selectShow ? 'ios-arrow-up' : 'ios-arrow-down'"
    />
    <div class="zTreeSelect" :style="{ width: width }" v-show="selectShow" @click.stop>
      <div>
        <div class="panel-top">
          <span @click="prevYear">
            <ui-icon type="ios-arrow-back" size="16" color="#001F45" />
          </span>
          <span>{{defaultYear}}</span>
          <span @click="nextYear">
            <ui-icon type="ios-arrow-forward" size="16" color="#001F45" />
          </span>
        </div>
        <div>
          <div
            class="option"
            :class="{'disabledCls':disabledCls(item)}"
            v-for="item in yearList"
            :key="item"
            @click="selectOption(item)"
          >
          {{item}}年</div>
        </div>
      </div>
    </div>
  </div>
</template>
<script>

export default {
  name: "viYearSelect",
  props: {
    model: {
      type: String
    },
    clearable: {
      type: Boolean,
      default: false
    },
    placeholder: {
      type: String,
      default: "请选择",
    },
    disabled: {
      type: Boolean,
      default: false,
    },
    disabledValR: { // 大于当前的值,禁止选择,值格式为: YYYY
      type: String,
      default: ""
    },
    disabledValL: { // 小于当前的值,禁止选择,值格式为: YYYY
      type: String,
      default: ""
    },
    type: { // 下拉类型,年(year)、星期(week)、季度
      type: String,
      default: "year"
    },
    rspType: {  // 返回类型,range,"",,range例如选择了年,那么就返回今年的开始时间和结束时间
      type: String,
      default: "range"
    }
  },
  // model中:prop代表着我要和props的指定变量(model)相对应,event表示着事件,我触发事件(change)的时候会改变父组件v-model的值
  model: {
    prop: "model",
    event: ""
  },
  watch: {
    model: {
      deep: true,
      immediate: true,
      handler(val) {
        this.selectVal = val;
      }
    },
    disabledValR: {
      deep: true,
      immediate: true,
      handler() {}
    },
    disabledValL: {
      deep: true,
      immediate: true,
      handler() {}
    }
  },
  computed: {
    // 年,禁止选择项判断
    disabledCls() {
      return function (item) {
        let bool = (this.disabledValR && item > this.disabledValR) || (this.disabledValL && item < this.disabledValL);
        return bool;
      };
    }
  },
  data() {
    return {
      selectVal: "",
      selectShow: false,
      width: 0,
      defaultYear: "",
      stepYear: 10,
      yearList: [],
    };
  },
  mounted() {
    const curY = this.$moment().format("YYYY");// 获取今年
    this.initYear(curY);
    this.initEvent();
  },
  methods: {
    initYear(initY) {
      this.defaultYear = Math.floor(initY / this.stepYear) * this.stepYear;
      this.yearList = [];
      for (let i = this.defaultYear; i < this.defaultYear * 1 + this.stepYear; i++) {
        this.yearList.push(i);
      }
    },
    resetWidth() {
      const width = this.$refs.viYearSelect.offsetWidth;
      this.width = `${width}px`;
    },
    prevYear() {
      this.defaultYear -= this.stepYear;
      this.initYear(this.defaultYear);
    },
    nextYear() {
      this.defaultYear += this.stepYear;
      this.initYear(this.defaultYear);
    },
    // 年组件选择
    selectOption(item) {
      const bool = this.disabledCls(item);
      if (bool) {
        // console.log("禁止选择时间段");
        return false;
      }
      this.selectShow = false;
      if (this.rspType == "range") {
        let rsp = {
          startTime: `${item}-01-01 00:00:00`,
          endTime: `${item}-12-31 23:59:59`
        };
        this.$emit("change", rsp, "year");
      } else {
        this.$emit("change", item, "year");
      }
      this.selectVal = item;
    },
    showSelect() {
      if (!this.disabled) {
        this.selectShow = !this.selectShow;
        this.resetWidth();
      }
    },
    initEvent() {
      document.addEventListener("click", () => {
        this.selectShow = false;
      });
    },
  },
};
</script>

<style lang="less" scoped>
.vi-year-select {
  position:relative;
}
.search-form .vi-year-select .zTreeSelect {
  position: fixed !important;
}
  .zTreeSelect {
    background-color: #fff;
    height: 200px;
    max-width: 400px;
    overflow: auto;
    position: absolute;
    z-index: 10;
    box-shadow: 0 1px 6px rgba(0, 0, 0, 0.2);
    border-radius: 4px;
    margin-top: 5px;
    z-index: 99;
    .option {
        text-align: center;
        cursor: pointer;
        margin: 0;
        line-height: normal;
        padding: 7px 0px;
        clear: both;
        color: #515a6e;
        font-size: 14px;
        white-space: nowrap;
        list-style: none;
        cursor: pointer;
        transition: background 0.2s ease-in-out;
        width: 50%;
        display: inline-block;
    }
    .option:hover{
        background: #f3f3f3;
    }
    .option.disabledCls {
      color: #AEB8C4;
      cursor: not-allowed;
    }
  }
  .panel-top {
      height: 30px;
      border-bottom: 1px solid #DCDEE2;
      display: flex;
      justify-content: space-around;
      &:last-child, &:first-child {
          cursor: pointer;
      }
  }
</style>

 

标签:false,自定义,defaultYear,default,选择,year,组件,const,type
From: https://www.cnblogs.com/luoxuemei/p/18351079

相关文章

  • ant disign vue pro 使用日期组件,无法动态赋值 解决
    原文地址:https://blog.csdn.net/weixin_43865196/article/details/121849591组件使用渲染<a-date-picker v-model="date" format="YYYY-MM-DD" valueFormat="YYYYMMDD" :allowClear="false" @change="(date,dateStr)=>{ this.da......
  • Vue3实现印章徽章组件
    1、组件结构2、组件封装src/components/StampBadge/src/StampBadge.vue文件代码<template><divclass="first-ring"v-bind="getBindValue":class="getStampBadgeClass"><divclass="second-ri......
  • Vue3水印组件
    1、组件封装<template><divref="watermarkContainerRef"class="watermark-container"><!--插槽--><slot></slot></div></template><scriptsetup>import{ref,onMounted,watc......
  • 为什么我选择ScreenToGif?看看它的这些亮点就知道了!
    前言在这个快节奏的数字时代,每一刻的精彩都值得被永久珍藏;当你精心策划的创意方案在屏幕上跃然生辉,或是游戏中的神来之笔让人拍案叫绝,你是否渴望能有一种魔法,让这些瞬间不仅仅是过往云烟,而是能够随时回放、分享给世界的璀璨宝石?小江湖今天要揭秘的,就是这样一款能够捕捉时间魔......
  • 25版王道数据结构课后习题详细分析 第三章栈、队列和数组 3.1 栈 选择题部分
    一、单项选择题————————————————————————————————————————解析:栈和队列的逻辑结构都是相同的,都属于线性结构,只是它们对数据的运算不同。正确答案:B————————————————————————————————————......
  • ToDesk全球节点绑定设备、不限设备怎么选择?有什么区别
    最近跨境电商和远程办公成为许多企业和打工人的工作选择,因此使用远程控制软件进行线上办公的需求也日益增多。小社长最近发现ToDesk远程控制软件有个全球节点功能,对跨境线上远控办公非常好用,能稳定远控国外的设备,远控的各种功能都挺完善的。ToDesk也是小社长的常备远控软件了,能......
  • 博客园自定义皮肤工具推荐:awescnb
    简介awescnb是一个用于博客园(Cnblogs)的自定义皮肤和功能增强插件。它允许用户通过简单的配置来自定义其博客的外观和增加一些额外的功能。下面是对awescnb的简要介绍:功能特点:自定义皮肤:用户可以选择不同的皮肤主题,包括背景颜色、字体样式等,以个性化他们的博客页面。扩展......
  • OpenTiny HUICharts开源发布,带你了解一个简单、易上手的图表组件库
    摘要:目前OpenTinyHUICharts已经成功落地在华为内部100多个产品中,持续提升了用户的可视化体验。本文分享自华为云社区《OpenTinyHUICharts正式开源发布,一个简单、易上手的图表组件库》,作者:OpenTiny。引言大家好!我们非常高兴地跟大家宣布,今天正式发布我们的新产品——Open......
  • 【自动驾驶】自定义消息格式的话题通信(C++版本)
    目录新建消息文件更改包xml文件中的依赖关系更改cmakelist文件中的配置执行时依赖改变cmakelist编译顺序发布者程序调用者程序程序测试新建消息文件在功能包目录下,新建msg文件夹,下面新建mymsg.msg文件,其内容为stringnamefloat64value发布者包含该消息,生成头文......
  • 使用Qt实现自定义GraphicsView
    在本文中,我们将介绍如何使用Qt实现一个自定义的GraphicsView,主要是作为笔记使用QGraphicsView框架方面的使用手法、套路,对代码就不做过多的解释了,它具有以下功能:显示图像可拖动的十字标记(CrossMarkItem)可调整大小的ROI(RegionofInterest)矩形FPS和日期时间显示保存和......