fs-week-bar.vue 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152
  1. <template>
  2. <view class="fs-week-bar">
  3. <view class="fs-week-arrow" @click="handleChange('left')">
  4. <fs-icon type="icon-d-down" rotate="90" size="28rpx" :color="textColor"></fs-icon>
  5. </view>
  6. <view class="fs-week-list">
  7. <view
  8. class="fs-week-item"
  9. :class="{'fs-week-item-active': state.activeDate === item.fullDate}"
  10. v-for="(item, index) in state.week"
  11. :key="index"
  12. @click="handleClick(item)"
  13. >
  14. <view class="fs-week-item-hd">周{{item.day}}</view>
  15. <view class="fs-week-item-bd">{{item.date}}</view>
  16. </view>
  17. </view>
  18. <view class="fs-week-arrow" @click="handleChange('right')">
  19. <fs-icon type="icon-d-down" rotate="-90" size="28rpx" :color="textColor"></fs-icon>
  20. </view>
  21. </view>
  22. </template>
  23. <script>
  24. export default {
  25. name: "fs-week-bar"
  26. }
  27. </script>
  28. <script setup>
  29. import { ref, reactive, watch, nextTick } from 'vue'
  30. import dayjs from 'dayjs'
  31. const props = defineProps({
  32. bgColor: {
  33. type: String,
  34. default: '#fff'
  35. },
  36. textColor: {
  37. type: String,
  38. default: '#666666'
  39. },
  40. activeColor: {
  41. type: String,
  42. default: '#165DFF'
  43. },
  44. activeDate: {
  45. type: String,
  46. default: dayjs().format('YYYY-MM-DD')
  47. }
  48. })
  49. const emits = defineEmits(['change', 'click'])
  50. const state = reactive({
  51. week: [],
  52. radix: 0,
  53. activeDate: '',
  54. curDay: '',
  55. curDate: ''
  56. })
  57. const dayMap = {
  58. 1: '一',
  59. 2: '二',
  60. 3: '三',
  61. 4: '四',
  62. 5: '五',
  63. 6: '六',
  64. 7: '日',
  65. }
  66. const initWeek = () => {
  67. state.week = []
  68. for (let i = 1; i < state.curDay; i++) {
  69. const diffDay = state.curDay - i
  70. const date = dayjs(state.curDate).subtract(diffDay, 'day').add(7 * state.radix, 'day')
  71. state.week.push({
  72. day: dayMap[i],
  73. date: date.format('MM-DD'),
  74. fullDate: date.format('YYYY-MM-DD'),
  75. })
  76. }
  77. for (let i = state.curDay; i <= 7; i++) {
  78. const diffDay = i - state.curDay
  79. const date = dayjs(state.curDate).add(diffDay, 'day').add(7 * state.radix, 'day')
  80. state.week.push({
  81. day: dayMap[i],
  82. date: date.format('MM-DD'),
  83. fullDate: date.format('YYYY-MM-DD'),
  84. })
  85. }
  86. }
  87. const stopWatch = watch(() => props.activeDate, val => {
  88. const date = val || undefined
  89. state.activeDate = dayjs(date).format('YYYY-MM-DD')
  90. state.curDate = dayjs(date).format('YYYY-MM-DD')
  91. state.curDay = dayjs(date).day() || 7
  92. // state.radix = Math.floor((dayjs(date).diff(dayjs(), 'day') + state.curDay) / 7)
  93. initWeek()
  94. }, { immediate: true })
  95. const handleChange = type => {
  96. type === 'left' ? state.radix-- : state.radix++
  97. }
  98. watch(() => state.radix, (val) => {
  99. initWeek()
  100. emits('change', state.week)
  101. })
  102. const handleClick= item => {
  103. stopWatch()
  104. state.activeDate = item.fullDate
  105. emits('click', item.fullDate)
  106. }
  107. </script>
  108. <style lang="scss" scoped>
  109. .fs-week{
  110. &-bar{
  111. display: flex;
  112. align-items: center;
  113. background-color: v-bind(bgColor);
  114. padding: 20rpx 0;
  115. }
  116. &-arrow{
  117. padding: 0 10rpx;
  118. }
  119. &-list{
  120. display: flex;
  121. flex: 1;
  122. }
  123. &-item{
  124. text-align: center;
  125. flex: 1;
  126. color: v-bind(textColor);
  127. &-active{
  128. color: v-bind(activeColor);
  129. }
  130. &-hd{
  131. font-size: 15px;
  132. font-weight: bold;
  133. }
  134. &-bd{
  135. font-size: 13px;
  136. }
  137. }
  138. }
  139. </style>