自定义日期选择器

HTML 部分代码

使用 popup 组件将它弹出

<view>
	<uni-popup ref="popupDate" type="bottom">
		<view class="popup-top-box">
			<text>日期选择</text>
			<text class="cancel-btn" @click="closeFun">取消</text>
		</view>
		<view class="popup-box">
			<picker-view v-if="visible" :indicator-style="indicatorStyle" :value="dateIndex" @change="bindChangeFun" class="picker-view">
				<picker-view-column>
					<view class="item" v-for="(item,index) in dateArray[0]" :key="index">{{item}}年</view>
				</picker-view-column>
				<picker-view-column>
					<view class="item" v-for="(item,index) in dateArray[1]" :key="index">{{item}}月</view>
				</picker-view-column>
				<picker-view-column>
					<view class="item" v-for="(item,index) in dateArray[2]" :key="index">{{item}}日</view>
				</picker-view-column>
			</picker-view>
		</view> 
		<view class="btn-box" style="padding: 10px;background-color: #FFFFFF;">
			<button type="warn" @click="submitDateFun" class="btnConfirm">确定</button>
		</view>
	</uni-popup>
</view>

JS 部分代码

对应 JS 部分代码,可以根据自己的需求进行修改。

<script>
	export default {
		data() {
			return {
				forms: {}, // 表达数据 
				yourData: {}, // 后台获取的数据
				dateArray: [], // 日期选择器展示数组
				visible: true, // 显隐
				indicatorStyle: `height: 50px;`, // 高亮样式 
				dateKey: "" , // 操作的字段 
				dateIndex: [0,0,0] // 选择器显示值下标
			}
		},
		mounted() {
			this.$refs.popupDate.close() 
			this.createDate() 
		},
		methods: {
			/**
			 * @author 单乘风 
			 * @description 自定义日期选择器,初始化日期数组  
			 * */ 
			createDate () {
			  var years = []
			  var year = new Date().getFullYear()
			  for (let i = year - 100; i <= year + 50; i++) {
			    years.push(String(i)) 
			  }
			  var months = []
			  for (let i = 1; i <= 12; i++) {
			    months.push((i < 10 ? '0' : '') + i)
			  }
			  var days = []
			  for (let i = 1; i <= 31; i++) {
			    days.push((i < 10 ? '0' : '') + i)
			  } 
			  years.push(String(9999))
			  this.dateArray.push(years, months, days) 
			  this.setDateIndex() 
			}, 
			
			/**
			 * @author 单乘风
			 * @description 自定义日期选择器,设置默认值(高亮值/当前值)  
			 * @remarks 设置高亮日期(根据接口返回日期查找日期数组中该日期的下标,如果数据库没有返回日期值则置0)
			 * */ 
			setDateIndex(){ 
				if(JSON.stringify(this.cusData)=="{}"){
					this.dateIndex= [0,0,0]
					return 
				} 
				let tempAry = this.cusData.cid$certEndDate.split("-")
				this.dateIndex= [this.dateArray[0].indexOf(tempAry[0]), this.dateArray[1].indexOf(tempAry[1]), this.dateArray[2].indexOf(tempAry[2])] 
			},
			
			/**
			 * @author 单乘风
			 * @description 自定义日期选择器,打开日期选择器
			 * @params key: 当前操作字段 
			 * @remarks 子组件回调方法(可以根据自己需求选择弹出选择器)  
			 * */ 
			onclickFun(key){
				this.dateKey= key 
				this.$refs.popupDate.open()
			},
			
			/**
			 * @author 单乘风 
			 * @description 自定义日期选择器,选择器中值发生改变时触发该方法
			 * @params e: 当前节点对象(即响应值)
			 * @remarks if 判断的意思为,当“年”发生变化时将“月、日”置0(即“01月01日”),当“月”发生变化时将“日”置0(即“01日”)且根据“年、月”重置“日”的值,否则将当前选择的日期小标值赋值给 dateIndex。
			 * */ 
			bindChangeFun(e){
				const val = e.detail.value  
				if(this.dateIndex[0] !== val[0]){
					this.dateIndex= [val[0], 0, 0]  
				}else if(this.dateIndex[1] !== val[1]){
					this.dateIndex= [val[0], val[1], 0]  
					this.setData(this.dateArray[0][val[0]], this.dateArray[1][val[1]])
				}else{
					this.dateIndex= val
				} 
			},
			
			/**
			 * @author 单乘风
			 * @description 自定义日期选择器,根据年、月设置对应日
			 * @params y: 年, m: 月  
			 * */ 
			setData(y,m){ 
				var Marr = [1,3,5,7,8,10,12] 
				var day = ''
				var year = parseInt(y) + 1960
				if(m == 2){
					if((year % 4 == 0 && year % 100 != 0) || (year % 400 == 0)){
						day = 29
					}else{
						day = 28
					}
				}else if(Marr.indexOf(Number(m)) != -1){
					day = 31
				}else{
					day = 30
				}
				
				var days = []
				for (let i = 1; i <= day; i++) {
				  days.push((i < 10 ? '0' : '') + i)
				} 
				this.dateArray[2] = days 
			}, 

			/**
			 * @author 单乘风
			 * @description 自定义日期选择器,选择器点击 "取消" 触发该方法关闭弹窗
			 * */ 
			closeFun(){
				this.$refs.popupDate.close()
			},
		
			/**
			 * @author 单乘风
			 * @description 证件到期日期,选择器点击 "确定" 触发该方法设置选择的参数  
			 * @remarks 将选中的日期设置到对应的表单字段中(根据自己的需求将时间设置)
			 * */ 
			submitDateFun(){
				let tempStr = this.dateArray[0][this.dateIndex[0]]+"-"+ this.dateArray[1][this.dateIndex[1]]+"-"+this.dateArray[2][this.dateIndex[2]] 
				this.forms[this.dateKey] = tempStr 
				this.forms.text[this.dateKey] = tempStr  
				this.$refs.popupDate.close()
			},
		}
	}
</script>

CSS 部分代码

css 样式

<style lang="scss">
	.popup-top-box {
		border-top-left-radius: 20rpx;
		border-top-right-radius: 20rpx;
		color: #333333;
		font-size: 36rpx;
		background-color: #FFF;
		text-align: center;
		padding: 20rpx 0;
		border-bottom: 1rpx solid #eee;
		box-sizing: border-box;
		position: relative;
	} 
	
	.cancel-btn {
		position: absolute;
		top: 28rpx;
		right: 20rpx;
		font-size: 28rpx;
		color: #999999;
	}
	.popup-box {
		height: 300rpx;
		text-align: center;
		background-color: #FFFFFF;
	}
	.picker-view {
		height: 100%;
	}
	.item {
		line-height: 50px;
	}
	.btnConfirm{
		background-color: #00B379;
		border: none;
		color: #FFFFFF;
	}
</style>

总结

可能有人不禁要问,uniapp 有对应的 picker mode="date" 不就行了?! 为什么要费劲去搞这么一个东东?

请听我狡辩

我的甲方爸爸有这么一个要求,要在日期后面加一个 9999 年,我最初的想法这个需求简单,把源码改了不就行了?呵呵!改完源码之后发现不生效,在网上找了很多大佬的文章,都试了一遍,搞不定。

我觉得有一篇文章比较靠谱,但是试了也不行,大家可以去试试,文章链接如下:
vue项目中修改element-ui源码,如何运用到项目中 (修改 node_modules 里的文件,并应用)

我也仅试了文章里如下的这个方法(PS:因为我懒觉得前面的方式太复杂不想去试)

使用patch-package来修改
使用 patch-package 来修改 node_modules 里面的文件更方便

  1. 安装 patch-packagenpm i patch-package --save-dev
  2. 修改 package.json,新增命令 postinstall
"scripts": {
	"postinstall": "patch-package"
 }
  1. 修改node_modules里面的代码
  2. 执行命令:npx patch-package qiankunqiankun为组件名/框架名)。

第一次使用patch-package会在项目根目录生成patches文件夹,里面有修改过的文件diff记录。

当这个包版本更新后,执行命令:git apply --ignore-whitespace patches/qiankun+2.0.11.patch 即可。其中qiankun+2.0.11.patch是它生成的文件名。

搞了一下之后发现不生效,随后我就放弃了,可能是技术水平有限,决定自己搞一个,就有了如上代码。

如果大家有更好的处理方式,望不吝赐教。

posted @ 2023-07-04 16:58  Chengo  阅读(41)  评论(0编辑  收藏  举报