当前位置:   article > 正文

vue2+uniApp+uview封装日期选择器(自动对齐星期)_uniapp uview calender

uniapp uview calender
  • 先看实现效果

显示当前选中日期的一周

展开显示当月

左右滑动可以切换上下周,顶部切换年月

  • 组件功能:

小程序/APP中,部分页面需要用户切换日期来实现数据请求,该组件可实现切换年月日,日期与星期匹配,返回一个YYYY-MM-DD的数据,这里我组装成了{year:YYYY, month:MM, day:DD}的格式。

  • 上代码

子组件:CustomCalendar.vue

图标使用的是uview的u-icon,你们可以自己替换想要的png都行

  1. <template>
  2. <view class="custom-calendar">
  3. <view class="title">
  4. <u-icon name="arrow-left" color="#8F9BB3" size="32rpx" class="left" @click="lastMonth"></u-icon>
  5. {{year}}年{{month<10?'0'+month:month}}月
  6. <u-icon name="arrow-right" color="#8F9BB3" size="32rpx" class="right" @click="nextMonth"></u-icon>
  7. </view>
  8. <view class="week">
  9. <view class="week-item" v-for="(item,index) in weekArr" :key="index">
  10. {{item}}
  11. </view>
  12. </view>
  13. <template v-if="!showAll">
  14. <swiper class="swiper" :current="swiperCurrent">
  15. <swiper-item v-for="item in daysArr" :key="item.id">
  16. <view class="day-wrap">
  17. <view :class="['day-item',{'active':current === i.value}]" v-for="i in item.arr" :key="i.id"
  18. @click="selectDate(i.value)">
  19. <text class="day">{{i.value}}</text>
  20. </view>
  21. </view>
  22. </swiper-item>
  23. </swiper>
  24. </template>
  25. <template v-else>
  26. <view class="day-wrap" v-for="item in daysArr" :key="item.id">
  27. <view :class="['day-item',{'active':current === i.value}]" v-for="i in item.arr" :key="i.id"
  28. @click="selectDate(i.value)">
  29. <text class="day">{{i.value}}</text>
  30. </view>
  31. </view>
  32. </template>
  33. <view class="more">
  34. <u-icon :name="!showAll?'arrow-down':'arrow-up'" size="40" @click="switchShowMode" color="#8F9BB3"></u-icon>
  35. </view>
  36. </view>
  37. </template>
  38. <script>
  39. export default {
  40. data() {
  41. return {
  42. // false展示一行 true展示所有
  43. showAll: false,
  44. // 年
  45. year: "",
  46. // 月
  47. month: "",
  48. // 日
  49. day: "",
  50. swiperCurrent: 0,
  51. // 星期几
  52. weekday: 1,
  53. // 每天
  54. daysArr: [],
  55. // 当前选中
  56. current: 1,
  57. weekArr: ['周一', '周二', '周三', '周四', '周五', '周六', '周日']
  58. }
  59. },
  60. created() {
  61. this.init();
  62. },
  63. methods: {
  64. // 选择日期
  65. selectDate(val) {
  66. if (!val) return;
  67. this.current = val;
  68.                 //这里我组装成了{year:YYYY, month:MM, day:DD}的格式
  69.                 //你们可以自己返回想要的数据格式
  70. this.$emit('current',{
  71. year:this.year,
  72. month:this.month,
  73. day:this.current,
  74. })
  75. },
  76. // 切换显示模式
  77. switchShowMode() {
  78. this.showAll = !this.showAll;
  79. this.getSwiperCurrent();
  80. },
  81. // 获取当前Swiper Current
  82. getSwiperCurrent() {
  83. this.swiperCurrent = this.daysArr.findIndex((item) => {
  84. return item.arr.some(i => i.value === this.current);
  85. });
  86. },
  87. // 初始化
  88. init() {
  89. let now = new Date();
  90. this.year = now.getFullYear();
  91. this.month = now.getMonth() + 1;
  92. this.day = now.getDate();
  93. this.current = this.day;
  94. //这里我组装成了{year:YYYY, month:MM, day:DD}的格式
  95. //你们可以自己返回想要的数据格式
  96. this.$emit('current',{
  97. year:this.year,
  98. month:this.month,
  99. day:this.current,
  100. })
  101. this.changeData();
  102. this.getSwiperCurrent();
  103. },
  104. // 获取当前星期几
  105. getWeekday(year, month) {
  106. let date = new Date(`${year}/${month}/01 00:00:00`);
  107. return date.getDay() === 0 ? 7 : date.getDay();
  108. },
  109. //一个月有多少天
  110. getMonthDay(year, month) {
  111. let days = new Date(year, month, 0).getDate();
  112. return days;
  113. },
  114.             // 切换日期 该函数逻辑完善不建议改动 但可精简优化
  115. changeData() {
  116. this.day = this.getMonthDay(this.year, this.month);
  117. this.weekday = this.getWeekday(this.year, this.month);
  118. let daysArr = this.generateArray(1, this.day)
  119. for (let i = 0; i < this.weekday - 1; i++) {
  120. daysArr.unshift("")
  121. }
  122. let arr = [];
  123. daysArr.map((item, index) => {
  124. if (index !== 0 && index % 7 === 0) {
  125. if (index === daysArr.length - 1) {
  126. this.daysArr.push({
  127. id: this.$u.guid(),
  128. arr
  129. });
  130. arr = [];
  131. arr.push({
  132. id: this.$u.guid(),
  133. value: item
  134. });
  135. this.daysArr.push({
  136. id: this.$u.guid(),
  137. arr
  138. });
  139. if (arr.length !== 7) {
  140. const len = arr.length
  141. for (let i = 0; i < 7 - len; i++) {
  142. arr.push("")
  143. }
  144. }
  145. } else {
  146. this.daysArr.push({
  147. id: this.$u.guid(),
  148. arr
  149. });
  150. arr = [];
  151. arr.push({
  152. id: this.$u.guid(),
  153. value: item
  154. });
  155. }
  156. } else if (index === daysArr.length - 1) {
  157. arr.push({
  158. id: this.$u.guid(),
  159. value: item
  160. });
  161. if (arr.length !== 7) {
  162. const len = arr.length
  163. for (let i = 0; i < 7 - len; i++) {
  164. arr.push("")
  165. }
  166. }
  167. this.daysArr.push({
  168. id: this.$u.guid(),
  169. arr
  170. });
  171. } else {
  172. arr.push({
  173. id: this.$u.guid(),
  174. value: item
  175. });
  176. }
  177. });
  178. this.daysArr = this.daysArr
  179. },
  180. generateArray: function(start, end) {
  181. return Array.from(new Array(end + 1).keys()).slice(start);
  182. },
  183. // 上一月
  184. lastMonth(){
  185. if (this.month==1) {
  186. this.month = 12
  187. this.year = this.year-1
  188. }else{
  189. this.month = this.month-1
  190. }
  191. this.day = 1
  192. this.daysArr = []
  193. this.changeData()
  194. this.showAll = true
  195. },
  196. //下一月
  197. nextMonth(){
  198. if (this.month==12) {
  199. this.month = 1
  200. this.year = this.year+1
  201. }else{
  202. this.month = this.month+1
  203. }
  204. this.day = 1
  205. this.daysArr = []
  206. this.changeData()
  207. this.showAll = true
  208. }
  209. }
  210. }
  211. </script>
  212. <style scoped lang="scss">
  213. .custom-calendar {
  214. background-color: #FFFFFF;
  215. position: sticky;
  216. top: 0;
  217. /* #ifdef H5 */
  218. top: 44px;
  219. /* #endif */
  220. z-index: 99;
  221. padding: 0 20rpx;
  222. .title {
  223. padding: 20rpx 32rpx;
  224. text-align: center;
  225. font-weight: bold;
  226. .left{
  227. padding: 10rpx;
  228. margin-right: 30rpx;
  229. background-color: #E4F0FC;
  230. border-radius: 8rpx;
  231. }
  232. .right{
  233. padding: 10rpx;
  234. margin-left: 30rpx;
  235. background-color: #E4F0FC;
  236. border-radius: 8rpx;
  237. }
  238. }
  239. .week {
  240. display: flex;
  241. align-items: center;
  242. text-align: center;
  243. .week-item {
  244. flex: 1;
  245. }
  246. }
  247. .day-wrap {
  248. display: flex;
  249. .day-item {
  250. display: flex;
  251. justify-content: center;
  252. flex: 1;
  253. padding: 10rpx 0;
  254. flex-direction: column;
  255. text-align: center;
  256. border-radius: 8rpx;
  257. .day {
  258. font-weight: bold;
  259. }
  260. .num {
  261. font-size: 24rpx;
  262. color: #8F9BB3;
  263. transform: scale(.8);
  264. }
  265. &.active {
  266. background-color: #0676ED;
  267. color: #FFFFFF;
  268. .num {
  269. color: #FFFFFF;
  270. }
  271. }
  272. }
  273. }
  274. .swiper {
  275. height: 60rpx !important;
  276. }
  277. .more {
  278. text-align: center;
  279. }
  280. }
  281. </style>

父组件:

  1. // 在父组件合适的位置引入即可
  2. <template>
  3.     <view class="header">
  4.         <CustomCalendar @current="getday"></CustomCalendar>
  5.     </view>
  6. </template>
  7. <script>
  8. import CustomCalendar from './components/CustomCalendar.vue'
  9.     export default {
  10. methods: {
  11. //获取子组件的天
  12. getday(item){
  13. console.log(item,"获取到的日期数据");
  14.                 // 格式为:{year:YYYY, month:MM, day:DD}
  15. }
  16.         }
  17.     }
  18. </script>

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

闽ICP备14008679号