自定义日期选择器
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
里面的文件更方便
- 安装
patch-package
:npm i patch-package --save-dev
- 修改
package.json
,新增命令postinstall
"scripts": { "postinstall": "patch-package" }
- 修改
node_modules
里面的代码- 执行命令:
npx patch-package qiankun
(qiankun
为组件名/框架名)。第一次使用patch-package会在项目根目录生成patches文件夹,里面有修改过的文件diff记录。
当这个包版本更新后,执行命令:
git apply --ignore-whitespace patches/qiankun+2.0.11.patch
即可。其中qiankun+2.0.11.patch
是它生成的文件名。
搞了一下之后发现不生效,随后我就放弃了,可能是技术水平有限,决定自己搞一个,就有了如上代码。
如果大家有更好的处理方式,望不吝赐教。