datepicker.vue 17 KB

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