tm-monthCalendar.vue 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302
  1. <template>
  2. <view class="tm-monthCalendar " :class="[inline?'d-inline-block':'d-block']">
  3. <view @click.stop.prevent="showpop=!showpop"><slot></slot></view>
  4. <tm-poup :black="black_tmeme" @change="toogle" ref="pop" v-model="showpop" height="900" >
  5. <view class="tm-monthCalendar-wk">
  6. <view class="shadow-10">
  7. <view class="tm-monthCalendar-title ">
  8. <view class="text-size-g text-align-left pl-32 py-32" :class="[color_tmeme,black_tmeme?'bk':'']">
  9. <view class="text-size-g text-white" style="font-size: 42upx;">{{ selectedDay?selectedDay.year:'' }}年</view>
  10. <view class="text-size-lg text-white" style="font-size: 72upx;">
  11. {{ selectedDay?selectedDay.month:'' }}
  12. <text class="text-size-g pl-10">月</text>
  13. </view>
  14. </view>
  15. <view class="tm-monthCalendar-close"><tm-icons @click="$refs.pop.close()" name="icon-times" :color="'white'"></tm-icons></view>
  16. </view>
  17. <view class="flex-between pa-24 " style="width: 50%;margin: auto;">
  18. <view><tm-icons @click="preYear" name="icon-angle-left" color="grey-lighten-1"></tm-icons></view>
  19. <view class="text-size-g text-weight-b">{{ titleVale }}</view>
  20. <view><tm-icons @click="nextYear" name="icon-angle-right" color="grey-lighten-1"></tm-icons></view>
  21. </view>
  22. </view>
  23. </view>
  24. <view class="tm-monthCalendar-body">
  25. <view class="tm-monthCalendar-bg flex-center">
  26. <text class="text" :class="[black_tmeme ? ' opacity-5 ' : '']">{{ selectedDay?selectedDay.year:'' }}</text>
  27. </view>
  28. <view class="tm-monthCalendar-content">
  29. <view style="height: 32upx;"></view>
  30. <tm-row>
  31. <tm-col
  32. @click="day_danxuanclick(item, index)"
  33. align="center"
  34. grid="3"
  35. v-for="(item, index) in nowData"
  36. :key="index"
  37. :round="6"
  38. >
  39. <view class="tm-monthCalendar-col flex-center flex-col round-6" :class="[item.checked === true ? color_tmeme : '']">
  40. <text class="text-size-g" :class="[item.checked ? 'text-white' : '']">{{ item.text }}</text>
  41. </view>
  42. </tm-col>
  43. </tm-row>
  44. </view>
  45. <view class="pa-32">
  46. <tm-button @click="confirm" block itemeClass="round-24" :theme="btnColor ? btnColor : color_tmeme" fontSize="32">{{ btnText }}</tm-button>
  47. </view>
  48. </view>
  49. </tm-poup>
  50. </view>
  51. </template>
  52. <script>
  53. /**
  54. * 月份日历
  55. * @description 日历组件,提供节气、农历公历显示,时间范围选择等功能。
  56. * @property {Function} confirm = [] 当选择日期确认后触发,如果未选择确认后不会触发事件。
  57. * @property {String} btn-text = [] 底部按钮确认的文字
  58. * @property {Boolean} inline = [] 默认true,是否内联或者块状block,内联有助于单行内想快速显示操作多个日历。非内联,适合独占一行。
  59. * @property {String} btn-color = [primary|green|orange|red|blue|bg-gradient-blue-lighten] 默认:bg-gradient-blue-lighten底部按钮确认的背景颜色仅支持主题色名称
  60. * @property {String} color = [primary|green|orange|red|blue] 主题默认:primary,提供是请写主题色名称
  61. * @property {String} default-value = [] 默认时间默认:当前时间,格式:'2021-7-21'
  62. * @property {Boolean|String} disabled = [true|false] 是否禁用,只读,默认false
  63. * @property {Boolean|String} black = [true|false] 是否开启暗黑模式
  64. */
  65. import tmIcons from "@/tm-vuetify/components/tm-icons/tm-icons.vue"
  66. import tmCol from "@/tm-vuetify/components/tm-col/tm-col.vue"
  67. import tmRow from "@/tm-vuetify/components/tm-row/tm-row.vue"
  68. import tmButton from "@/tm-vuetify/components/tm-button/tm-button.vue"
  69. import tmPoup from "@/tm-vuetify/components/tm-poup/tm-poup.vue"
  70. export default {
  71. components:{tmIcons,tmCol,tmRow,tmButton,tmPoup},
  72. name: 'tm-monthCalendar',
  73. props: {
  74. black: {
  75. type: Boolean | String,
  76. default: null
  77. },
  78. disabled: {
  79. type: Boolean | String,
  80. default: false
  81. },
  82. // 默认年月2020-7
  83. defaultValue: {
  84. type: String,
  85. default: ''
  86. },
  87. // 底部按钮文件
  88. btnText: {
  89. type: String,
  90. default: '确认'
  91. },
  92. // 底部按钮背景主题色名称
  93. btnColor: {
  94. type: String,
  95. default: ''
  96. },
  97. // 主题色。
  98. color: {
  99. type: String,
  100. default: 'primary'
  101. },
  102. value: {
  103. type: Boolean,
  104. default: false
  105. },
  106. // 跟随主题色的改变而改变。
  107. fllowTheme:{
  108. type:Boolean|String,
  109. default:true
  110. },
  111. inline:{
  112. type:Boolean|String,
  113. default:true
  114. }
  115. },
  116. model: {
  117. prop: 'value',
  118. event: 'input'
  119. },
  120. computed:{
  121. black_tmeme: function() {
  122. if (this.black !== null) return this.black;
  123. return this.$tm.vx.state().tmVuetify.black;
  124. },
  125. color_tmeme:function(){
  126. if(this.$tm.vx.state().tmVuetify.color!==null&&this.$tm.vx.state().tmVuetify.color && this.fllowTheme){
  127. return this.$tm.vx.state().tmVuetify.color;
  128. }
  129. return this.color;
  130. },
  131. },
  132. watch: {
  133. value:function(val){
  134. this.showpop = val;
  135. },
  136. defaultValue: function(val) {
  137. let d = new Date().toLocaleDateString();
  138. if (this.defaultValue) {
  139. d = this.defaultValue.replace(/-/g,'/');
  140. }
  141. this.selectedDay = null;
  142. this.cal = new Date(d);
  143. this.titleVale = this.cal.getFullYear() + '年';
  144. this.getData();
  145. }
  146. },
  147. data() {
  148. return {
  149. showpop:false,
  150. nowData: [], //当前月份数据。
  151. cal: null, //日历对象数据。
  152. selectedDay: null,
  153. titleVale: '',
  154. dataValue:null,
  155. };
  156. },
  157. mounted() {
  158. let d = new Date().toLocaleDateString();
  159. if (this.defaultValue) {
  160. d = this.defaultValue.replace(/-/g,'/');
  161. this.dataValue = this.defaultValue;
  162. }
  163. this.cal = new Date(d);
  164. this.titleVale = this.cal.getFullYear() + '年';
  165. this.getData();
  166. this.showpop = this.value;
  167. },
  168. methods: {
  169. // 取当前年份的月数据。
  170. getData() {
  171. let text = ['一月', '二月', '三月', '四月', '五月', '六月', '七月', '八月', '九月', '十月', '十一月', '十二月'];
  172. let year = this.cal.getFullYear();
  173. let month = this.cal.getMonth();
  174. this.nowData = [];
  175. for (let i = 0; i < 12; i++) {
  176. let checked = false;
  177. if (this.selectedDay) {
  178. checked = this.selectedDay.year == year && this.selectedDay.index == i ? true : false;
  179. } else {
  180. checked = month == i ? true : false;
  181. }
  182. let obj = {
  183. month: i + 1,
  184. text: text[i],
  185. index: i,
  186. year: year,
  187. checked: checked
  188. };
  189. this.nowData.push(obj);
  190. if (checked) {
  191. this.selectedDay = obj;
  192. }
  193. }
  194. },
  195. confirm() {
  196. this.$emit('confirm', this.selectedDay);
  197. this.$refs.pop.close();
  198. },
  199. close(){
  200. this.$refs.pop.close();
  201. },
  202. toogle(e){
  203. let t = this;
  204. if(e){
  205. this.$nextTick(function(){
  206. if(this.dataValue != this.defaultValue){
  207. this.dataValue = this.defaultValue.replace(/-/g,'/');
  208. }
  209. })
  210. }
  211. this.$emit('input',e);
  212. this.$emit('update:value',e);
  213. },
  214. preYear() {
  215. if (!this.cal) return;
  216. this.cal.setFullYear(this.cal.getFullYear() - 1);
  217. this.titleVale = this.cal.getFullYear() + '年';
  218. this.getData();
  219. },
  220. nextYear() {
  221. if (!this.cal) return;
  222. this.cal.setFullYear(this.cal.getFullYear() + 1);
  223. this.titleVale = this.cal.getFullYear() + '年';
  224. this.getData();
  225. },
  226. day_danxuanclick(item, index) {
  227. if (this.disabled) {
  228. this.$tm.toast('不可选择');
  229. return;
  230. }
  231. let d = { ...item };
  232. this.selectedDay = item;
  233. this.getData();
  234. }
  235. }
  236. };
  237. </script>
  238. <style lang="scss" scoped>
  239. .tm-monthCalendar-col {
  240. width: 100%;
  241. height: 120upx;
  242. // text-align: center;
  243. // line-height: 80upx;
  244. line-height: 0;
  245. position: relative;
  246. .text {
  247. position: absolute;
  248. bottom: 14upx;
  249. }
  250. }
  251. .textOn {
  252. color: #1976d2 !important;
  253. }
  254. .tm-monthCalendar-wk {
  255. width: 100%;
  256. .tm-monthCalendar-title {
  257. position: relative;
  258. .tm-monthCalendar-close {
  259. position: absolute;
  260. top: 32upx;
  261. right: 32upx;
  262. }
  263. }
  264. }
  265. .tm-monthCalendar-body {
  266. position: relative;
  267. .tm-monthCalendar-bg {
  268. height: 400upx;
  269. .text {
  270. font-size: 200upx;
  271. color: rgba(225, 225, 225, 0.4);
  272. }
  273. }
  274. .tm-monthCalendar-content {
  275. width: 100%;
  276. position: absolute;
  277. top: 0;
  278. left: 0;
  279. }
  280. }
  281. </style>