index.js 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379
  1. import CustomPickerView from '../customPickerView/index.vue';
  2. import DateUtil from '../dateTimePicker/dateUtil';
  3. import { DATE_TYPES } from './constant';
  4. export default {
  5. components: {
  6. CustomPickerView
  7. },
  8. props: {
  9. // 日期模式,1:年月日(默认),2:年月,3:年份,4:年月日时分秒,5:时分秒,6:时分
  10. mode: {
  11. type: Number,
  12. default: DATE_TYPES.YMD
  13. },
  14. // 可选的最小日期,默认十年前
  15. minDate: {
  16. type: String,
  17. default: ''
  18. },
  19. // 可选的最大日期,默认十年后
  20. maxDate: {
  21. type: String,
  22. default: ''
  23. },
  24. // 默认选中日期(注意要跟日期模式对应)
  25. defaultDate: {
  26. type: String,
  27. default: ''
  28. }
  29. },
  30. data() {
  31. return {
  32. selectYear: new Date().getFullYear(),
  33. selectMonth: new Date().getMonth() + 1, // 选中的月份,1~12
  34. selectDay: new Date().getDate(),
  35. selectHour: new Date().getHours(),
  36. selectMinute: new Date().getMinutes(),
  37. selectSecond: new Date().getSeconds()
  38. };
  39. },
  40. watch: {
  41. defaultDate: {
  42. immediate: true,
  43. handler(val) {
  44. if (val) {
  45. if (this.mode == DATE_TYPES.YM && val.replace(/\-/g, '/').split('/').length == 2) {
  46. // 日期模式为年月时有可能传进来的defaultDate是2022-02这样的格式,在ios下new Date会报错,加上日期部分做兼容
  47. val += '-01';
  48. } else if (this.mode == DATE_TYPES.HMS || this.mode == DATE_TYPES.HM) {
  49. // 只有时分秒或者只有时分是不能调用new Date生成Date对象的,先加上一个假设的年月日(就取当年一月一日)来兼容
  50. const now = new Date();
  51. val = `${now.getFullYear()}-01-01 ${val}`;
  52. }
  53. let date = new Date(DateUtil.handleDateStr(val));
  54. this.selectYear = date.getFullYear();
  55. this.selectMonth = date.getMonth() + 1;
  56. this.selectDay = date.getDate();
  57. this.selectHour = date.getHours();
  58. this.selectMinute = date.getMinutes();
  59. this.selectSecond = date.getSeconds();
  60. }
  61. }
  62. }
  63. },
  64. computed: {
  65. minDateObj() {
  66. let minDate = this.minDate;
  67. if (minDate) {
  68. if (this.mode == DATE_TYPES.YM && minDate.replace(/\-/g, '/').split('/').length == 2) {
  69. // 日期模式为年月时有可能传进来的minDate是2022-02这样的格式,在ios下new Date会报错,加上日期部分做兼容
  70. minDate += '-01';
  71. } else if (this.mode == DATE_TYPES.HMS || this.mode == DATE_TYPES.HM) {
  72. // 只有时分秒或者只有时分是不能调用new Date生成Date对象的,先加上一个假设的年月日(就取当年一月一日)来兼容
  73. const now = new Date();
  74. minDate = `${now.getFullYear()}-01-01 ${minDate}`;
  75. }
  76. return new Date(DateUtil.handleDateStr(minDate));
  77. } else {
  78. // 没有传最小日期,默认十年前
  79. let year = new Date().getFullYear() - 10;
  80. minDate = new Date(year, 0, 1);
  81. return minDate;
  82. }
  83. },
  84. maxDateObj() {
  85. let maxDate = this.maxDate;
  86. if (maxDate) {
  87. if (this.mode == DATE_TYPES.YM && maxDate.replace(/\-/g, '/').split('/').length == 2) {
  88. // 日期模式为年月时有可能传进来的maxDate是2022-02这样的格式,在ios下new Date会报错,加上日期部分做兼容
  89. maxDate += '-01';
  90. } else if (this.mode == DATE_TYPES.HMS || this.mode == DATE_TYPES.HM) {
  91. // 只有时分秒或者只有时分是不能调用new Date生成Date对象的,先加上一个假设的年月日(就取当年一月一日)来兼容
  92. const now = new Date();
  93. maxDate = `${now.getFullYear()}-01-01 ${maxDate}`;
  94. }
  95. return new Date(DateUtil.handleDateStr(maxDate));
  96. } else {
  97. // 没有传最大日期,默认十年后
  98. let year = new Date().getFullYear() + 10;
  99. maxDate = new Date(year, 11, 31);
  100. return maxDate;
  101. }
  102. },
  103. years() {
  104. let years = [];
  105. let minYear = this.minDateObj.getFullYear();
  106. let maxYear = this.maxDateObj.getFullYear();
  107. for (let i = minYear; i <= maxYear; i++) {
  108. years.push(i);
  109. }
  110. return years;
  111. },
  112. months() {
  113. let months = [];
  114. let minMonth = 1;
  115. let maxMonth = 12;
  116. // 如果选中的年份刚好是最小可选日期的年份,那月份就要从最小日期的月份开始
  117. if (this.selectYear == this.minDateObj.getFullYear()) {
  118. minMonth = this.minDateObj.getMonth() + 1;
  119. }
  120. // 如果选中的年份刚好是最大可选日期的年份,那月份就要在最大日期的月份结束
  121. if (this.selectYear == this.maxDateObj.getFullYear()) {
  122. maxMonth = this.maxDateObj.getMonth() + 1;
  123. }
  124. for (let i = minMonth; i <= maxMonth; i++) {
  125. months.push(i);
  126. }
  127. return months;
  128. },
  129. days() {
  130. // 一年中12个月每个月的天数
  131. let monthDaysConfig = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
  132. // 闰年2月有29天
  133. if (this.selectMonth == 2 && this.selectYear % 4 == 0) {
  134. monthDaysConfig[1] = 29;
  135. }
  136. let minDay = 1;
  137. let maxDay = monthDaysConfig[this.selectMonth - 1];
  138. if (this.selectYear == this.minDateObj.getFullYear() && this.selectMonth == this.minDateObj.getMonth() + 1) {
  139. minDay = this.minDateObj.getDate();
  140. }
  141. if (this.selectYear == this.maxDateObj.getFullYear() && this.selectMonth == this.maxDateObj.getMonth() + 1) {
  142. maxDay = this.maxDateObj.getDate();
  143. }
  144. let days = [];
  145. for (let i = minDay; i <= maxDay; i++) {
  146. days.push(i);
  147. }
  148. return days;
  149. },
  150. hours() {
  151. let hours = [];
  152. let minHour = 0;
  153. let maxHour = 23;
  154. if (
  155. this.selectYear == this.minDateObj.getFullYear() &&
  156. this.selectMonth == this.minDateObj.getMonth() + 1 &&
  157. this.selectDay == this.minDateObj.getDate()
  158. ) {
  159. minHour = this.minDateObj.getHours();
  160. }
  161. if (
  162. this.selectYear == this.maxDateObj.getFullYear() &&
  163. this.selectMonth == this.maxDateObj.getMonth() + 1 &&
  164. this.selectDay == this.maxDateObj.getDate()
  165. ) {
  166. maxHour = this.maxDateObj.getHours();
  167. }
  168. for (let i = minHour; i <= maxHour; i++) {
  169. hours.push(i);
  170. }
  171. return hours;
  172. },
  173. minutes() {
  174. let mins = [];
  175. let minMin = 0;
  176. let maxMin = 59;
  177. if (
  178. this.selectYear == this.minDateObj.getFullYear() &&
  179. this.selectMonth == this.minDateObj.getMonth() + 1 &&
  180. this.selectDay == this.minDateObj.getDate() &&
  181. this.selectHour == this.minDateObj.getHours()
  182. ) {
  183. minMin = this.minDateObj.getMinutes();
  184. }
  185. if (
  186. this.selectYear == this.maxDateObj.getFullYear() &&
  187. this.selectMonth == this.maxDateObj.getMonth() + 1 &&
  188. this.selectDay == this.maxDateObj.getDate() &&
  189. this.selectHour == this.maxDateObj.getHours()
  190. ) {
  191. maxMin = this.maxDateObj.getMinutes();
  192. }
  193. for (let i = minMin; i <= maxMin; i++) {
  194. mins.push(i);
  195. }
  196. return mins;
  197. },
  198. seconds() {
  199. let seconds = [];
  200. let minSecond = 0;
  201. let maxSecond = 59;
  202. if (
  203. this.selectYear == this.minDateObj.getFullYear() &&
  204. this.selectMonth == this.minDateObj.getMonth() + 1 &&
  205. this.selectDay == this.minDateObj.getDate() &&
  206. this.selectHour == this.minDateObj.getHours() &&
  207. this.selectMinute == this.minDateObj.getMinutes()
  208. ) {
  209. minSecond = this.minDateObj.getSeconds();
  210. }
  211. if (
  212. this.selectYear == this.maxDateObj.getFullYear() &&
  213. this.selectMonth == this.maxDateObj.getMonth() + 1 &&
  214. this.selectDay == this.maxDateObj.getDate() &&
  215. this.selectHour == this.maxDateObj.getHours() &&
  216. this.selectMinute == this.maxDateObj.getMinutes()
  217. ) {
  218. maxSecond = this.maxDateObj.getSeconds();
  219. }
  220. for (let i = minSecond; i <= maxSecond; i++) {
  221. seconds.push(i);
  222. }
  223. return seconds;
  224. },
  225. // 传给pickerView组件的数组,根据mode来生成不同的数据
  226. dateConfig() {
  227. let years = this.years.map((y) => y + '年');
  228. let months = this.months.map((m) => m + '月');
  229. let days = this.days.map((d) => d + '日');
  230. let hours = this.hours.map((h) => h + '时');
  231. let minutes = this.minutes.map((m) => m + '分');
  232. let seconds = this.seconds.map((s) => s + '秒');
  233. let ret = [];
  234. switch (this.mode) {
  235. case DATE_TYPES.YM:
  236. ret = [years, months];
  237. break;
  238. case DATE_TYPES.Y:
  239. ret = [years];
  240. break;
  241. case DATE_TYPES['YMD-HMS']:
  242. ret = [years, months, days, hours, minutes, seconds];
  243. break;
  244. case DATE_TYPES.HMS:
  245. ret = [hours, minutes, seconds];
  246. break;
  247. case DATE_TYPES.HM:
  248. ret = [hours, minutes];
  249. break;
  250. default:
  251. ret = [years, months, days];
  252. break;
  253. }
  254. return ret;
  255. },
  256. selectVals() {
  257. let ret = [];
  258. switch (this.mode) {
  259. case DATE_TYPES.YM:
  260. ret = [this.selectYear + '年', this.selectMonth + '月'];
  261. break;
  262. case DATE_TYPES.Y:
  263. ret = [this.selectYear + '年'];
  264. break;
  265. case DATE_TYPES['YMD-HMS']:
  266. ret = [
  267. this.selectYear + '年',
  268. this.selectMonth + '月',
  269. this.selectDay + '日',
  270. this.selectHour + '时',
  271. this.selectMinute + '分',
  272. this.selectSecond + '秒'
  273. ];
  274. break;
  275. case DATE_TYPES.HMS:
  276. ret = [this.selectHour + '时', this.selectMinute + '分', this.selectSecond + '秒'];
  277. break;
  278. case DATE_TYPES.HM:
  279. ret = [this.selectHour + '时', this.selectMinute + '分'];
  280. break;
  281. default:
  282. ret = [this.selectYear + '年', this.selectMonth + '月', this.selectDay + '日'];
  283. break;
  284. }
  285. return ret;
  286. }
  287. },
  288. methods: {
  289. onChangePickerValue(e) {
  290. const { value } = e;
  291. if (this.mode == DATE_TYPES.YM && value[0] && value[1]) {
  292. // 年月模式
  293. this.selectYear = Number(value[0].replace('年', ''));
  294. this.selectMonth = Number(value[1].replace('月', ''));
  295. } else if (this.mode == DATE_TYPES.Y && value[0]) {
  296. // 只有年份模式
  297. this.selectYear = Number(value[0].replace('年', ''));
  298. } else if (this.mode == DATE_TYPES['YMD-HMS'] && value[0] && value[1] && value[2] != '' && value[3] && value[4] && value[5]) {
  299. // 年月日时分秒模式
  300. this.selectYear = Number(value[0].replace('年', ''));
  301. this.selectMonth = Number(value[1].replace('月', ''));
  302. this.selectDay = Number(value[2].replace('日', ''));
  303. this.selectHour = Number(value[3].replace('时', ''));
  304. this.selectMinute = Number(value[4].replace('分', ''));
  305. this.selectSecond = Number(value[5].replace('秒', ''));
  306. } else if (this.mode == DATE_TYPES.HMS && value[0] && value[1] && value[2]) {
  307. // 时分秒模式
  308. this.selectHour = Number(value[0].replace('时', ''));
  309. this.selectMinute = Number(value[1].replace('分', ''));
  310. this.selectSecond = Number(value[2].replace('秒', ''));
  311. } else if (this.mode == DATE_TYPES.HM && value[0] && value[1]) {
  312. // 时分模式
  313. this.selectHour = Number(value[0].replace('时', ''));
  314. this.selectMinute = Number(value[1].replace('分', ''));
  315. } else if (value[0] && value[1] && value[2]) {
  316. // 默认,年月日模式
  317. this.selectYear = Number(value[0].replace('年', ''));
  318. this.selectMonth = Number(value[1].replace('月', ''));
  319. this.selectDay = Number(value[2].replace('日', ''));
  320. } else {
  321. // 其他情况可能是pickerView返回的数据有问题,不处理
  322. console.log('onChangePickerValue其他情况');
  323. return;
  324. }
  325. let formatTmpl = 'YYYY-MM-DD';
  326. switch (this.mode) {
  327. case DATE_TYPES.YM:
  328. formatTmpl = 'YYYY-MM';
  329. break;
  330. case DATE_TYPES.Y:
  331. formatTmpl = 'YYYY';
  332. break;
  333. case DATE_TYPES['YMD-HMS']:
  334. formatTmpl = 'YYYY-MM-DD HH:mm';
  335. break;
  336. case DATE_TYPES.HMS:
  337. formatTmpl = 'HH:mm:ss';
  338. break;
  339. case DATE_TYPES.HM:
  340. formatTmpl = 'HH:mm';
  341. break;
  342. default:
  343. break;
  344. }
  345. this.$emit(
  346. 'onChange',
  347. DateUtil.formatDate(
  348. new Date(`${this.selectYear}/${this.selectMonth}/${this.selectDay} ${this.selectHour}:${this.selectMinute}:${this.selectSecond}`),
  349. formatTmpl
  350. )
  351. );
  352. }
  353. }
  354. };