当前位置:   article > 正文

uniapp、小程序自定义选择日、周、月、季、年的时间选择器组件_uniapp日期选择

uniapp日期选择

目录

代码分享

utils文件

uniapp使用插件使用

zdp-date-picker使用说明


本组件用到了uni-ui的uni-popup弹窗组件

废话不多说直接上代码

代码分享

  1. <template>
  2. <view class="content-pop">
  3. <uni-popup ref="popup" type="bottom">
  4. <view class="zdp-pop">
  5. <view class="top-cont">
  6. <view class="close-cont" @click="close(1)">
  7. 取消
  8. </view>
  9. <!-- 可以自定义显示 -->
  10. <slot name="text" :scope="{range,zdpdate}">
  11. <view class="text-info">
  12. 请选择时间
  13. <view>
  14. {{selInfo}}
  15. </view>
  16. </view>
  17. </slot>
  18. <view class="save-cont" @click="close(2)">
  19. 确认
  20. </view>
  21. </view>
  22. <view class="tabs-cont">
  23. <view class="tab-list" v-for="item in tabs" :class="item.value==activeIdx?'active':''"
  24. @click="handleTabs(item.value)">
  25. {{item.label}}
  26. </view>
  27. </view>
  28. <view class="date-cont">
  29. <picker-view :value="value" @change="handleChange" class="picker-view">
  30. <picker-view-column v-for="obj in SelArr">
  31. <view class="item" v-for="(item,index) in obj.child" :key="index">{{item}}{{obj.value}}
  32. </view>
  33. </picker-view-column>
  34. </picker-view>
  35. </view>
  36. </view>
  37. </uni-popup>
  38. </view>
  39. </template>
  40. <script>
  41. import {
  42. whichWeek
  43. } from '../../utils/getWeek.js'
  44. import {
  45. getMonthStartEnd
  46. } from '../../utils/getMonth.js'
  47. import {
  48. getQuarterDates
  49. } from '../../utils/getQuarter.js'
  50. export default {
  51. props: {
  52. type: {
  53. type: String,
  54. default: '日',
  55. validator(value, props) {
  56. return ['日', '月', '周', '年', '季'].includes(value)
  57. }
  58. },
  59. time: {
  60. type: String, //'2024-1-1' '2024-2' '2024-2' '2024-2' '2024
  61. }
  62. },
  63. data() {
  64. return {
  65. tabs: [{
  66. label: '日',
  67. value: '日'
  68. },
  69. {
  70. label: '周',
  71. value: '周',
  72. },
  73. {
  74. label: '月',
  75. value: '月',
  76. },
  77. {
  78. label: '季',
  79. value: '季',
  80. },
  81. {
  82. label: '年',
  83. value: '年',
  84. }
  85. ],
  86. activeIdx: '日',
  87. value: [], //选择的值,要设置默认值
  88. dateArr: [],
  89. day: 18,
  90. week: 1,
  91. month: 1, //
  92. quarter: 2,
  93. years: 24,
  94. SelArr: [],
  95. range: '',
  96. zdpdate: ''
  97. }
  98. },
  99. computed: {
  100. selInfo() {
  101. let str = ''
  102. let {
  103. activeIdx,
  104. years,
  105. day,
  106. month,
  107. week,
  108. quarter
  109. } = this
  110. if (activeIdx == '日') {
  111. str = `20${years}年 ${month<10?'0'+month:month}月 ${day}日`
  112. } else if (activeIdx == '周') {
  113. str = `20${years}年 第${week}周`
  114. } else if (activeIdx == '月') {
  115. str = `20${years}年 ${month<10?'0'+month:month}月`
  116. } else if (activeIdx == '季') {
  117. str = `20${years}年 ${quarter}季`
  118. } else if (activeIdx == '年') {
  119. str = `20${years}年`
  120. }
  121. return str
  122. }
  123. },
  124. created() {
  125. },
  126. methods: {
  127. //
  128. handleProps() {
  129. let arr = []
  130. arr = this.time.split('-')
  131. if (this.type == '日') {
  132. this.month = arr[1] - 0
  133. this.day = arr[2] - 0
  134. } else if (this.type == '周') {
  135. this.week = arr[1] - 0
  136. } else if (this.type == '季') {
  137. this.quarter = arr[1] - 0
  138. } else if (this.type == '月') {
  139. this.month = arr[1] - 0
  140. this.quarter = this.handleQuarter(this.month)
  141. }
  142. for (let i = 0; i < arr.length; i++) {
  143. if (i == 0) {
  144. arr[0] = arr[0].slice(2)
  145. arr[0] -= 0
  146. this.years = arr[0]
  147. } else {
  148. arr[i]--
  149. }
  150. }
  151. this.value = arr
  152. },
  153. // 初始化
  154. newDate() {
  155. // this.activeIdx=this.type
  156. const date = new Date()
  157. this.day = date.getDate()
  158. this.years = date.getFullYear()
  159. this.week = this.getYearWeek(date)
  160. this.quarter = this.handleQuarter(this.month)
  161. this.month = date.getMonth() + 1
  162. this.handleTabs(this.type)
  163. if (this.time) {
  164. this.handleProps()
  165. }
  166. this.initArr()
  167. },
  168. initArr() {
  169. const date = new Date()
  170. let arr = []
  171. let {
  172. activeIdx,
  173. } = this
  174. let day = []
  175. let week = []
  176. let month = []
  177. let quarter = []
  178. let years = []
  179. for (let i = 2000; i <= date.getFullYear(); i++) {
  180. years.push(i)
  181. }
  182. for (let i = 1; i <= 12; i++) {
  183. month.push(i)
  184. }
  185. let weekArr = whichWeek(`20${this.years}`)
  186. for (let i = 1; i <= weekArr.length; i++) {
  187. week.push(i)
  188. }
  189. for (let i = 1; i <= 4; i++) {
  190. quarter.push(i)
  191. }
  192. if (activeIdx == '日') {
  193. let num = this.getMonthDays(this.years, this.month)
  194. for (let i = 1; i <= num; i++) {
  195. day.push(i)
  196. }
  197. arr = [{
  198. value: "年",
  199. child: years
  200. }, {
  201. value: "月",
  202. child: month
  203. }, {
  204. value: "日",
  205. child: day
  206. }]
  207. this.zdpdate = `20${this.years}-${this.month<10?'0'+this.month:this.month}-${this.day}`
  208. this.range = `20${this.years}-${this.month<10?'0'+this.month:this.month}-${this.day}`
  209. } else if (activeIdx == '月') {
  210. arr = [{
  211. value: "年",
  212. child: years
  213. }, {
  214. value: "月",
  215. child: month
  216. }]
  217. // console.log(this.years,'年22');
  218. this.zdpdate = `20${this.years}-${this.month<10?'0'+this.month:this.month}`
  219. this.range = getMonthStartEnd(this.zdpdate)
  220. } else if (activeIdx == '年') {
  221. arr = [{
  222. value: "年",
  223. child: years
  224. }]
  225. this.zdpdate = `20${this.years}`
  226. this.range = `20${this.years}-1-31/20${this.years}-12-31`
  227. } else if (activeIdx == '周') {
  228. arr = [{
  229. value: "年",
  230. child: years
  231. }, {
  232. value: "周",
  233. child: week
  234. }]
  235. this.zdpdate = `20${this.years}年 第${this.week}周`
  236. let wk = weekArr[this.week - 1]
  237. this.range = `${wk.year}-${wk.month}-${wk.date}` + '/' +
  238. `${wk.last.year}-${wk.last.month}-${wk.last.date}`
  239. } else if (activeIdx == '季') {
  240. arr = [{
  241. value: "年",
  242. child: years
  243. }, {
  244. value: "季度",
  245. child: quarter
  246. }]
  247. this.zdpdate = `20${this.years}年 ${this.quarter}季度`
  248. let obj = getQuarterDates(`20${this.years}`, this.quarter)
  249. this.range = obj.startDate + '/' + obj.endDate
  250. }
  251. this.SelArr = arr
  252. },
  253. open() {
  254. this.newDate()
  255. this.$refs.popup.open('bottom')
  256. },
  257. close(num) {
  258. if (num == 1) {
  259. this.newDate()
  260. this.handleEmit()
  261. } else {
  262. this.handleEmit()
  263. }
  264. this.$refs.popup.close()
  265. },
  266. handleEmit() {
  267. let {
  268. zdpdate,
  269. range,
  270. } = this
  271. this.$emit('submit-date', {
  272. zdpdate,
  273. range,
  274. type: this.activeIdx
  275. })
  276. },
  277. handleTabs(val) {
  278. this.activeIdx = val
  279. let {
  280. activeIdx,
  281. years,
  282. month,
  283. day,
  284. quarter,
  285. week
  286. } = this
  287. if (activeIdx == '日') {
  288. this.value = [years, month - 1, day - 1]
  289. } else if (activeIdx == '周') {
  290. this.value = [years, week - 1]
  291. } else if (activeIdx == '月') {
  292. this.value = [years, month - 1]
  293. } else if (activeIdx == '季') {
  294. this.value = [years, quarter - 1, ]
  295. } else if (activeIdx == '年') {
  296. this.value = [years]
  297. }
  298. console.log(this.value, '选择的日期');
  299. this.initArr()
  300. },
  301. // 选择器选择
  302. handleChange(e) {
  303. let {
  304. value
  305. } = e.detail
  306. let {
  307. activeIdx
  308. } = this
  309. console.log(value);
  310. // 年小于前面+0
  311. if (value[0] < 10) {
  312. value[0] = '0' + value[0]
  313. }
  314. this.years = value[0]
  315. if (activeIdx == '日') {
  316. this.month = value[1] + 1 //月
  317. this.day = value[2] + 1 //日
  318. } else if (activeIdx == '周') {
  319. this.week = value[1] + 1 //周
  320. } else if (activeIdx == '季') {
  321. this.quarter = value[1] + 1
  322. } else if (activeIdx == '月') {
  323. this.month = value[1] + 1 //月
  324. }
  325. this.initArr()
  326. },
  327. //获取当前月的天数
  328. getMonthDays(year, month) {
  329. var thisDate = new Date(year, month, 0);
  330. return thisDate.getDate();
  331. },
  332. getYearWeek(endDate) {
  333. //本年的第一天
  334. let beginDate = new Date(endDate.getFullYear(), 0, 1);
  335. //星期从0-6,0代表星期天,6代表星期六
  336. let endWeek = endDate.getDay();
  337. if (endWeek == 0) endWeek = 7;
  338. let beginWeek = beginDate.getDay();
  339. if (beginWeek == 0) beginWeek = 7;
  340. //计算两个日期的天数差
  341. let millisDiff = endDate.getTime() - beginDate.getTime();
  342. let dayDiff = Math.floor((millisDiff + (beginWeek - endWeek) * (24 * 60 * 60 * 1000)) / 86400000);
  343. return Math.ceil(dayDiff / 7) + 1;
  344. },
  345. handleQuarter(month) {
  346. const oneQuarter = [1, 2, 3]
  347. const twoQuarter = [4, 5, 6]
  348. const threeQuarter = [7, 8, 9]
  349. let num
  350. if (oneQuarter.includes(month)) {
  351. num = 1
  352. } else if (twoQuarter.includes(month)) {
  353. num = 2
  354. } else if (threeQuarter.includes(month)) {
  355. num = 3
  356. } else {
  357. num = 4
  358. }
  359. return num
  360. }
  361. }
  362. }
  363. </script>
  364. <style lang="scss" scoped>
  365. * {
  366. box-sizing: border-box;
  367. }
  368. .zdp-pop {
  369. box-sizing: border-box;
  370. padding: 24rpx;
  371. width: 100%;
  372. height: 750rpx;
  373. background-color: #fff;
  374. .top-cont {
  375. height: 100rpx;
  376. display: flex;
  377. justify-content: space-between;
  378. align-items: center;
  379. margin-bottom: 32rpx;
  380. .close-cont {
  381. color: #aaa;
  382. letter-spacing: 6rpx;
  383. }
  384. .text-info {
  385. display: flex;
  386. flex-direction: column;
  387. align-items: center;
  388. }
  389. .save-cont {
  390. background: #409EFF;
  391. color: #fff;
  392. width: 100rpx;
  393. height: 60rpx;
  394. text-align: center;
  395. line-height: 60rpx;
  396. border-radius: 6rpx;
  397. }
  398. }
  399. .tabs-cont {
  400. box-sizing: border-box;
  401. height: 80rpx;
  402. background-color: #F3F5F9;
  403. display: flex;
  404. align-items: center;
  405. border-radius: 4rpx;
  406. padding: 0 10rpx;
  407. .tab-list {
  408. min-width: 20%;
  409. display: flex;
  410. height: 60%;
  411. flex: 1;
  412. justify-content: center;
  413. border-radius: 4rpx;
  414. &.active {
  415. background-color: #fff;
  416. }
  417. }
  418. }
  419. .date-cont {
  420. height: calc(750rpx - 180rpx);
  421. .picker-view {
  422. width: 100%;
  423. height: 100%;
  424. .item {
  425. display: flex;
  426. justify-content: center;
  427. align-items: center;
  428. }
  429. .uni-picker-view-indicator {
  430. height: 100rpx;
  431. }
  432. }
  433. }
  434. }
  435. </style>

utils文件

@/utils/getMonth.js
  1. //获取这个月的月初和月末
  2. export function getMonthStartEnd(vars){
  3. var str = '';
  4. if(vars!=null&&vars!=''){
  5. var nyYear=vars.slice(0,4);
  6. var nyMonth=vars.slice(5,vars.length);
  7. var firstDay = new Date(nyYear,nyMonth-1);
  8. var lastDay = new Date(new Date(nyYear,nyMonth).valueOf()-60*60*1000*24);
  9. function datasFormat(d){
  10. var datetime=d.getFullYear() + '-' + (d.getMonth() + 1) + '-' + d.getDate();
  11. return datetime;
  12. }
  13. str = datasFormat(firstDay) + "/" + datasFormat(lastDay)
  14. }
  15. return str
  16. }
@/utils/getQuarter.js
  1. export function getQuarterDates(year, quarter) {
  2. const startDate = new Date(year, (quarter - 1) * 3, 1);
  3. const endDate = new Date(year, quarter * 3, 0);
  4. const startDay = startDate.getDate();
  5. const endDay = endDate.getDate();
  6. const startMonth = startDate.getMonth() + 1;
  7. const endMonth = endDate.getMonth() + 1;
  8. const startYear = startDate.getFullYear();
  9. const endYear = endDate.getFullYear();
  10. const startDateString =
  11. `${startYear}-${startMonth < 10 ? '0' + startMonth : startMonth}-${startDay < 10 ? '0' + startDay : startDay}`;
  12. const endDateString =
  13. `${endYear}-${endMonth < 10 ? '0' + endMonth : endMonth}-${endDay < 10 ? '0' + endDay : endDay}`;
  14. return {
  15. startDate: startDateString,
  16. endDate: endDateString
  17. };
  18. }
  19. // // 示例用法:计算2024年第2季度的起止日期
  20. // const quarterDates = getQuarterDates(2024,2);
  21. // console.log(quarterDates.startDate); // 输出:2024-04-01
  22. // console.log(quarterDates.endDate); // 输出:2024-06-30
@/utils/getWeek.js
  1. //时间戳转年月日 参数是秒的时间戳 函数返回一个对象 对象里有年 月 日
  2. export function yearDay(long){
  3. var time = new Date(long * 1000)
  4. var year = time.getFullYear();
  5. var month = (time.getMonth()+1) < 10 ? '0' + (time.getMonth()+1) : (time.getMonth()+1);
  6. var date = time.getDate() < 10 ? '0' + time.getDate() : time.getDate() ;
  7. var yearday = {year,month,date}
  8. return yearday
  9. }
  10. //计算一年中的每一周都是从几号到几号
  11. //第一周为1月1日到 本年的 第一个周日
  12. //第二周为 本年的 第一个周一 往后推到周日
  13. //以此类推 再往后推52周。。。
  14. //如果最后一周在12月31日之前,则本年有垮了54周,反之53周
  15. //12月31 日不论是周几,都算为本周的最后一天
  16. //参数年份 ,函数返回一个数组,数组里的对象包含 这一周的开始日期和结束日期
  17. export function whichWeek(year){
  18. var d = new Date(year, 0, 1);
  19. while (d.getDay() != 1) {
  20. d.setDate(d.getDate() + 1);
  21. }
  22. let arr = []
  23. let longnum = d.setDate(d.getDate())
  24. if(longnum > +new Date(year, 0, 1)){
  25. let obj = yearDay(+new Date(year, 0, 1) / 1000)
  26. obj.last = yearDay( longnum / 1000 - 86400)
  27. arr.push(obj)
  28. }
  29. let oneitem = yearDay(longnum / 1000)
  30. oneitem.last = yearDay( longnum / 1000 + 86400 * 6)
  31. arr.push(oneitem)
  32. var lastStr
  33. for(var i = 0 ; i<51 ;i++){
  34. let long = d.setDate(d.getDate() + 7)
  35. let obj = yearDay( long / 1000)
  36. obj.last = yearDay( long / 1000 + 86400 * 6)
  37. lastStr = long + 86400000 * 6
  38. arr.push(obj)
  39. }
  40. if(lastStr < +new Date(year + 1, 0, 1)){
  41. let obj = yearDay(lastStr / 1000 + 86400)
  42. obj.last = yearDay(+new Date(year + 1, 0, 1) / 1000 - 86400)
  43. arr.push(obj)
  44. }else{
  45. arr[arr.length-1].last = yearDay(+new Date(year + 1, 0, 1) / 1000 - 86400)
  46. }
  47. return arr
  48. }
  49. // //例如 2012 年就跨了54周,也有很多是53周的
  50. // let week2012 = whichWeek(2012)
  51. // console.log(week2012)
  52. // //调用完得到的是一个数组见下图

uniapp使用插件使用

https://ext.dcloud.net.cn/plugin?id=16387icon-default.png?t=N7T8https://ext.dcloud.net.cn/plugin?id=16387

zdp-date-picker使用说明

<zdp-date-picker ref="zdpdate" type="月" time="2023-2" @submit-date="handleDate($event)"></zdp-date-picker>

  • 属性参数说明:

ref用于控制picker的弹出与隐藏,组件内有open和close函数

this.$refs.zdpdate.open()
参数名作用类型默认值
type控制打开piker时tabs默认显示的位置String
time显示的默认日期String2023-1

type用于控制打开piker时显示的tabs;默认参数:日、周、月、季、年

time用于控制显示的默认日期;

type=“日” time="2024-1-23" 代表默认显示日、time代表选中日期2024年1月23日

type=“周” time=“2024-4” 代表默认显示周、time代表选中日期2024年第4周

type=“月” time=“2024-1” 代表默认显示月、time代表选中日期2024年1月

type=“季” time=“2024-1” 代表默认显示季、time代表选中日期2024年第1季度

type=“年” time=“2024” 代表默认显示年、time代表选中日期2024

  • 事件返回参数说明:
事件名作用
submit-date用于接收组件返回的时间

submit-date 用于接收组件返回的时间

range 是选中日期的时间范围

zdpdate是具体的固定日期

type 是选中日期类型 日、周、月、季、年

  1. handleDate(e){
  2. let {range,zdpdate,type}=e
  3. this.range=range
  4. this.zdpdate=zdpdate
  5.    this.type=type
  6. }
  • 自定义插槽:

自定义显示组件内文本内容:

  1. <zdp-date-picker ref="zdpdate" :type="type" time="2024-3"
  2. @submit-date="handleDate($event)">
  3. <template #text="{scope}">
  4. {{scope.range}}
  5. {{scope.zdpdate}}
  6. </template>
  7. </zdp-date-picker>

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/我家自动化/article/detail/761854
推荐阅读
相关标签
  

闽ICP备14008679号