uv-calendar-body.vue 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349
  1. <template>
  2. <view class="uv-calendar-body">
  3. <view class="uv-calendar__header">
  4. <view class="uv-calendar__header-btn-box" @click.stop="pre">
  5. <view class="uv-calendar__header-btn uv-calendar--left"></view>
  6. </view>
  7. <picker mode="date" :value="date" fields="month" @change="bindDateChange">
  8. <text class="uv-calendar__header-text">{{ (nowDate.year||'') +' / '+( nowDate.month||'')}}</text>
  9. </picker>
  10. <view class="uv-calendar__header-btn-box" @click.stop="next">
  11. <view class="uv-calendar__header-btn uv-calendar--right"></view>
  12. </view>
  13. <text class="uv-calendar__backtoday" @click="backToday">{{todayText}}</text>
  14. </view>
  15. <view class="uv-calendar__box">
  16. <view v-if="showMonth" class="uv-calendar__box-bg">
  17. <text class="uv-calendar__box-bg-text">{{nowDate.month}}</text>
  18. </view>
  19. <view class="uv-calendar__weeks uv-calendar__weeks-week">
  20. <view class="uv-calendar__weeks-day">
  21. <text class="uv-calendar__weeks-day-text">{{SUNText}}</text>
  22. </view>
  23. <view class="uv-calendar__weeks-day">
  24. <text class="uv-calendar__weeks-day-text">{{monText}}</text>
  25. </view>
  26. <view class="uv-calendar__weeks-day">
  27. <text class="uv-calendar__weeks-day-text">{{TUEText}}</text>
  28. </view>
  29. <view class="uv-calendar__weeks-day">
  30. <text class="uv-calendar__weeks-day-text">{{WEDText}}</text>
  31. </view>
  32. <view class="uv-calendar__weeks-day">
  33. <text class="uv-calendar__weeks-day-text">{{THUText}}</text>
  34. </view>
  35. <view class="uv-calendar__weeks-day">
  36. <text class="uv-calendar__weeks-day-text">{{FRIText}}</text>
  37. </view>
  38. <view class="uv-calendar__weeks-day">
  39. <text class="uv-calendar__weeks-day-text">{{SATText}}</text>
  40. </view>
  41. </view>
  42. <view class="uv-calendar__weeks" v-for="(item,weekIndex) in weeks" :key="weekIndex">
  43. <view class="uv-calendar__weeks-item" v-for="(weeks,weeksIndex) in item" :key="weeksIndex">
  44. <calendar-item class="uv-calendar-item--hook" :weeks="weeks" :rangeInfoText="rangeInfoText(weeks)" :calendar="calendar" :selected="selected" :lunar="lunar" :color="color" @change="choiceDate"></calendar-item>
  45. </view>
  46. </view>
  47. </view>
  48. </view>
  49. </template>
  50. <script>
  51. import mpMixin from '@/uni_modules/uv-ui-tools/libs/mixin/mpMixin.js';
  52. import mixin from '@/uni_modules/uv-ui-tools/libs/mixin/mixin.js';
  53. import CalendarItem from './uv-calendar-item.vue';
  54. import { initVueI18n } from '@dcloudio/uni-i18n';
  55. import i18nMessages from './i18n/index.js';
  56. const { t } = initVueI18n(i18nMessages);
  57. export default {
  58. mixins: [mpMixin, mixin],
  59. components: {
  60. CalendarItem
  61. },
  62. props: {
  63. date: {
  64. type: String,
  65. default: ''
  66. },
  67. nowDate: {
  68. type: [String, Object],
  69. default: ''
  70. },
  71. weeks: {
  72. type: [Array, Object],
  73. default () {
  74. return []
  75. }
  76. },
  77. calendar: {
  78. type: Object,
  79. default () {
  80. return {}
  81. }
  82. },
  83. selected: {
  84. type: Array,
  85. default () {
  86. return []
  87. }
  88. },
  89. lunar: {
  90. type: Boolean,
  91. default: false
  92. },
  93. showMonth: {
  94. type: Boolean,
  95. default: true
  96. },
  97. color: {
  98. type: String,
  99. default: '#3c9cff'
  100. },
  101. startText: {
  102. type: String,
  103. default: '开始'
  104. },
  105. endText: {
  106. type: String,
  107. default: '结束'
  108. }
  109. },
  110. computed: {
  111. /**
  112. * for i18n
  113. */
  114. todayText() {
  115. return t("uv-calender.today")
  116. },
  117. monText() {
  118. return t("uv-calender.MON")
  119. },
  120. TUEText() {
  121. return t("uv-calender.TUE")
  122. },
  123. WEDText() {
  124. return t("uv-calender.WED")
  125. },
  126. THUText() {
  127. return t("uv-calender.THU")
  128. },
  129. FRIText() {
  130. return t("uv-calender.FRI")
  131. },
  132. SATText() {
  133. return t("uv-calender.SAT")
  134. },
  135. SUNText() {
  136. return t("uv-calender.SUN")
  137. },
  138. rangeInfoText(weeks) {
  139. return weeks=> {
  140. if(weeks.beforeMultiple) {
  141. if(weeks.extraInfo) {
  142. weeks.extraInfo.info = this.startText;
  143. }else {
  144. weeks.extraInfo = {
  145. info: this.startText
  146. }
  147. }
  148. }
  149. if(weeks.afterMultiple) {
  150. if(weeks.extraInfo) {
  151. weeks.extraInfo.info = this.endText;
  152. }else {
  153. weeks.extraInfo = {
  154. info: this.endText
  155. }
  156. }
  157. }
  158. }
  159. }
  160. },
  161. methods: {
  162. bindDateChange(e) {
  163. this.$emit('bindDateChange', e);
  164. },
  165. backToday() {
  166. this.$emit('backToday');
  167. },
  168. pre() {
  169. this.$emit('pre');
  170. },
  171. next() {
  172. this.$emit('next');
  173. },
  174. choiceDate(e) {
  175. this.$emit('choiceDate', e);
  176. }
  177. }
  178. }
  179. </script>
  180. <style scoped lang="scss">
  181. @mixin flex($direction: row) {
  182. /* #ifndef APP-NVUE */
  183. display: flex;
  184. /* #endif */
  185. flex-direction: $direction;
  186. }
  187. $uv-bg-color-mask: rgba($color: #000000, $alpha: 0.4);
  188. $uv-border-color: #EDEDED !default;
  189. $uv-text-color: #333;
  190. $uv-bg-color-hover: #f1f1f1;
  191. $uv-font-size-base: 14px;
  192. $uv-text-color-placeholder: #808080;
  193. $uv-color-subtitle: #555555;
  194. $uv-text-color-grey: #999;
  195. .uv-calendar {
  196. @include flex(column);
  197. }
  198. .uv-calendar__mask {
  199. position: fixed;
  200. bottom: 0;
  201. top: 0;
  202. left: 0;
  203. right: 0;
  204. background-color: $uv-bg-color-mask;
  205. transition-property: opacity;
  206. transition-duration: 0.3s;
  207. opacity: 0;
  208. /* #ifndef APP-NVUE */
  209. z-index: 99;
  210. /* #endif */
  211. }
  212. .uv-calendar--mask-show {
  213. opacity: 1
  214. }
  215. .uv-calendar--fixed {
  216. position: fixed;
  217. /* #ifdef APP-NVUE */
  218. bottom: 0;
  219. /* #endif */
  220. left: 0;
  221. right: 0;
  222. transition-property: transform;
  223. transition-duration: 0.3s;
  224. transform: translateY(460px);
  225. /* #ifndef APP-NVUE */
  226. bottom: calc(var(--window-bottom));
  227. z-index: 99;
  228. /* #endif */
  229. }
  230. .uv-calendar--ani-show {
  231. transform: translateY(0);
  232. }
  233. .uv-calendar__content {
  234. background-color: #fff;
  235. }
  236. .uv-calendar__header {
  237. position: relative;
  238. @include flex;
  239. justify-content: center;
  240. align-items: center;
  241. height: 50px;
  242. border-bottom-color: $uv-border-color;
  243. border-bottom-style: solid;
  244. border-bottom-width: 1px;
  245. }
  246. .uv-calendar--fixed-top {
  247. @include flex;
  248. justify-content: space-between;
  249. border-top-color: $uv-border-color;
  250. border-top-style: solid;
  251. border-top-width: 1px;
  252. }
  253. .uv-calendar--fixed-width {
  254. width: 50px;
  255. }
  256. .uv-calendar__backtoday {
  257. position: absolute;
  258. right: 0;
  259. top: 25rpx;
  260. padding: 0 5px;
  261. padding-left: 10px;
  262. height: 25px;
  263. line-height: 25px;
  264. font-size: 12px;
  265. border-top-left-radius: 25px;
  266. border-bottom-left-radius: 25px;
  267. color: $uv-text-color;
  268. background-color: $uv-bg-color-hover;
  269. }
  270. .uv-calendar__header-text {
  271. text-align: center;
  272. width: 100px;
  273. font-size: $uv-font-size-base;
  274. color: $uv-text-color;
  275. }
  276. .uv-calendar__header-btn-box {
  277. @include flex;
  278. align-items: center;
  279. justify-content: center;
  280. width: 50px;
  281. height: 50px;
  282. }
  283. .uv-calendar__header-btn {
  284. width: 10px;
  285. height: 10px;
  286. border-left-color: $uv-text-color-placeholder;
  287. border-left-style: solid;
  288. border-left-width: 2px;
  289. border-top-color: $uv-color-subtitle;
  290. border-top-style: solid;
  291. border-top-width: 2px;
  292. }
  293. .uv-calendar--left {
  294. transform: rotate(-45deg);
  295. }
  296. .uv-calendar--right {
  297. transform: rotate(135deg);
  298. }
  299. .uv-calendar__weeks {
  300. position: relative;
  301. @include flex;
  302. }
  303. .uv-calendar__weeks-week {
  304. padding: 0 0 2rpx;
  305. }
  306. .uv-calendar__weeks-item {
  307. flex: 1;
  308. }
  309. .uv-calendar__weeks-day {
  310. flex: 1;
  311. @include flex(column);
  312. justify-content: center;
  313. align-items: center;
  314. height: 45px;
  315. border-bottom-color: #F5F5F5;
  316. border-bottom-style: solid;
  317. border-bottom-width: 1px;
  318. }
  319. .uv-calendar__weeks-day-text {
  320. font-size: 14px;
  321. }
  322. .uv-calendar__box {
  323. position: relative;
  324. }
  325. .uv-calendar__box-bg {
  326. @include flex(column);
  327. justify-content: center;
  328. align-items: center;
  329. position: absolute;
  330. top: 0;
  331. left: 0;
  332. right: 0;
  333. bottom: 0;
  334. }
  335. .uv-calendar__box-bg-text {
  336. font-size: 200px;
  337. font-weight: bold;
  338. color: $uv-text-color-grey;
  339. opacity: 0.1;
  340. text-align: center;
  341. /* #ifndef APP-NVUE */
  342. line-height: 1;
  343. /* #endif */
  344. }
  345. </style>