当前位置: 首页 > news >正文

Vue2 elementUI年份区间选择组件

一、显现效果

二、组件封装 yearPicker.vue

<template><div class="yearPicker" ref="yearPicker" :style="{ width: width + 'px' }"><div class="_inner labelText" :style="{ width: labelWidth + 'px' }">{{ labelText }}</div><input class="_inner" ref="inputLeft" v-model.number="startShowYear" @focus="onFocus" type="text" @click="clickInput"name="yearInput" @input="checkStartInput($event)" placeholder="选择年份" /><span>{{ sp }}</span><input class="_inner" ref="inputRight" v-model.number="endShowYear" @focus="onFocus" type="text" @click="clickInput"name="yearInput" @input="checkEndInput($event)" placeholder="选择年份" /><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 v-for="item in leftYearList" :class="{disabled: checkValidYear(item) != 0,oneSelected: item === startYear && oneSelected,startSelected: item === startYear,endSelected: item === endYear,_inner: true,betweenSelected: item > startYear && item < endYear}" :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="_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="{disabled: checkValidYear(item) != 0,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>
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);}},props: {width: {default: 200,},labelWidth: {default: 80,},labelText: {default: "时间标签",},sp: {default: "至",},initYear: {default: null,},},data () {return {startShowYear: null,//输入框 开始年份endShowYear: null,//输入框 结束年份yearList: [], //选择框里可选择的年份showPanel: false, //选择框是否显示startYear: null, //选择框选中的开始年份endYear: null, //选择框选中的结束年份curYear: 0,curSelectedYear: 0,curState: SELECT_STATE.unselect,};},methods: {// 重置时间范围onReset () {this.startYear = null;this.endYear = null;this.startShowYear = null;this.endShowYear = null;this.$emit("updateTimeRange", {startYear: null,endYear: null,});},// 检查年份是否在可选区间内  是否禁用checkValidYear (iYear) {if (this.initYear) {if (iYear > this.initYear.endYear) {return 1} else if (iYear < this.initYear.startYear) {return -1}}return 0},// 开始年份 输入框校验  并将选择框对应开始年份选中checkStartInput (event) {if (isNaN(this.startShowYear)) {this.startShowYear = this.startYear;} else {this.startYear = this.startShowYear * 1;}},// 结束年份 输入框校验  并将选择框对应结束年份选中checkEndInput () {if (isNaN(this.endShowYear)) {this.endShowYear = this.endYear;} else {this.endYear = this.endShowYear * 1;}},// 选择框 鼠标悬停事件  选中年份范围onHoverItem (iYear) {if (this.checkValidYear(iYear) != 0) {return;}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.checkValidYear(iYear) != 0) {// 点击禁用年份  直接返回return;}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) {// 处于选中一个,然后再点击 // 如果 开始年份和结束年份是一样  但 结束年份值为空 则 结束年份 == 开始年份if(this.startYear && !this.endYear){this.endYear = this.startYear;}this.endShowYear = this.endYear;this.startShowYear = this.startYear;this.curState = SELECT_STATE.selected;this.$emit("updateTimeRange", {startYear: this.startYear,endYear: this.endYear,});setTimeout(() => {//为动画留的时间,可优化this.showPanel = false;}, 300);}},//使 input 获取焦点onFocus () {this.$nextTick(() => {this.showPanel = true;if(this.startShowYear && this.endShowYear){// 点击选择框  已选择年份范围  则将选择框对应年份选中this.endYear = this.endShowYear;this.startYear = this.startShowYear;this.curState = SELECT_STATE.selected;}});},// 点击 input 阻止事件冒泡clickInput (e) {e.stopPropagation();return false;},// 点击空白区域关闭选择框closePanel (e) {if (!this.showPanel) {return;}if (typeof e.target.className !== "string" || e.target.className === "") {this.$nextTick(() => {this.changeYear();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.changeYear();this.showPanel = false;});}e.stopPropagation();return false;},// 点击空白区域关闭选择框   时间检验回显changeYear () {if (!this.startYear || !this.endYear) {return;}if (this.startYear > this.endYear) {let tmp = this.endYear;this.endYear = this.startYear;this.startYear = tmp;}if (this.initYear) {this.startYear = Math.max(this.startYear, this.initYear.startYear)this.endYear = Math.min(this.endYear, this.initYear.endYear)}this.startShowYear = this.startYear;this.endShowYear = this.endYear;if (this.startYear && this.endYear) {this.$emit("updateTimeRange", {startYear: this.startYear,endYear: this.endYear + ""});} else {console.warn("WARN:年份不合法", this.startYear, this.endYear);}},// 点击左箭头  切换到上一个十年onClickLeft () {this.curYear = this.curYear * 1 - 10;this.updateYearList();},// 点击右箭头  切换到下一个十年onClickRight () {this.curYear = this.curYear * 1 + 10;this.updateYearList();},// 更新年份列表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);}},//------------------对外接口------------------------// //直接传时间戳// 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 = new Date().getFullYear();this.updateYearList();},beforeUnmount () {// 组件销毁时移除事件监听// 点击空白区域关闭选择框document.removeEventListener("click", this.closePanel.bind(this));},mounted () {// 组件挂载时添加事件监听// 点击空白区域关闭选择框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 {text-align: center;}input:first-child {text-align: right;}background-color: #fff;.labelText {text-align: center;}span {padding: 0 8px;height: 38px;line-height: 38px;}border: 1px solid #eff1f3;height: 40px;line-height: 40px;border-radius: 4px;padding: 0 28px 0 8px;box-sizing: border-box;.floatPanel {>div {width: 50%;}padding: 0 16px;position: absolute;display: flex;background-color: #fff;z-index: 2000;border-radius: 4px;width: 650px;height: 250px;top: 40px;left: -10px;box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);.panelContent {display: flex;flex-wrap: wrap;width: 100%;height: calc(100% - 70px);.disabled {color: #ccc;}.oneSelected {border-top-right-radius: 24px;border-bottom-right-radius: 24px;}.startSelected {background-color: #f6f6f7;border-top-left-radius: 24px;border-bottom-left-radius: 24px;}.endSelected {background-color: #f6f6f7;border-top-right-radius: 24px;border-bottom-right-radius: 24px;}.betweenSelected {background-color: #f6f6f7;}>div {width: 75px;height: 48px;line-height: 48px;margin: 3px 0;// border-radius: 24px;text-align: center;a {display: inline-block;width: 60px;height: 36px;cursor: pointer;line-height: 36px;border-radius: 18px;}.selected {background-color: #3e77fc;color: #fff;}}}.panelHead {position: relative;height: 46px;line-height: 46px;text-align: center;i {position: absolute;cursor: pointer;&:hover {color: #3e77fc;}}}.rightPanel {padding-left: 8px;}.leftPanel .panelHead i {left: 20px;top: 15px;}.rightPanel .panelHead i {right: 20px;top: 15px;}}.floatPanel::before {content: "";height: 100%;position: absolute;left: 50%;width: 1px;border-left: 1px solid #e4e4e4;}
}input {width: 60px;border: none;height: 40px;line-height: 40px;box-sizing: border-box;background-color: transparent;
}input:focus {outline: none;background-color: transparent;
}.yearPicker:hover {border-color: #3e77fc;
}.dateIcon {position: absolute;right: 16px;top: 9px;color: #adb2bc;
}
</style>

三、组件使用

<template>

  <div class="moneyType">

   <div class="moneyType_con">

      <el-form :inline="true" :model="formInline" class="demo-form-inline">

        <el-form-item label="年度">

          <YearPicker ref="yearPicker" labelText="" :label-width="0"  :initYear="initYear" @updateTimeRange="updateStatisticYear"></YearPicker>

        </el-form-item>

        <el-form-item>

          <el-button type="primary" icon="el-icon-search" @click="getData(1)">查询</el-button>

          <el-button type="success" icon="el-icon-refresh" @click="onReset(1)">重置</el-button>

        </el-form-item>

      </el-form>

    </div>

  </div>

</template>

<script>

import YearPicker from "../components/yearPicker.vue";

export default {

  components: {

    YearPicker

  },

  data () {

    return {

      initYear: {

        startYear: 1945,

        endYear: new Date().getFullYear()

      },//年份区间选择框初始时间

      formInline: {

        nd: '',

        nds: '',

      },

    };

  },

  mounted () {

   

  },

  methods: {

    // 更新时间范围

    updateStatisticYear({startYear, endYear}){

      this.formInline.nd = startYear

      this.formInline.nds = endYear

    },

    // 查询

    getData () {

     

    },

    // 重置

    onReset () {

      this.formInline = {

        nd: '',

        nds: '',

      }

      this.$refs.yearPicker.onReset()

      this.getData();

    },

  },

};

</script>

四、实现功能

 1、可选年份区间(区间外禁止点击和选择,同时校正输入)。

2、实现选择开始年和结束年一样,如2024-2024。

3、实现弹框显示时回显当前选择的开始年和结束年。


http://www.dtcms.com/a/537424.html

相关文章:

  • 工装设计方案网站wordpress的仪表盘进不去
  • 深度学习笔记40-CGAN|生成手势图像
  • 浙江建设职业技术学院oa网站怎么做微信推广和宣传
  • React 08
  • 企业信息门户网站建设方案设计素材的网站
  • 如何将自己做的网站变成中文帮忙制作网页的公司
  • gpu driven:vello新执行流程
  • LangGraph的Agent长短时记忆的原理有什么区别,分别适用于什么业务场景
  • 定制网站开发的目的是什么做单位网站的公司吗
  • 做网站建立数据库自适应的网站模板
  • 路由硬盘做网站空间不中国城乡建中国城乡建设部网站
  • 电脑怎么做服务器 网站wordpress手机号网站
  • 跨境电商技术与运营双升级!亚马逊 / TikTok/Temu 本周新政解读,附卖家技术适配指南​
  • C++ 类的学习(七) 类的转换 和 嵌套类
  • C++进阶: 虚函数1-----继承中的灵魂
  • 软件协议使用应知应会
  • C语言进阶:深入探讨指针(一)
  • 网站备案 信息wordpress支付接口同步回调
  • 当 AI 开始书写历史:我们如何用 Gateone.ai 把“历史人物时间线”从学术幻想变成 SaaS 产品
  • 如何推广企业网站杭州物联网前十名公司
  • SQL Server
  • state machine diagrams用于需求分析阶段还是设计阶段
  • 【穿越Effective C++】Scott Meyers的《Effective C++》逻辑框架概要汇总--各条款是什么?为什么?怎么做?
  • 易旅游网站建设wap网站开发和自适应
  • 免费iOS加固方案指南
  • 登封快乐送餐在那个网站做的广告wordpress版本对应php版本
  • 云南网站建设一度科技网站团购活动页面怎么做
  • 电动自行车为何限速25公里每小时?——安全、法规与技术的平衡之道
  • 怎样用vs2017做网站长沙做网站要多少钱
  • 怎么学建设网站盐城企业建设网站