浏览代码

Merge branch 'v2' of https://github.com/jdf2e/nutui into v2

Frans 6 年之前
父节点
当前提交
7674bd66a5

+ 10 - 0
src/config.json

@@ -410,6 +410,16 @@
       "sort": "2",
       "showDemo": true,
       "author": "永无止晋"
+    },
+    {
+      "version": "1.0.0",
+      "name": "CountDown",
+      "chnName": "倒计时",
+      "desc": "倒计时组件",
+      "type": "component",
+      "sort": "0",
+      "showDemo": true,
+      "author": "famanoder"
     }
   ]
 }

+ 27 - 0
src/packages/countdown/__test__/countdown.spec.js

@@ -0,0 +1,27 @@
+import {shallowMount} from '@vue/test-utils';
+import CountDown, {restTime} from '../countdown.vue';
+
+describe('CountDown.vue', () => {
+    const end = 1559334689373;
+    const wrapper = shallowMount(CountDown, {
+        propsData: {
+            endTime: end 
+        }
+    });
+    it('默认显示时分秒', () => {
+        const rest = restTime(end - Date.now());
+        const h = Number(rest.d) * 24 + Number(rest.h);
+        const text_h = wrapper.findAll('.nut-cd-block').at(0).text();
+        expect(h).toBe(Number(text_h));
+        expect(h).toBe(wrapper.vm.resttime.h);
+    });
+
+    it('显示天', () => {
+        wrapper.setProps({
+            showDays: true
+        });
+        const rest = restTime(end - Date.now());
+        expect(rest.d).toBe(wrapper.find('.nut-cd-block').text());
+    });
+
+});

+ 0 - 0
src/packages/countdown/countdown.scss


+ 139 - 0
src/packages/countdown/countdown.vue

@@ -0,0 +1,139 @@
+<template>
+  <span class="nut-cd-timer">
+    <template v-if="showPlainText">
+      <span class="nut-cd-block">{{plainText}}</span>
+    </template>
+    <template v-else>
+      <template v-if="resttime.d > 0 && showDays">
+        <span class="nut-cd-block">{{resttime.d}}</span>
+        <span class="nut-cd-dot">天</span>
+      </template>
+      <span class="nut-cd-block">{{resttime.h}}</span><span class="nut-cd-dot">:</span><span class="nut-cd-block">{{resttime.m}}</span><span class="nut-cd-dot">:</span><span class="nut-cd-block">{{resttime.s}}</span>
+    </template>
+  </span>
+</template>
+<script>
+
+function fill2(v) {
+  v += '';
+  while(v.length < 2) {
+    v = '0' + v;
+  }
+  return v;
+}
+function restTime(t) {
+  const ts = t;
+  let rest = {
+    d: '-',
+    h: '--',
+    m: '--',
+    s: '--'
+  };
+  if(ts === 0) {
+    rest = {
+      d: '0',
+      h: '00',
+      m: '00',
+      s: '00'
+    };
+  }
+  if(ts) {
+    const ds = 24 * 60 * 60 * 1000;
+    const hs = 60 * 60 * 1000;
+    const ms = 60 * 1000;
+
+    const d = ts >= ds? parseInt(ts / ds): 0;
+    const h = ts - d*ds >= hs? parseInt((ts - d*ds) / hs): 0;
+    const m = ts - d*ds - h*hs >= ms? parseInt((ts - d*ds - h*hs) / ms): 0;
+    const s = parseInt((ts - d*ds - h*hs - m*ms) / 1000);
+    
+    if(d >= 0) rest.d = d + '';
+    if(h >= 0) rest.h = fill2(h);
+    if(m >= 0) rest.m = fill2(m);
+    if(s >= 0) rest.s = fill2(s);
+      
+  }
+  return rest;
+};
+
+const countdownTimer = {
+  name: 'CountDown',
+  data() {
+    return {
+      restTime: 0
+    }
+  },
+  props: {
+    paused: {
+      default: false,
+      type: Boolean
+    },
+    showDays: {
+      default: false,
+      type: Boolean
+    },
+    showPlainText: {
+      default: false,
+      type: Boolean
+    },
+    interval: {
+      default: 1000,
+      type: Number
+    },
+    startTime: {
+      // 可以是服务器当前时间
+      default: Date.now(),
+      type: [Number, String]
+    },
+    endTime: {
+      default: Date.now(),
+      type: [Number, String]
+    }
+  },
+  computed: {
+    resttime() {
+      const rest = restTime(this.restTime);
+      const {d, h, m, s} = rest;
+      if(!this.showDays && d > 0) {
+        rest.h = Number(rest.h) + d * 24;
+        rest.d = 0;
+      }
+      return rest;
+    },
+    plainText() {
+      const {d, h, m, s} = this.resttime;
+
+      return `${d > 0 && this.showDays? d + '天' + h: h}小时${m}分${s}秒`;
+    }
+  },
+  created() {
+    if(this.interval > 0) {
+      let _start = 0;
+      const curr = Date.now();
+      const start = new Date(+this.startTime).getTime();
+      const end = new Date(+this.endTime).getTime();
+      const diffTime = curr - start;
+      
+      this.restTime = end - (start + diffTime);
+      this.timer = setInterval(() => {
+        if(!this.paused) {
+          let restTime = end - (new Date().getTime() + diffTime);
+          restTime -= 1000;
+          this.restTime = restTime;
+          if(restTime < 0) {
+            this.restTime = 0;
+            clearInterval(this.timer);
+          }
+        }
+      }, this.interval);
+      
+    }
+  }
+}
+countdownTimer.restTime = restTime;
+
+export {restTime};
+export default countdownTimer; 
+</script>
+
+

+ 66 - 0
src/packages/countdown/demo.vue

@@ -0,0 +1,66 @@
+<template>
+    <div class="demo-list">
+      <h4>基本用法</h4>
+      <div>
+        <nut-cell>
+          <count-down slot="title" :endTime="end" />
+        </nut-cell>
+      </div>
+      <h4>显示天</h4>
+      <div>
+        <nut-cell>
+          <count-down slot="title" :endTime="end" showDays/>
+        </nut-cell>
+      </div>
+      <h4>以服务端的时间为准</h4>
+      <div>
+        <nut-cell>
+          <count-down slot="title" :startTime="serverTime" :endTime="end" />
+        </nut-cell>
+      </div>
+      <h4>显示为 天时分秒</h4>
+      <div>
+        <nut-cell>
+          <count-down slot="title" showDays showPlainText :endTime="end" />
+        </nut-cell>
+      </div>
+      <h4>控制开始和暂停的倒计时</h4>
+      <div>
+        <nut-cell>
+          <count-down slot="title" :endTime="end" :paused="paused" />
+          <div slot="desc">
+            <nut-button type="default" small shape="circle" @click="toggle">
+              <b style="font-size: 14px;">{{paused ? 'start': 'stop'}}</b>
+            </nut-button>
+          </div>
+        </nut-cell>
+      </div>
+      <h4>自定义显示</h4>
+      <div>
+        <nut-cell>
+          <span slot="title">可调用该组件提供的 restTime 方法获取 '天时分秒' 自定义显示</span>
+        </nut-cell>
+      </div>
+    </div>
+</template>
+
+<script>
+export default {
+  data() {
+    return {
+      serverTime: 1551943874069,
+      end: 1559334689373,
+      paused: false
+    };
+  },
+  methods: {
+    toggle() {
+      this.paused = !this.paused;
+    }
+  }
+};
+</script>
+
+<style lang="scss" scoped>
+
+</style>

+ 0 - 0
src/packages/countdown/doc.md


+ 8 - 0
src/packages/countdown/index.js

@@ -0,0 +1,8 @@
+import CountDown from './countdown.vue';
+import './countdown.scss';
+
+CountDown.install = function(Vue) {
+  Vue.component(CountDown.name, CountDown);
+};
+
+export default CountDown;