datepicker.vue 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468
  1. <template>
  2. <nut-picker
  3. :is-visible="isVisible"
  4. :title="title"
  5. :list-data="listData"
  6. :default-value-data="defaultValueData"
  7. :custom-class-name="`nut-datepicker`"
  8. @close="switchPicker('isVisible')"
  9. @confirm="setChooseValue"
  10. @choose="updateChooseValue"
  11. @close-update="closeUpdateChooseValue"
  12. >
  13. </nut-picker>
  14. </template>
  15. <script>
  16. import nutpicker from '../picker/picker.vue';
  17. import '../picker/picker.scss';
  18. import Utils from '../../utils/date.js';
  19. export default {
  20. name: 'nut-datepicker',
  21. props: {
  22. type: {
  23. type: String,
  24. default: 'date'
  25. },
  26. isSetSecond: {
  27. type: Boolean,
  28. default: false
  29. },
  30. isVisible: {
  31. type: Boolean,
  32. default: true
  33. },
  34. isUse12Hours: {
  35. type: Boolean,
  36. default: false
  37. },
  38. isAm: {
  39. type: Boolean,
  40. default: true
  41. },
  42. minuteStep: {
  43. type: Number,
  44. default: 1
  45. },
  46. secondStep: {
  47. type: Number,
  48. default: 1
  49. },
  50. isShowChinese: {
  51. type: Boolean,
  52. default: true
  53. },
  54. title: {
  55. type: String,
  56. default: null
  57. },
  58. defaultValue: {
  59. type: String,
  60. default: null
  61. },
  62. startDate: {
  63. type: String,
  64. default: '2000-01-01'
  65. },
  66. endDate: {
  67. type: String,
  68. default: Utils.date2Str(new Date())
  69. },
  70. startHour: {
  71. type: Number | String,
  72. default: 0
  73. },
  74. endHour: {
  75. type: Number | String,
  76. default: 23
  77. }
  78. },
  79. data() {
  80. return {
  81. listData: [],
  82. defaultValueData: null,
  83. startDateArr: null,
  84. endDateArr: null,
  85. startYear: null,
  86. endYear: null,
  87. cacheDefaultData: [],
  88. cacheListData: [],
  89. updateYear: null,
  90. updateMonth: null,
  91. updateDay: null,
  92. updateHour: null,
  93. use12Hours: ['上午', '下午'],
  94. chinese: !this.isShowChinese
  95. ? new Array(6).fill('')
  96. : this.type == 'time'
  97. ? this.isUse12Hours
  98. ? ['时', '分', '']
  99. : ['时', '分', '秒']
  100. : ['年', '月', '日', '时', '分']
  101. };
  102. },
  103. components: {
  104. [nutpicker.name]: nutpicker
  105. },
  106. created() {
  107. this.init();
  108. },
  109. computed: {
  110. dateRange() {
  111. const { startDate, endDate, defaultValue } = this;
  112. return { startDate, endDate, defaultValue };
  113. }
  114. },
  115. watch: {
  116. dateRange(newValue, oldValue) {
  117. this.init();
  118. }
  119. },
  120. methods: {
  121. init() {
  122. if (this.startDate && Utils.isDateString(this.startDate)) {
  123. this.startDateArr = Utils.getDateArr(this.startDate);
  124. } else {
  125. this.startDateArr = Utils.getDateArr('2000-01-01');
  126. }
  127. if (this.endDate && Utils.isDateString(this.endDate)) {
  128. this.endDateArr = Utils.getDateArr(this.endDate);
  129. } else {
  130. this.endDateArr = Utils.date2Str(new Date());
  131. }
  132. // 结束时间小于开始时间,结束时间重置为开始时间
  133. if (Utils.compareDateArr(this.endDateArr, this.startDateArr)) {
  134. // this.endDate = this.startDate;
  135. this.endDateArr = this.startDateArr;
  136. }
  137. // this.startDateArr = this.startDate.replace(/-/g, '/').split('/');
  138. // this.endDateArr = this.endDate.replace(/-/g, '/').split('/');
  139. this.initListData();
  140. },
  141. initListData() {
  142. this.resetDefaultValue();
  143. switch (this.type) {
  144. case 'date':
  145. this.cacheListData = [
  146. ...[this.getYears(), this.getMonths(this.defaultValueData[0]), this.getDays(this.defaultValueData[0], this.defaultValueData[1])]
  147. ];
  148. break;
  149. case 'datetime':
  150. this.cacheListData = [
  151. ...[
  152. this.getYears(),
  153. this.getMonths(this.defaultValueData[0]),
  154. this.getDays(this.defaultValueData[0], this.defaultValueData[1]),
  155. this.getChangeHours(this.defaultValueData[0], this.defaultValueData[1], this.defaultValueData[2]),
  156. this.getChangeMinutes(this.defaultValueData[0], this.defaultValueData[1], this.defaultValueData[2], this.defaultValueData[3])
  157. ]
  158. ];
  159. break;
  160. case 'time':
  161. this.cacheListData = [...[this.getHours(), this.getMinutes()]];
  162. if (this.isUse12Hours) {
  163. this.cacheListData = [...this.cacheListData, this.use12Hours];
  164. } else {
  165. this.cacheListData = this.isSetSecond ? [...this.cacheListData, this.getSeconds()] : [...this.cacheListData];
  166. }
  167. break;
  168. }
  169. this.listData = [...this.cacheListData];
  170. },
  171. resetDefaultValue() {
  172. let cacheDefaultValue = null;
  173. if (!this.defaultValue || !Utils.isDateString(this.defaultValue)) {
  174. switch (this.type) {
  175. case 'time':
  176. cacheDefaultValue = this.isSetSecond ? `00:00:00` : `00:00`;
  177. break;
  178. case 'date':
  179. case 'datetime':
  180. cacheDefaultValue = `${this.startDateArr[0]}-${this.startDateArr[1]}-${this.startDateArr[2]} ${this.startDateArr[3]}:${this.startDateArr[4]}`;
  181. break;
  182. }
  183. } else {
  184. cacheDefaultValue = this.defaultValue;
  185. }
  186. let splitArr = cacheDefaultValue.split(' ');
  187. if (this.type === 'time') {
  188. let timeArr = splitArr[0].split(':');
  189. this.isUse12Hours && timeArr.push(this.isAm ? this.use12Hours[0] : this.use12Hours[1]);
  190. this.cacheDefaultData = this.getCacheData(timeArr);
  191. } else {
  192. let cacheData = [...splitArr[0].replace(/-/g, '/').split('/')];
  193. if (this.type == 'datetime') {
  194. cacheData = [...cacheData, ...splitArr[1].split(':')];
  195. }
  196. this.cacheDefaultData = this.getCacheData(cacheData);
  197. this.updateYear = this.cacheDefaultData[0];
  198. this.updateMonth = this.cacheDefaultData[1];
  199. this.updateDay = this.cacheDefaultData[2];
  200. this.updateHour = this.cacheDefaultData[3];
  201. }
  202. this.defaultValueData = [...this.cacheDefaultData];
  203. },
  204. getCacheData(data) {
  205. let cacheData = [];
  206. data.map((item, index) => {
  207. item < 10 && (item = item.replace(/^0/g, ''));
  208. cacheData.push(`${item}${this.chinese[index]}`);
  209. });
  210. return cacheData;
  211. },
  212. getYears() {
  213. let cacheYears = [];
  214. for (var i = this.startDateArr[0]; i <= this.endDateArr[0]; i++) {
  215. cacheYears.push(`${i}${this.chinese[0]}`);
  216. }
  217. return cacheYears;
  218. },
  219. getMonths(year) {
  220. year = this.removeChinese(year);
  221. let cacheMonths = [];
  222. for (var i = 1; i <= 12; i++) {
  223. if (!(year == this.startDateArr[0] && i < this.startDateArr[1]) && !(year == this.endDateArr[0] && i > this.endDateArr[1])) {
  224. cacheMonths.push(`${i}${this.chinese[1]}`);
  225. }
  226. }
  227. return cacheMonths;
  228. },
  229. getDays(year, month) {
  230. year = this.removeChinese(year);
  231. month = this.removeChinese(month);
  232. let days = Array.from(Array(Utils.getMonthDays(year, month)), (v, k) => {
  233. if (
  234. !(year == this.startDateArr[0] && month == parseInt(this.startDateArr[1]) && (k + 1) < parseInt(this.startDateArr[2])) &&
  235. !(year == this.endDateArr[0] && month == parseInt(this.endDateArr[1]) && (k + 1) > parseInt(this.endDateArr[2]))
  236. ) {
  237. return `${k + 1}${this.chinese[2]}`;
  238. }
  239. });
  240. return days.filter(item => item);
  241. },
  242. getChangeHours(year, month, day) {
  243. year = this.removeChinese(year);
  244. month = this.removeChinese(month).padStart(2, '0');
  245. day = this.removeChinese(day).padStart(2, '0');
  246. let hours = Array.from(Array(24).keys()).map(hour => {
  247. let startEqualState = year == this.startDateArr[0] && month == this.startDateArr[1] && day == this.startDateArr[2];
  248. let endEqualState = year == this.endDateArr[0] && month == this.endDateArr[1] && day == this.endDateArr[2];
  249. let startHour = this.startDateArr[3],
  250. endHour = this.endDateArr[3];
  251. let resHour = undefined;
  252. if (startEqualState && endEqualState) {
  253. if (hour >= parseInt(startHour) && hour <= parseInt(endHour)) {
  254. resHour = hour;
  255. }
  256. } else if (startEqualState) {
  257. if (hour >= parseInt(startHour)) {
  258. resHour = hour;
  259. }
  260. } else if (endEqualState) {
  261. if (hour <= parseInt(endHour)) {
  262. resHour = hour;
  263. }
  264. } else {
  265. resHour = hour;
  266. }
  267. if (resHour == 0) {
  268. resHour = '0';
  269. }
  270. return resHour ? `${resHour}${this.chinese[3]}` : undefined;
  271. });
  272. return hours.filter(item => item);
  273. },
  274. getChangeMinutes(year, month, day, hour) {
  275. year = this.removeChinese(year);
  276. month = this.removeChinese(month).padStart(2, '0');
  277. day = this.removeChinese(day).padStart(2, '0');
  278. hour = this.removeChinese(hour).padStart(2, '0');
  279. let minutes = Array.from(Array(60).keys()).map(minute => {
  280. let startEqualState =
  281. year == this.startDateArr[0] && month == this.startDateArr[1] && day == this.startDateArr[2] && hour == this.startDateArr[3];
  282. let endEqualState = year == this.endDateArr[0] && month == this.endDateArr[1] && day == this.endDateArr[2] && hour == this.endDateArr[3];
  283. let startMinute = this.startDateArr[4],
  284. endMinute = this.endDateArr[4];
  285. let resMinute = undefined;
  286. if (startEqualState && endEqualState) {
  287. if (minute >= parseInt(startMinute) && minute <= parseInt(endMinute)) {
  288. resMinute = minute;
  289. }
  290. } else if (startEqualState) {
  291. if (minute >= parseInt(startMinute)) {
  292. resMinute = minute;
  293. }
  294. } else if (endEqualState) {
  295. if (minute <= parseInt(endMinute)) {
  296. resMinute = minute;
  297. }
  298. } else {
  299. resMinute = minute;
  300. }
  301. if (resMinute == 0) {
  302. resMinute = '0';
  303. }
  304. return resMinute % this.minuteStep == 0 ? `${resMinute}${this.chinese[4]}` : undefined;
  305. });
  306. return minutes.filter(item => item);
  307. },
  308. getHours() {
  309. let endHour = this.endHour;
  310. if (this.isUse12Hours) {
  311. endHour = 11;
  312. }
  313. let hours = Array.from(Array(parseInt(endHour) + 1), (v, k) => {
  314. if (this.isUse12Hours && k == 0) {
  315. k = 12;
  316. }
  317. if (k >= this.startHour) {
  318. return `${k}${this.type == 'time' ? this.chinese[0] : this.chinese[3]}`;
  319. }
  320. });
  321. return hours.filter(item => item);
  322. },
  323. getMinutes() {
  324. let minutes = Array.from(Array(60), (v, k) => {
  325. if (k == 0 || k % this.minuteStep == 0) {
  326. return `${k}${this.type == 'time' ? this.chinese[1] : this.chinese[4]}`;
  327. }
  328. });
  329. return minutes.filter(item => item);
  330. },
  331. getSeconds() {
  332. let seconds = Array.from(Array(60), (v, k) => {
  333. if (k == 0 || k % this.secondStep == 0) {
  334. return `${k}${this.type == 'time' ? this.chinese[2] : this.chinese[5]}`;
  335. }
  336. });
  337. return seconds.filter(item => item);
  338. },
  339. setChooseValue(chooseData) {
  340. let cacheChooseData = [];
  341. chooseData.map((item, index) => {
  342. if (this.isUse12Hours && this.type == 'time' && index == 2) {
  343. cacheChooseData.push(item);
  344. } else {
  345. cacheChooseData.push(Utils.getNumTwoBit(this.removeChinese(item)));
  346. }
  347. });
  348. if (/^date/.test(this.type)) {
  349. switch (this.type) {
  350. case 'date':
  351. cacheChooseData.push(`${cacheChooseData[0]}-${cacheChooseData[1]}-${cacheChooseData[2]}`);
  352. break;
  353. case 'datetime':
  354. cacheChooseData.push(`${cacheChooseData[0]}-${cacheChooseData[1]}-${cacheChooseData[2]} ${cacheChooseData[3]}:${cacheChooseData[4]}`);
  355. break;
  356. }
  357. let week = Utils.getWhatDay(cacheChooseData[0], cacheChooseData[1], cacheChooseData[2]);
  358. cacheChooseData.push(week);
  359. } else {
  360. cacheChooseData.push(`${cacheChooseData[0]}:${cacheChooseData[1]}${this.isSetSecond ? ':' + cacheChooseData[2] : ''}`);
  361. }
  362. this.$emit('choose', cacheChooseData);
  363. },
  364. removeChinese(value) {
  365. return value.toString().replace(/([^\u0000-\u00FF])/g, '');
  366. },
  367. updateLinkage(self, index, value, chooseValue, cacheValueData) {
  368. if (!value || !cacheValueData[index] || this.type == 'time') {
  369. return false;
  370. }
  371. value = this.removeChinese(value);
  372. switch (index) {
  373. case 1: //year
  374. this.updateYear = value;
  375. this.listData.splice(index, 1, this.getMonths(value));
  376. chooseValue = chooseValue ? chooseValue : cacheValueData[index];
  377. let curMonthsData = this.listData[index];
  378. if (curMonthsData.indexOf(chooseValue) === -1) {
  379. chooseValue = curMonthsData[0];
  380. }
  381. self && self.updateChooseValue(self, index, chooseValue);
  382. this.updateLinkage(self, 2, cacheValueData[index], null, cacheValueData);
  383. break;
  384. case 2: //month
  385. this.updateMonth = value;
  386. this.listData.splice(index, 1, this.getDays(parseInt(this.updateYear), value));
  387. chooseValue = chooseValue ? chooseValue : cacheValueData[index];
  388. let curDaysData = this.listData[index];
  389. if (curDaysData.indexOf(chooseValue) === -1) {
  390. if (curDaysData.length < 28) {
  391. chooseValue = curDaysData[0];
  392. } else {
  393. let curChooseDay = parseInt(this.removeChinese(chooseValue));
  394. let days = curDaysData.length;
  395. chooseValue = (curChooseDay > days ? days : curChooseDay) + this.chinese[2];
  396. }
  397. }
  398. self && self.updateChooseValue(self, index, chooseValue);
  399. this.updateLinkage(self, 3, cacheValueData[index], null, cacheValueData);
  400. break;
  401. case 3: //day
  402. this.updateDay = value;
  403. this.listData.splice(index, 1, this.getChangeHours(parseInt(this.updateYear), parseInt(this.updateMonth), value));
  404. chooseValue = chooseValue ? chooseValue : cacheValueData[index];
  405. let curHoursData = this.listData[index];
  406. if (curHoursData.indexOf(chooseValue) === -1) {
  407. chooseValue = curHoursData[0];
  408. }
  409. self && self.updateChooseValue(self, index, chooseValue);
  410. this.updateLinkage(self, 4, cacheValueData[index], null, cacheValueData);
  411. break;
  412. case 4: //hour
  413. this.updateHour = value;
  414. this.listData.splice(
  415. index,
  416. 1,
  417. this.getChangeMinutes(parseInt(this.updateYear), parseInt(this.updateMonth), parseInt(this.updateDay), parseInt(this.updateHour), value)
  418. );
  419. chooseValue = chooseValue ? chooseValue : cacheValueData[index];
  420. let curMinuteData = this.listData[index];
  421. if (curMinuteData.indexOf(chooseValue) === -1) {
  422. chooseValue = curMinuteData[0];
  423. }
  424. self && self.updateChooseValue(self, index, chooseValue);
  425. }
  426. },
  427. updateChooseValue(self, index, value, cacheValueData) {
  428. switch (index) {
  429. case 0: //year
  430. case 1: //month
  431. case 2: //day
  432. case 3: //hour
  433. this.updateLinkage(self, index + 1, value, null, cacheValueData);
  434. break;
  435. case 4: //min
  436. break;
  437. }
  438. },
  439. closeUpdateChooseValue(self, chooseData) {
  440. this.updateLinkage(self, 1, chooseData[0], chooseData[1], chooseData);
  441. },
  442. switchPicker(param) {
  443. this.$emit('close');
  444. }
  445. }
  446. };
  447. </script>