Vue 实现countDown倒计时

项目中要用到倒计时,用Vue 实现了一个

 

  1 <template>
  2   <transition name="bkcd">
  3     <div class="bkCountDown" v-show="bkCountDownShow">
  4     <div class="kbCountDownTitle">
  5       <img src="http://static.crecgec.com/Kaipiao/countDownTitle.png">
  6     </div>
  7     <div id="kbCountDownContent" class="kbCountDownContent" ref="kbCountDownContent">
  8     </div>
  9     <!--倒计时结束后提示的信息-->
 10     <div class="cdEndCon" v-show="cdEndConShow">{{cdEndContent}}</div>
 11   </div>
 12   </transition>
 13 </template>
 14 
 15 <script>
 16 import $ from 'jquery'
 17 
 18 export default {
 19   props: {
 20     // 控制倒计时页面显示、隐藏
 21     bkCountDownShow: {
 22       type: Boolean,
 23       default: true
 24     },
 25     // 这个参数:为了实现中途倒计时暂停功能
 26     // 控制倒计时暂停/开始
 27     cdStartOrEnd: {
 28       type: Boolean,
 29       default: true
 30     },
 31     // 倒计时的时间,有父组件传递
 32     countDownTime: {
 33       type: String,
 34       default: '2017/11/9 15:03:01'
 35     },
 36     // 倒计时结束后显示的内容
 37     cdEndContent: {
 38       type: String,
 39       default: '倒计时已经结束'
 40     }
 41   },
 42   data () {
 43     return {
 44       // 倒计时结束后显示cdEndCon
 45       cdEndConShow: false,
 46       timestamp: '', // 倒计时的时间戳
 47       cdTimer: '', // setTimeOut值
 48       timeInterval: '', // 倒计时结束时间与当前时间的之间的间隔
 49       timeIntervalVal: '', // 保存时间间隔的参数
 50       d: '',
 51       h: '',
 52       m: '',
 53       s: '',
 54       days: 24 * 60 * 60,
 55       hours: 60 * 60,
 56       minutes: 60
 57     }
 58   },
 59   mounted () {
 60     this.countdown()
 61   },
 62   watch: {
 63     // 监控cdStartOrEnd值
 64     cdStartOrEnd () {
 65       if (this.cdStartOrEnd) {
 66         this.tick()
 67       } else {
 68         clearTimeout(this.cdTimer)
 69       }
 70     }
 71   },
 72   methods: {
 73     countdown () {
 74       this.timestamp = new Date(this.countDownTime).getTime()
 75       this.init('kbCountDownContent')
 76     },
 77     // 初始化
 78     init (ele) {
 79       $.each(['Hours', 'Minutes', 'Seconds'], function (i) {
 80         $('<div class="count' + this + '">').html(
 81           `<div class = "countPos">\
 82              <span class="digit static">0</span>\
 83         </div>\
 84         <div class="countPos">\
 85           <span class="digit static">0</span>\
 86         </div>`
 87         ).appendTo($('#' + ele))
 88         if (this !== 'Seconds') {
 89           $('#' + ele).append('<div class="countDiv countDiv' + i + '"></div>')
 90         }
 91       })
 92       this.tick()
 93     },
 94     tick () {
 95 //      每次进入这个方法,就重新计算和当前时间的间隔,然后赋值给timeInterval
 96       this.timeInterval = Math.floor((this.timestamp - (new Date())) / 1000)
 97       if (this.timeInterval < 0) {
 98         this.timeInterval = 0
 99       }
100       this.timeIntervalVal = this.timeInterval
101 //       Number of days left
102 //      现在是只有时分秒,可以通过调整下面的代码,来确定显示什么
103 //      this.d = Math.floor(this.timeInterval / this.days)
104 //      this.updateDuo(0, 1, this.d)
105 //      this.timeInterval -= this.d * this.days
106       // Number of hours left
107       this.h = Math.floor(this.timeInterval / this.hours)
108       this.updateDuo(0, 1, this.h)
109       this.timeInterval -= this.h * this.hours
110       // Number of minutes timeInterval
111       this.m = Math.floor(this.timeInterval / this.minutes)
112       this.updateDuo(2, 3, this.m)
113       this.timeInterval -= this.m * this.minutes
114       // Number of seconds timeInterval
115       this.s = this.timeInterval
116       this.updateDuo(4, 5, this.s)
117       // timeIntervalVal大于0,就执行setTimeout方法
118       if (this.timeIntervalVal > 0) {
119         this.cdTimer = setTimeout(this.tick, 1000)
120       } else {
121         // 倒计时结束
122         this.cdEndConShow = true
123         // 这块可以添加emit,给父组件传参
124         // 通过emit给父组件传参数来操作bkCountDownShow
125         //  bkCountDownShow = false
126       }
127     },
128     updateDuo (minor, major, value) {
129       this.switchDigit($('#kbCountDownContent').find('.countPos').eq(minor), Math.floor(value / 10) % 10)
130       this.switchDigit($('#kbCountDownContent').find('.countPos').eq(major), value % 10)
131     },
132     switchDigit (position, number) {
133       let digit = position.find('.digit')
134       if (digit.is(':animated')) {
135         return false
136       }
137       if (position.data('digit') === number) {
138         return false
139       }
140       position.data('digit', number)
141       var replacement = $('<span>', {
142         'class': 'digit',
143         css: {
144           top: '-170px',
145           opacity: 0
146         },
147         html: number
148       })
149       digit
150         .before(replacement)
151         .removeClass('static')
152         .animate({top: '170px', opacity: 0}, 'slow', function () {
153           digit.remove()
154         })
155       replacement
156         .delay(100)
157         .animate({top: 0, opacity: 1}, 'slow', function () {
158           replacement.addClass('static')
159         })
160     }
161   }
162 }
163 </script>
164 
165 <!-- Add "scoped" attribute to limit CSS to this component only -->
166 <style>
167   *{
168     margin:0;
169     padding:0;
170     font-family: 'Microsoft Yahei',Tahoma,'Simsun','宋体' !important;
171   }
172 
173   .bkCountDown{
174     width: 100%;
175     height: 980px;
176     background:url('http://static.crecgec.com/Kaipiao/background.png') #b0b0b0;
177     position: absolute;
178     background-size: cover;
179     overflow: hidden;
180   }
181   .kbCountDownTitle{
182     width: 1070px;
183     height: 120px;
184     line-height: 120px;
185     font-size: 120px;
186     margin: 190px auto 0;
187     text-align: center;
188     color: #fff;
189   }
190   .kbCountDownContent{
191     width:1070px;
192     margin:160px auto 0;
193     text-align:center;
194     letter-spacing:-3px;
195     overflow: hidden;
196   }
197   .countPos{
198     display: inline-block;
199     width: 150px;
200     height: 170px;
201     overflow: hidden;
202     position: relative;
203     margin-left: 15px;
204   }
205 
206   .digit{
207     position:absolute;
208     display:block;
209     width:150px;
210     height: 170px;
211     line-height: 170px;
212     text-align:center;
213     color:#fff;
214     font-size: 80px;
215     background: url('http://static.crecgec.com/Kaipiao/countDown.png') 0 0 no-repeat;
216   }
217 
218   .digit.static{
219     background: url('http://static.crecgec.com/Kaipiao/countDown.png') 0 0 no-repeat;
220   }
221   .countDays,.countHours,.countMinutes,.countSeconds{
222     float: left;
223     font-size: 0;
224   }
225   .countDiv{
226     display:inline-block;
227     width:10px;
228     height:50px;
229     float: left;
230     margin-top: 60px;
231     margin-left: 15px;
232     background: url('http://static.crecgec.com/Kaipiao/countDown1.png') 0 0 no-repeat;
233   }
234   .cdEndCon{
235     width:1070px;
236     margin:20px auto 0;
237     text-align: center;
238     color: #fff;
239     font-size: 20px;
240   }
241   .bkcd-enter-active, .bkcd-leave-active{
242     transition: opacity .5s
243   }
244   .bkcd-enter, .bkcd-leave-to{
245     opacity: 0
246   }
247 </style>

 

posted @ 2017-11-08 16:01  zhaobao1830  阅读(6778)  评论(0编辑  收藏  举报