123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727 |
- <template>
- <view>
- <view v-if="isShow">
- <view class="date-picker-mask" bubble='true' @click="hide" :class="[isOpen?'show-date-picker-mask':'hide-date-picekr-mask']"
- :style="{backgroundColor:maskColor}"></view>
- <view class="date-picker-container" @click.stop="handleClick" :class="[isOpen?'show-date-picker':'hide-date-picekr']">
- <!-- 操作 -->
- <view class="date-picker-title row between-center">
- <text class="date-picker-cancel" @click="hide">取消</text>
- <text class="date-picker-confirm" @click="dateConfirm">确定</text>
- </view>
- <!-- 内容 -->
- <picker-view class="date-picker-box" v-if="visible" :indicator-style="indicatorStyle" :value="value" @change="bindChange">
- <picker-view-column class="center">
- <view class="date-picker-item center" v-for="(item,index) in years" :key="index">
- <text >{{item}}</text>
- </view>
- </picker-view-column>
- <picker-view-column>
- <view class="date-picker-item center" v-for="(item,index) in months" :key="index">
- <text>{{item}}</text>
- </view>
- </picker-view-column>
- <picker-view-column>
- <view class="date-picker-item center" v-for="(item,index) in days" :key="index">
- <text>{{item}}</text>
- </view>
- </picker-view-column>
- </picker-view>
- </view>
- </view>
- </view>
- </template>
- <script>
- var that
- /**
- * 日期控件
- * @property {String} maskColor 模态框背景色
- * @property {String,Number} checkYear 控件打开默认选中的年份(未传值或传空字符串默认选中的年份为当年)
- * @property {String,Number} checkMonth 控件打开默认选中的月份(未传值或传空字符串默认选中的年份为当月)
- * @property {String,Number} checkDay 控件打开默认选中的日期(未传值或传空字符串默认选中的年份为当日)
- * @property {String,Number} startYear 开始年份,默认为1940
- * @property {String,Number} futureYear 终止年份,今年向后多少年,可选的最晚年份(截止日期未传时生效)
- * @property {Boolean} periodOfValidity = [true | false] 是否是有效期(开启之后选择今天及之前的日期提示日期已过期)
- * @property {Boolean} isShow = [true | false] 开启|关闭
- * @property {String} overdueContent 开启periodOfValidity之后,选择今天及之前的日期提示日期已过期的内容文字
- * @property {Object} endDate 截止日期,可选的最晚日期
- * @property {String,Number} dateStatus 日期类型,默认0没有长期和随时,1长期,2随时
- */
- export default {
- name: "datePicker",
- props: {
- maskColor: {
- type: String,
- default: 'rgba(0,0,0,0.3)'
- },
- checkYear:{
- type: [String,Number],
- default: new Date().getFullYear()
- },
- checkMonth:{
- type: [String,Number],
- default: new Date().getMonth() + 1
- },
- checkDay:{
- type: [String,Number],
- default: new Date().getDate()
- },
- startYear:{
- type: [String,Number],
- default: 1940
- },
- futureYear:{
- type: [String,Number],
- default: 10
- },
- periodOfValidity:{
- type: Boolean,
- default: false
- },
- overdueContent:{
- type: String,
- default: ''
- },
- endDate: {
- type: Object,
- default: () => ({})
- },
- dateStatus:{
- type: [String,Number],
- default: 0
- }
- },
- data() {
- const date = new Date();
- let years = [],months = [];
- if(this.dateStatus==1){
- years = ['长期'];
- months = [''];
- }
- if(this.dateStatus==2){
- years = ['随时'];
- months = [''];
- }
- const currectyear = date.getFullYear()
- const currectmonth = date.getMonth() + 1
- const currectday = date.getDate()
- // console.log(this.checkYear)
- // const month = date.getMonth() + 1
- // const day = date.getDate();
-
- // 传截止日期设置起始年份和终止年份
- if(JSON.stringify(this.endDate)!='{}'){
- if(this.endDate.year&&this.endDate.year<currectyear){
- this.showtoast('截止日期年份必须大于等于当前年份')
- return
- }
- if(this.endDate.year&&this.endDate.year==currectyear&&this.endDate.month&&this.endDate.month<currectmonth){
- this.showtoast('截止日期月份必须大于等于当前月份')
- return
- }
- if(this.endDate.year&&this.endDate.year==currectyear&&this.endDate.month&&this.endDate.month==currectmonth&&this.endDate.day&&this.endDate.day<currectday){
- this.showtoast('截止日期必须大于等于今天')
- return
- }
- var obj=this.createExpirationDate()
- // console.log(obj)
- years=obj.years
- months=obj.months
- }
-
- const year = this.checkYear?this.checkYear:currectyear
- const month = this.checkMonth?Number(this.checkMonth):currectmonth
- const day = this.checkDay?Number(this.checkDay):currectday
-
- console.log(year,month,day)
- // 未传截止日期设置起始年份和终止年份
- if(JSON.stringify(this.endDate)=='{}'){
- for (let i = this.startYear; i <= currectyear + this.futureYear; i++) {
- years.push(i);
- }
- if(this.dateStatus==0&&year=='长期'||this.dateStatus==0&&year=='随时'){
- this.showtoast('当前日期选择器未带长期和随时选项,请修改当前类型')
- return
- }
- if(year!='长期'&&year!='随时'){
- for (let i = 1; i <= 12; i++) {
- months.push(i);
- }
- }
- }
-
- return {
- isShow: false, // 是否弹出
- isOpen: false,
- years,
- months,
- days: [''],
- year,
- month,
- day,
- value: this.dateStatus==0?[Number(year - this.startYear), month-1 , day]:year=='长期'||year=='随时'?[0,0,0]:[Number(year - this.startYear+1), month , day], // 默认选中当天
- visible: true,
- indicatorStyle: `height: ${Math.round(uni.getSystemInfoSync().screenWidth/(750/100))}px;`
- }
- },
- methods: {
- setYearList(){
- const date = new Date();
- let years = [],months = [];
- if(this.dateStatus==1){
- years = ['长期'];
- months = [''];
- }
- if(this.dateStatus==2){
- years = ['随时'];
- months = [''];
- }
- const currectyear = date.getFullYear()
- const currectmonth = date.getMonth() + 1
- const currectday = date.getDate()
- // console.log(this.checkYear)
- // const month = date.getMonth() + 1
- // const day = date.getDate();
-
- // 传截止日期设置起始年份和终止年份
- if(JSON.stringify(this.endDate)!='{}'){
- if(this.endDate.year&&this.endDate.year<currectyear){
- this.showtoast('截止日期年份必须大于等于当前年份')
- return
- }
- if(this.endDate.year&&this.endDate.year==currectyear&&this.endDate.month&&this.endDate.month<currectmonth){
- this.showtoast('截止日期月份必须大于等于当前月份')
- return
- }
- if(this.endDate.year&&this.endDate.year==currectyear&&this.endDate.month&&this.endDate.month==currectmonth&&this.endDate.day&&this.endDate.day<currectday){
- this.showtoast('截止日期必须大于等于今天')
- return
- }
- var obj=this.createExpirationDate()
- // console.log(obj)
- years=obj.years
- }
-
- // console.log(year,month,day)
- // 未传截止日期设置起始年份和终止年份
- if(JSON.stringify(this.endDate)=='{}'){
- for (let i = this.startYear; i <= currectyear + this.futureYear; i++) {
- years.push(i);
- }
- }
- // console.log(years,2222222)
- this.years=years
- },
- createExpirationDate(){
- let years = [],months = [];
- if(this.dateStatus==1){
- years = ['长期'];
- months = [''];
- }
- if(this.dateStatus==2){
- years = ['随时'];
- months = [''];
- }
- var year=this.checkYear?this.checkYear:this.year?this.year:new Date().getFullYear()
- if(this.dateStatus==0&&year=='长期'||this.dateStatus==0&&year=='随时'){
- this.showtoast('当前日期选择器未带长期和随时选项,请修改当前类型')
- return
- }
- for (let i = this.startYear; i <= this.endDate.year; i++) {
- years.push(i);
- }
-
- if(year==this.endDate.year&&this.endDate.month){
- if(year!='长期'||year!='随时'){
- for (let i = 1; i <= this.endDate.month; i++) {
- months.push(i);
- }
- }
- }
- if(year!=this.endDate.year){
- for (let i = 1; i <= 12; i++) {
- months.push(i);
- }
- }
- return {years,months}
- },
- showtoast(content){
- // #ifdef APP-PLUS
- plus.nativeUI.toast(`<font style=\"font-size:15px;margin:20px;\" color="#f56c6c">    ${content?content:this.overdueContent}!    </font>`, {
- icon : "icon URL",// eg. "/img/add.png"
- duration : "long",// 持续3.5s,short---2s
- align : "center",// 水平居中
- verticalAlign : "center",// 垂直底部
- background:'#FEF0F0',
- type: "richtext",
- })
- // #endif
- // #ifdef H5
- uni.showToast({
- title: (content?content:this.overdueContent)+'!',
- icon:'none',
- duration: 2000
- });
- // #endif
- },
- setValue(){
- var val=[]
- console.log(this.days)
- for (let i = 0; i < this.years.length; i++) {
- if(this.year==this.years[i]){
- val[0]=i
- }
- }
- for (let i = 0; i < this.months.length; i++) {
- if(Number(this.month)==this.months[i]){
- val[1]=i
- }
- }
- for (let i = 0; i < this.days.length; i++) {
- if(Number(this.day)==this.days[i]){
- val[2]=i
- }
- }
- return val
- },
- // 选中日期
- dateConfirm() {
- if(this.month==''&&this.year!='长期'&&this.month==''&&this.year!='随时'){
- this.showtoast('未选择月份')
- return
- }
- if(this.day==''&&this.year!='长期'&&this.day==''&&this.year!='随时'){
- this.showtoast('未选择日期')
- return
- }
- if(this.periodOfValidity&&this.year!='长期'&&this.periodOfValidity&&this.year!='随时'){
- const date=new Date()
- const currectyear = date.getFullYear()
- const currectmonth = date.getMonth() + 1
- const currectday = date.getDate()
- if(this.year<currectyear){
- this.showtoast()
- return
- }
- if(this.year==currectyear&&this.month<currectmonth){
- this.showtoast()
- return
- }
- if(this.year==currectyear&&this.month==currectmonth&&this.day<=currectday){
- this.showtoast()
- return
- }
- }
- let dateobj={
- year:this.year,
- month:this.month?this.month > 9 ? this.month : '0' + this.month:'',
- day:this.day?this.day > 9 ? this.day :'0' + this.day:'',
- date:''
- }
- if(this.year!='长期'&&this.year!='随时'){
- this.value=this.setValue()
- dateobj.date= this.year + '-' + (this.month > 9 ? this.month : '0' + this.month) + '-' + (this.day > 9 ? this.day :
- '0' + this.day);
- }else{
- this.value=[0,0,0]
- dateobj.date = this.year
- }
-
- // 发送一个点击事件,并把当前选中的日期发送出去
-
- this.$emit('dateConfirm', dateobj);
- this.hide();
-
- },
- bindChange(e) {
- const date = new Date();
- const year = date.getFullYear()
- const month = date.getMonth() + 1
- const day = date.getDate()
- // console.log(this.value,e)
-
- const val = e.detail.value;
- this.year = this.years[val[0]];
- this.month = this.months[val[1]];
- this.day = this.days[val[2]];
-
- // this.value=[this.year, this.month, this.day]
- },
- // 弹出
- show() {
- this.isShow = true;
- this.$nextTick(() => {
- setTimeout(() => {
- this.isOpen = true;
- }, 20);
- });
- },
- // 关闭
- hide() {
- this.isOpen = false;
- setTimeout(() => {
- this.isShow = false;
- }, 200);
- },
- // 阻止冒泡
- handleClick(event) {
- event.stopPropagation();
- }
- },
- watch: {
- "checkYear":{
- handler(val){
- // console.log(val)
- this.checkYear=val
- this.year=val
- this.$nextTick(() => {
- setTimeout(() => {
- if(val=='长期'||val=='随时'){
- this.value=[0,0,0]
- }
- }, 500);
- })
- }
- },
- 'dateStatus':{
- handler(val){
- this.dateStatus=val
- this.setYearList()
- // console.log(this.years,3333333)
- },
- deep: true,
- immediate: true
- },
- "endDate":{
- handler(val){
- this.endDate=val
- },
- deep: true,
- immediate: true
- },
- "checkMonth":{
- handler(val){
- this.checkMonth=val
- this.month=val
- this.$nextTick(() => {
- setTimeout(() => {
- // console.log(this.month,this.day,this.days)
- if(val!='长期'&&val!='随时'){
- this.value=this.setValue()
- // console.log(this.value)
- }
- }, 500);
- })
- // this.$nextTick(() => {
- // setTimeout(() => {
- // if(val!='长期'&&val!='随时'){
- // this.value=this.setValue()
- // // console.log(this.value)
- // }else{
- // this.value=[0,0,0]
- // }
- // }, 350);
- // })
- }
- },
- "checkDay":{
- handler(val){
- console.log(val,333333)
- this.checkDay=val
- this.day=val
- // this.$nextTick(() => {
- // setTimeout(() => {
- // if(val!='长期'&&val!='随时'){
- // this.value=this.setValue()
- // // console.log(this.value)
- // }else{
- // this.value=[0,0,0]
- // }
- // }, 350);
- // })
- }
- },
- "month": { // 监听月份变化,改变当前月份天数值
- handler(val) {
- console.log(this.endDate)
- if (val < 8&&this.year!='长期'&&val < 8&&this.year!='随时') {
- if (val % 2 !== 0) {
- this.days = [''];
- if(this.endDate.day&&val===this.endDate.month&&this.year===this.endDate.year){
- for (let i = 1; i <= this.endDate.day; i++) {
- this.days.push(i);
- }
- }else{
- for (let i = 1; i <= 31; i++) {
- this.days.push(i);
- }
- }
- } else {
- this.days = [''];
- if(this.endDate.day&&val===this.endDate.month&&this.year===this.endDate.year){
- for (let i = 1; i <= this.endDate.day; i++) {
- this.days.push(i);
- }
- }else{
- for (let i = 1; i <= 30; i++) {
- this.days.push(i);
- }
- }
- }
- }
- if (val > 7&&this.year!='长期'&&val > 7&&this.year!='随时') {
- if (val % 2 === 0) {
- this.days = [''];
- if(this.endDate.day&&val===this.endDate.month&&this.year===this.endDate.year){
- for (let i = 1; i <= this.endDate.day; i++) {
- this.days.push(i);
- }
- }else{
- for (let i = 1; i <= 31; i++) {
- this.days.push(i);
- }
- }
- } else {
- this.days = [''];
- if(this.endDate.day&&val===this.endDate.month&&this.year===this.endDate.year){
- for (let i = 1; i <= this.endDate.day; i++) {
- this.days.push(i);
- }
- }else{
- for (let i = 1; i <= 30; i++) {
- this.days.push(i);
- }
- }
- }
- }
- if (val === 2&&this.year!='长期'&&val === 2&&this.year!='随时') {
- if (this.year % 4 === 0) {
- this.days = [''];
- if(this.endDate.day&&val===this.endDate.month&&this.year===this.endDate.year){
- for (let i = 1; i <= this.endDate.day; i++) {
- this.days.push(i);
- }
- }else{
- for (let i = 1; i <= 29; i++) {
- this.days.push(i);
- }
- }
- } else {
- this.days = [''];
- if(this.endDate.day&&val===this.endDate.month&&this.year===this.endDate.year){
- for (let i = 1; i <= this.endDate.day; i++) {
- this.days.push(i);
- }
- }else{
- for (let i = 1; i <= 28; i++) {
- this.days.push(i);
- }
- }
- }
- }
- },
- deep: true,
- immediate: true
- },
- "year": { // 监听年份变化,处理2月份天数变化
- handler(val) {
- if(val=='长期'||val=='随时'){
- this.months=[''];
- this.days = [''];
- }else{
- const months = [''];
- // console.log(this.endDate)
- if(this.endDate.year&&val===this.endDate.year&&this.endDate.month){
- for (let i = 1; i <= this.endDate.month; i++) {
- months.push(i);
- }
- }else{
- for (let i = 1; i <= 12; i++) {
- months.push(i);
- }
- }
-
- this.months=months
- if (val % 4 === 0) {
- if (this.month === 2) {
- this.days = [''];
- if(this.endDate.year&&val===this.endDate.year&&this.endDate.month&&this.endDate.month===this.month&&this.endDate.day){
- for (let i = 1; i <= this.endDate.day; i++) {
- this.days.push(i);
- }
- }else{
- for (let i = 1; i <= 29; i++) {
- this.days.push(i);
- }
- }
- }
- } else {
- if (this.month === 2) {
- this.days = [''];
- if(this.endDate.year&&val===this.endDate.year&&this.endDate.month&&this.endDate.month===this.month&&this.endDate.day){
- for (let i = 1; i <= this.endDate.day; i++) {
- this.days.push(i);
- }
- }else{
- for (let i = 1; i <= 28; i++) {
- this.days.push(i);
- }
- }
- }
- }
- }
-
- }
- },
- deep: true,
- immediate: true
- }
- }
- </script>
- <style lang="scss">
- .date-picker-mask {
- position: fixed;
- left: 0;
- right: 0;
- top: 0;
- bottom: 0;
- z-index: 99988;
- }
- .date-picker-container {
- position: fixed;
- left: 0;
- right: 0;
- bottom: 0;
- z-index: 99999;
- background-color: #FFFFFF;
- }
- .show-date-picker-mask {
- transition-property: opacity;
- transition-duration: 0.2s;
- transition-timing-function: ease;
- opacity: 1;
- }
- .hide-date-picekr-mask {
- transition-property: opacity;
- transition-duration: 0.2s;
- transition-timing-function: ease;
- opacity: 0;
- }
- .show-date-picker {
- transition-property: transform, opacity;
- transition-duration: 0.2s;
- transition-timing-function: ease;
- transform: translateY(0);
- opacity: 1;
- /* #ifndef APP-PLUS-NVUE */
- -moz-transition-property: transform, opacity;
- -webkit-transition-property: transform, opacity;
- -o-transition-property: transform, opacity;
- -moz-transition-duration: 0.2s;
- -webkit-transition-duration: 0.2s;
- -webkit-transition-duration: 0.2s;
- -moz-transition-timing-function: ease;
- -webkit-transition-timing-function: ease;
- -o-transition-timing-function: ease;
- -moz-transform: translateY(0);
- -webkit-transform: translateY(0);
- -o-transform: translateY(0);
- /* #endif */
- }
- .hide-date-picekr {
- transition-property: transform, opacity;
- transition-duration: 0.2s;
- transition-timing-function: ease;
- transform: translateY(500px);
- opacity: 1;
- /* #ifndef APP-PLUS-NVUE */
- -moz-transition-property: transform, opacity;
- -webkit-transition-property: transform, opacity;
- -o-transition-property: transform, opacity;
- -moz-transition-duration: 0.2s;
- -webkit-transition-duration: 0.2s;
- -webkit-transition-duration: 0.2s;
- -moz-transition-timing-function: ease;
- -webkit-transition-timing-function: ease;
- -o-transition-timing-function: ease;
- -moz-transform: translateY(500px);
- -webkit-transform: translateY(500px);
- -o-transform: translateY(500px);
- /* #endif */
- }
- // 确定、取消
- .date-picker-title {
- height: 100rpx;
- padding: 0 20rpx;
- // box-shadow: 0 1rpx 1rpx #e4e4e4;
- }
- .date-picker-confirm {
- padding: 10rpx 30rpx;
- font-size: 32rpx;
- color: #007AFF;
- }
- .date-picker-cancel {
- padding: 10rpx 30rpx;
- font-size: 32rpx;
- // color: red;
- }
- // 内容
- .date-picker-box {
- width: 750rpx;
- height: 500rpx;
- padding: 0 20rpx;
- /* #ifndef APP-PLUS-NVUE */
- box-sizing: border-box;
- /* #endif */
- background-color: #FFF;
- }
- .date-picker-item {
- height: 100rpx;
- }
- // flex
- .row {
- /* #ifndef APP-PLUS-NVUE */
- display: flex;
- /* #endif */
- flex-direction: row;
- }
- .center {
- /* #ifndef APP-PLUS-NVUE */
- display: flex;
- /* #endif */
- justify-content: center;
- align-items: center;
- }
- .between-center {
- justify-content: space-between;
- align-items: center;
- }
- </style>
|