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

闽ICP备14008679号