金诚优选前端代码
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

263 lines
6.1 KiB

4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
  1. <template>
  2. <view class="uni-countdown">
  3. <text v-if="showDay" :style="{ borderColor: borderColor, color: color }"
  4. class="uni-countdown__number">{{ d }}</text>
  5. <text v-if="showDay" :style="{ color: splitorColor }" class="uni-countdown__splitor">{{dayText}}</text>
  6. <text v-if="showHour" :style="{ borderColor: borderColor, color: color }"
  7. class="uni-countdown__number">{{ h }}</text>
  8. <text v-if="showHour" :style="{ color: splitorColor }" class="uni-countdown__splitor">{{ showColon ? '' : hourText }}</text>
  9. <text :style="{ borderColor: borderColor, color: color }"
  10. class="uni-countdown__number">{{ i }}</text>
  11. <text :style="{ color: splitorColor }" class="uni-countdown__splitor">{{ showColon ? '分' : minuteText }}</text>
  12. <text :style="{ borderColor: borderColor, color: color }"
  13. class="uni-countdown__number">{{ s }}</text>
  14. <text :style="{ color: splitorColor }" class="uni-countdown__splitor">{{ showColon ? '秒' : secondText }}</text>
  15. <text v-if="!showColon" :style="{ color: splitorColor }" class="uni-countdown__splitor">{{secondText}}</text>
  16. </view>
  17. </template>
  18. <script>
  19. import {
  20. initVueI18n
  21. } from '@dcloudio/uni-i18n'
  22. import messages from './i18n/index.js'
  23. const { t } = initVueI18n(messages)
  24. /**
  25. * Countdown 倒计时
  26. * @description 倒计时组件
  27. * @tutorial https://ext.dcloud.net.cn/plugin?id=25
  28. * @property {String} backgroundColor 背景色
  29. * @property {String} color 文字颜色
  30. * @property {Number} day 天数
  31. * @property {Number} hour 小时
  32. * @property {Number} minute 分钟
  33. * @property {Number} second
  34. * @property {Number} timestamp 时间戳
  35. * @property {Boolean} showDay = [true|false] 是否显示天数
  36. * @property {Boolean} showColon = [true|false] 是否以冒号为分隔符
  37. * @property {String} splitorColor 分割符号颜色
  38. * @event {Function} timeup 倒计时时间到触发事件
  39. * @example <uni-countdown :day="1" :hour="1" :minute="12" :second="40"></uni-countdown>
  40. */
  41. export default {
  42. name: 'UniCountdown',
  43. emits:['timeup'],
  44. props: {
  45. showDay: {
  46. type: Boolean,
  47. default: true
  48. },
  49. showHour: {
  50. type: Boolean,
  51. default: true
  52. },
  53. showColon: {
  54. type: Boolean,
  55. default: true
  56. },
  57. start: {
  58. type: Boolean,
  59. default: true
  60. },
  61. backgroundColor: {
  62. type: String,
  63. default: '#FFFFFF'
  64. },
  65. borderColor: {
  66. type: String,
  67. default: '#15716E'
  68. },
  69. color: {
  70. type: String,
  71. default: '#15716E'
  72. },
  73. splitorColor: {
  74. type: String,
  75. default: '#15716E'
  76. },
  77. day: {
  78. type: Number,
  79. default: 0
  80. },
  81. hour: {
  82. type: Number,
  83. default: 0
  84. },
  85. minute: {
  86. type: Number,
  87. default: 0
  88. },
  89. second: {
  90. type: Number,
  91. default: 0
  92. },
  93. timestamp: {
  94. type: Number,
  95. default: 0
  96. }
  97. },
  98. data() {
  99. return {
  100. timer: null,
  101. syncFlag: false,
  102. d: '00',
  103. h: '00',
  104. i: '00',
  105. s: '00',
  106. leftTime: 0,
  107. seconds: 0
  108. }
  109. },
  110. computed: {
  111. dayText() {
  112. return t("uni-countdown.day")
  113. },
  114. hourText(val) {
  115. return t("uni-countdown.h")
  116. },
  117. minuteText(val) {
  118. return t("uni-countdown.m")
  119. },
  120. secondText(val) {
  121. return t("uni-countdown.s")
  122. },
  123. },
  124. watch: {
  125. day(val) {
  126. this.changeFlag()
  127. },
  128. hour(val) {
  129. this.changeFlag()
  130. },
  131. minute(val) {
  132. this.changeFlag()
  133. },
  134. second(val) {
  135. this.changeFlag()
  136. },
  137. start: {
  138. immediate: true,
  139. handler(newVal, oldVal) {
  140. if (newVal) {
  141. this.startData();
  142. } else {
  143. if (!oldVal) return
  144. clearInterval(this.timer)
  145. }
  146. }
  147. }
  148. },
  149. created: function(e) {
  150. this.seconds = this.toSeconds(this.timestamp, this.day, this.hour, this.minute, this.second)
  151. this.countDown()
  152. },
  153. // #ifndef VUE3
  154. destroyed() {
  155. clearInterval(this.timer)
  156. },
  157. // #endif
  158. // #ifdef VUE3
  159. unmounted() {
  160. clearInterval(this.timer)
  161. },
  162. // #endif
  163. methods: {
  164. toSeconds(timestamp, day, hours, minutes, seconds) {
  165. if (timestamp) {
  166. return timestamp - parseInt(new Date().getTime() / 1000, 10)
  167. }
  168. return day * 60 * 60 * 24 + hours * 60 * 60 + minutes * 60 + seconds
  169. },
  170. timeUp() {
  171. clearInterval(this.timer)
  172. this.$emit('timeup')
  173. },
  174. countDown() {
  175. let seconds = this.seconds
  176. let [day, hour, minute, second] = [0, 0, 0, 0]
  177. if (seconds > 0) {
  178. day = Math.floor(seconds / (60 * 60 * 24))
  179. hour = Math.floor(seconds / (60 * 60)) - (day * 24)
  180. minute = Math.floor(seconds / 60) - (day * 24 * 60) - (hour * 60)
  181. second = Math.floor(seconds) - (day * 24 * 60 * 60) - (hour * 60 * 60) - (minute * 60)
  182. } else {
  183. this.timeUp()
  184. }
  185. if (day < 10) {
  186. day = '0' + day
  187. }
  188. if (hour < 10) {
  189. hour = '0' + hour
  190. }
  191. if (minute < 10) {
  192. minute = '0' + minute
  193. }
  194. if (second < 10) {
  195. second = '0' + second
  196. }
  197. this.d = day
  198. this.h = hour
  199. this.i = minute
  200. this.s = second
  201. },
  202. startData() {
  203. this.seconds = this.toSeconds(this.timestamp, this.day, this.hour, this.minute, this.second)
  204. if (this.seconds <= 0) {
  205. return
  206. }
  207. clearInterval(this.timer)
  208. this.countDown()
  209. this.timer = setInterval(() => {
  210. this.seconds--
  211. if (this.seconds < 0) {
  212. this.timeUp()
  213. return
  214. }
  215. this.countDown()
  216. }, 1000)
  217. },
  218. changeFlag() {
  219. if (!this.syncFlag) {
  220. this.seconds = this.toSeconds(this.timestamp, this.day, this.hour, this.minute, this.second)
  221. this.startData();
  222. this.syncFlag = true;
  223. }
  224. }
  225. }
  226. }
  227. </script>
  228. <style lang="scss" scoped>
  229. $countdown-height: 48rpx;
  230. $countdown-width: 52rpx;
  231. .uni-countdown {
  232. /* #ifndef APP-NVUE */
  233. display: flex;
  234. /* #endif */
  235. flex-direction: row;
  236. justify-content: flex-start;
  237. padding: 2rpx 0;
  238. }
  239. .uni-countdown__splitor {
  240. /* #ifndef APP-NVUE */
  241. display: flex;
  242. /* #endif */
  243. justify-content: center;
  244. line-height: $countdown-height;
  245. padding: 5rpx;
  246. font-size: $uni-font-size-sm;
  247. }
  248. .uni-countdown__number {
  249. /* #ifndef APP-NVUE */
  250. display: flex;
  251. /* #endif */
  252. justify-content: center;
  253. align-items: center;
  254. line-height: $countdown-height;
  255. margin: 5rpx;
  256. text-align: center;
  257. font-size: $uni-font-size-sm;
  258. }
  259. </style>