Vue-cli框架实现计时器应用

技术背景

本应用使用 vue-cli 框架,并使用了自定义组件(将按钮拆分成单独的组件)和vue 模板。

使用说明

开始正计时:点击工具栏的“开始正计时”按钮即可,快捷键为"Enter"键。

开始倒计时:在输入框内写入时间后,点击“开始倒计时”按钮,即可开始倒计时。

暂停计时器:点击“暂停计时器”按钮即可暂停。

清空正/倒计时:点击此按钮,计时器便会回到初始状态,等待新的计时。

重新再计时:点击此按钮,计时器便会重新开始此次计时。

恢复计时器:点击此按钮即可从暂停状态中恢复。

代码

首先初始化项目

vue init webpack <project name>

components文件夹中放入文件:CounterButton.vue

<template>
  <div>
    <button v-bind:class="styleObject" v-on:click="$emit('click-button')">{{ text }}</button>
  </div>
</template>

<script>
export default {
  name: "CounterButton",
  props: {
    text: String
  },
  data: function() {
    return {
      styleObject: {
        countup: false,
        countdown: false,
        clear: false,
        pause: false,
        restart: false,
        resume: false
      }
    };
  },
  created: function() {
    if (this.text == "开始正计时") {
      this.styleObject.countup = true;
    } else if (this.text == "开始倒计时") {
      this.styleObject.countdown = true;
    } else if (this.text == "清空倒计时" || this.text == "清空正计时") {
      this.styleObject.clear = true;
    } else if (this.text == "暂停计时器") {
      this.styleObject.pause = true;
    } else if (this.text == "重新再计时") {
      this.styleObject.restart = true;
    } else if (this.text == "恢复计时器") {
      this.styleObject.resume = true;
    }
  }
};
</script>

<style>
.countup {
  background-color: #2188e9;
  border-radius: 5px;
  border-color: #2188e9;
  position: absolute;
  left: 310px;
  top: 15px;
  width: 98px;
  height: 40px;
  font-family: PingFangSC-Regular, "PingFang SC", sans-serif;
  font-size: 16px;
  color: #ffffff;
}

.countdown {
  background-color: #2188e9;
  border-radius: 5px;
  border-color: #2188e9;
  position: absolute;
  left: 428px;
  top: 15px;
  width: 98px;
  height: 40px;
  font-family: PingFangSC-Regular, "PingFang SC", sans-serif;
  font-size: 16px;
  color: #ffffff;
}

.clear {
  background-color: #dd2e1d;
  border-radius: 5px;
  border-color: #dd2e1d;
  position: absolute;
  left: 964px;
  top: 15px;
  width: 98px;
  height: 40px;
  font-family: PingFangSC-Regular, "PingFang SC", sans-serif;
  font-size: 16px;
  color: #ffffff;
}

.pause {
  background-color: #2188e9;
  border-radius: 5px;
  border-color: #2188e9;
  position: absolute;
  left: 227px;
  top: 15px;
  width: 98px;
  height: 40px;
  font-family: PingFangSC-Regular, "PingFang SC", sans-serif;
  font-size: 16px;
  color: #ffffff;
}

.restart {
  background-color: #ffb020;
  border-radius: 5px;
  border-color: #ffb020;
  position: absolute;
  left: 1082px;
  top: 15px;
  width: 98px;
  height: 40px;
  font-family: PingFangSC-Regular, "PingFang SC", sans-serif;
  font-size: 16px;
  color: #ffffff;
}

.resume {
  background-color: #2188e9;
  border-radius: 5px;
  border-color: #2188e9;
  position: absolute;
  left: 227px;
  top: 15px;
  width: 98px;
  height: 40px;
  font-family: PingFangSC-Regular, "PingFang SC", sans-serif;
  font-size: 16px;
  color: #ffffff;
}
</style>

将App.vue改为

<template>
  <div id="app">
    <div class="toolbar">
      <div v-show="initialSeen">
        <input v-model="hour" id="hour" />

        <input v-model="minute" id="minute" />

        <input v-model="second" id="second" />

        <span id="hourlabel">时</span>

        <span id="minutelabel">分</span>

        <span id="secondlabel">秒</span>

        <counter-button text="开始正计时" v-on:click-button="startCountUp" id="countup"></counter-button>

        <counter-button text="开始倒计时" v-on:click-button="startCountDown" id="countdown"></counter-button>
      </div>

      <span id="hint" v-show="hintSeen">{{ hint }}</span>

      <counter-button v-bind:text="clearText" v-on:click-button="clearCounter" v-show="clearSeen" id="clear"></counter-button>
      <counter-button text="暂停计时器" v-on:click-button="pauseCounter" v-show="pauseSeen" id="pause"></counter-button>
      <counter-button text="重新再计时" v-on:click-button="restartCounter" v-show="restartSeen" id="restart"></counter-button>
      <counter-button text="恢复计时器" v-on:click-button="resumeCounter" v-show="resumeSeen" id="resume"></counter-button>
    </div>
    <span id="time">{{ time }}</span>
  </div>
</template>

<script>
import CounterButton from "./components/CounterButton";
export default {
  name: "App",
  data: function() {
    return {
      status: 1,
      // status---1: before start; 2: up timing; 3: down timing; 4: up pausing;
      // 5: down pausing; 6: down finished;
      hour: null,
      minute: null,
      second: null,
      time: "00:00:00",
      timer: null,
      Hour: 0,
      Minute: 0,
      Second: 0,
      Millisecond: 0,
      hourString: "",
      minuteString: "",
      secondString: "",
      recordHour: 0,
      recordMinute: 0,
      recordSecond: 0,
      recordMillisecond: 0,
      hint: "正在倒计时 12:20:00",
      clearText: "清空倒计时",
      initialSeen: true,
      clearSeen: false,
      pauseSeen: false,
      restartSeen: false,
      resumeSeen: false,
      hintSeen: false
    };
  },
  methods: {
    format: function(Hour, Minute, Second) {
      if (Second < 10) {
        this.secondString = "0" + Second;
      } else {
        this.secondString = Second;
      }

      if (Minute < 10) {
        this.minuteString = "0" + Minute;
      } else {
        this.minuteString = Minute;
      }

      if (Hour < 10) {
        this.hourString = "0" + Hour;
      } else {
        this.hourString = Hour;
      }
      return (
        this.hourString + ":" + this.minuteString + ":" + this.secondString
      );
    },
    changeStatus: function(aimStatus) {
      if (aimStatus == 1) {
        // before start
        this.initialSeen = true;
        this.clearSeen = false;
        this.pauseSeen = false;
        this.restartSeen = false;
        this.resumeSeen = false;
        this.hintSeen = false;
      } else if (aimStatus == 2 || aimStatus == 3) {
        // up timing || down timing
        this.initialSeen = false;
        this.clearSeen = true;
        this.pauseSeen = true;
        this.restartSeen = true;
        this.resumeSeen = false;
        this.hintSeen = true;

        if (aimStatus == 2) {
          this.hint = "正在正计时";
          this.clearText = "清空正计时";
        } else if (aimStatus == 3) {
          this.recordHour = parseInt(this.recordMillisecond / 3600000);
          this.recordMinute = parseInt(
            (this.recordMillisecond % 3600000) / 60000
          );
          this.recordSecond = parseInt((this.recordMillisecond % 60000) / 1000);
          this.hint =
            "正在倒计时 " +
            this.format(this.recordHour, this.recordMinute, this.recordSecond);
          this.clearText = "清空倒计时";
        }
      } else if (aimStatus == 4 || aimStatus == 5) {
        // up pausing || down pausing
        this.initialSeen = false;
        this.clearSeen = true;
        this.pauseSeen = false;
        this.restartSeen = true;
        this.resumeSeen = true;
        this.hintSeen = true;

        if (aimStatus == 4) {
          // up pausing
          this.hint = "暂停正计时";
          this.clearText = "清空正计时";
        } else if (aimStatus == 5) {
          // down pausing
          this.recordHour = parseInt(this.recordMillisecond / 3600000);
          this.recordMinute = parseInt(
            (this.recordMillisecond % 3600000) / 60000
          );
          this.recordSecond = parseInt((this.recordMillisecond % 60000) / 1000);
          this.hint =
            "暂停倒计时 " +
            this.format(this.recordHour, this.recordMinute, this.recordSecond);
          this.clearText = "清空倒计时";
        }
      } else if (aimStatus == 6) {
        // down finished
        this.initialSeen = false;
        this.clearSeen = true;
        this.pauseSeen = false;
        this.restartSeen = true;
        this.resumeSeen = false;
        this.hintSeen = true;

        this.recordHour = parseInt(this.recordMillisecond / 3600000);
        this.recordMinute = parseInt(
          (this.recordMillisecond % 3600000) / 60000
        );
        this.recordSecond = parseInt((this.recordMillisecond % 60000) / 1000);
        this.hint =
          "倒计时 " +
          this.format(this.recordHour, this.recordMinute, this.recordSecond) +
          " 已结束";
      }
    },
    CountUp: function() {
      this.Millisecond += 50;
      this.Hour = parseInt(this.Millisecond / 3600000);
      this.Minute = parseInt((this.Millisecond % 3600000) / 60000);
      this.Second = parseInt((this.Millisecond % 60000) / 1000);
      this.time = this.format(this.Hour, this.Minute, this.Second);
    },
    CountDown: function() {
      this.Millisecond -= 50;
      this.Hour = parseInt(this.Millisecond / 3600000);
      this.Minute = parseInt((this.Millisecond % 3600000) / 60000);
      this.Second = parseInt((this.Millisecond % 60000) / 1000);
      if (this.Millisecond <= 0) {
        clearInterval(this.timer);
        this.changeStatus(6);
      }
      this.time = this.format(this.Hour, this.Minute, this.Second);
    },
    startCountUp: function() {
      this.status = 2;
      this.Millisecond = 0;
      this.changeStatus(this.status);
      this.timer = setInterval(this.CountUp, 50);
    },
    startCountDown: function() {
      this.status = 3;
      this.Hour = this.hour;
      if (this.minute > 59) {
        this.Minute = 59;
      } else {
        this.Minute = this.minute;
      }
      if (this.second > 59) {
        this.Second = 59;
      } else {
        this.Second = this.second;
      }

      this.hour = null;
      this.minute = null;
      this.second = null;

      this.Millisecond =
        this.Hour * 3600000 + this.Minute * 60000 + this.Second * 1000;
      this.recordMillisecond = this.Millisecond;
      this.changeStatus(this.status);

      this.timer = setInterval(this.CountDown, 50);
    },
    clearCounter: function() {
      this.status = 1;
      this.changeStatus(this.status);
      clearInterval(this.timer);
      this.time = this.format(0, 0, 0);
    },
    pauseCounter: function() {
      if (this.status == 2) {
        // Now count up
        this.status = 4;
        this.changeStatus(this.status);
        clearInterval(this.timer);
      } else if (this.status == 3) {
        // now count down
        this.status = 5;
        this.changeStatus(this.status);
        clearInterval(this.timer);
      }
    },
    restartCounter: function() {
      if (this.status == 2 || this.status == 4) {
        this.status = 2;
        this.Millisecond = 0;
        this.changeStatus(this.status);
        clearInterval(this.timer);
        this.timer = setInterval(this.CountUp, 50);
      } else if ((this.status = 3 || this.status == 5 || this.status == 6)) {
        this.status = 3;
        this.Millisecond = this.recordMillisecond;
        this.changeStatus(this.status);
        clearInterval(this.timer);
        this.timer = setInterval(this.CountDown, 50);
      }
    },
    resumeCounter: function() {
      if (this.status == 4) {
        this.status = 2;
        this.changeStatus(this.status);
        this.timer = setInterval(this.CountUp, 50);
      } else if ((status = 5)) {
        this.status = 3;
        this.changeStatus(this.status);
        this.timer = setInterval(this.CountDown, 50);
      }
    },
    // 键盘事件
    handleKeyup(event) {
      const e = event || window.event || arguments.callee.caller.arguments[0];
      if (!e) return;
      const { key, keyCode } = e;
      if (key == "Enter") {
        if (this.status == 1) {
          // before start
          this.status = 2;
          this.Millisecond = 0;
          this.changeStatus(this.status);
          this.timer = setInterval(this.CountUp, 50);
        }
      } else if (keyCode == 32) {
        if (this.status == 2) {
          // Now count up
          this.status = 4;
          this.changeStatus(this.status);
          clearInterval(this.timer);
        } else if (this.status == 3) {
          // now count down
          this.status = 5;
          this.changeStatus(this.status);
          clearInterval(this.timer);
        } else if (this.status == 4) {
          this.status = 2;
          this.changeStatus(this.status);
          this.timer = setInterval(this.CountUp, 50);
        } else if (this.status == 5) {
          this.status = 3;
          this.changeStatus(this.status);
          this.timer = setInterval(this.CountDown, 50);
        }
      }
    }
  },
  mounted: function() {
    window.addEventListener("keyup", this.handleKeyup);
  },
  destroyed() {
    window.removeEventListener("keyup", this.handleKeyup);
  },
  components: {
    CounterButton
  }
};
</script>

<style>
body {
  margin: 0;
  padding: 0;
}

.toolbar {
  background-color: #97a5bc;
  width: 1220px;
  height: 70px;
}

#hour {
  background-color: white;
  border-radius: 5px;
  position: absolute;
  left: 40px;
  top: 15px;
  width: 69px;
  height: 34px;
  font-size: 15px;
}

#hourlabel {
  position: absolute;
  left: 86px;
  top: 24px;
  font-family: PingFangSC-Regular, "PingFang SC", sans-serif;
  font-size: 16px;
  color: #222222;
}

#minute {
  background-color: white;
  border-radius: 5px;
  position: absolute;
  left: 130px;
  top: 15px;
  width: 69px;
  height: 34px;
  font-size: 15px;
}

#minutelabel {
  position: absolute;
  left: 177px;
  top: 24px;
  font-family: PingFangSC-Regular, "PingFang SC", sans-serif;
  font-size: 16px;
  color: #222222;
}

#second {
  background-color: white;
  border-radius: 5px;
  position: absolute;
  left: 220px;
  top: 15px;
  width: 69px;
  height: 34px;
  font-size: 15px;
}

#secondlabel {
  position: absolute;
  left: 268px;
  top: 24px;
  font-family: PingFangSC-Regular, "PingFang SC", sans-serif;
  font-size: 16px;
  color: #222222;
}

#time {
  position: absolute;
  left: 131px;
  top: 197px;
  font-size: 200px;
  font-family: PTMono-Bold, "PT Mono", monospace;
  font-weight: 700;
  color: #333333;
}

#hint {
  position: absolute;
  left: 40px;
  top: 24px;
  font-family: PTMono-Bold, "PT Mono", monospace;
  font-size: 16px;
  color: white;
}
</style>

最后在目录中使用

npm run dev

即可运行该项目。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • 在Vue环境下利用worker运行interval计时器的步骤

    今天在code review时,发现之前遗留的问题: 在一个视频播放页面,有一个40ms的interval一直在阻碍,导致视频延时逐渐增大 于是写了一个worker单独把计时器拉出去跑了 实现步骤如下 由于用的是vue-cli,在webpack下要安装worker-loader依赖才能单独加载worker.js npm install worker-loader --save-dev 更改 vue.config.js 文件的配置项 configureWebpack:{ module: { rul

  • 解决vue组件销毁之后计时器继续执行的问题

    直接上代码,以下 window.setTimeout(function(){ if(this && !this._isDestroyed){ //_isDestroyed 组件是否被销毁 return; } window.location.href = "/serverMonitor?t="+ new Date().getTime(); },5000) 很粗暴的方法,在执行之前看是否被销毁就行, 第二种方法,调用路由组件内的钩子函数beforeRouteLeave be

  • Vue 使用计时器实现跑马灯效果的实例代码

    Vue 使用计时器实现跑马灯效果,代码如下所示: <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="

  • vue 计时器组件的实现代码

    整理文档,搜刮出一个vue 计时器组件的代码,稍微整理精简一下做下分享. <template> <div> <span :sendSync="sendSync" :autoStart="autoStart" :defaultVal="defaultVal" >{{countString}}</span> </div> </template> <script> ex

  • Vue计时器的用法详解

    本文实例为大家分享了Vue实现计时器的具体代码,供大家参考,具体内容如下 功能简介: 1.初始值为0,点击[加]按钮,数字自+1:连续点击[加],不影响数字+1 2.点击[停]按钮,停止+1 源码: <!DOCTYPE html> <html add="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="

  • vue.js实现简单计时器功能

    本文实例为大家分享了vue.js实现简单计时器功能的具体代码,供大家参考,具体内容如下 <!DOCTYPE html> <html lang="en"> <head> <title>抬腿计数器</title> <script src="/static/vue/vue.js"></script> <script src="/static/vue/index.js&quo

  • vue实现简易计时器组件

    在做项目中难免会碰到需要实时刷新,广告动画依次出现等等需求,刚最近基于业务需求,需要实现一个累加通话时长的计时器,这时候就需要定时器登上我们的代码舞台了,其实对于计时器,它的原理就是通过定时器来实现的,那么在写业务需求之前,我先说说关于定时器的一些知识. window对象提供了两个方法来实现定时器的效果,分别是window.setTimeout()和window.setInterval. 在Javascript中,代码一般都是同步执行的,但定时器却是异步执行的. window.setTimeou

  • vue计时器的实现方法

    本文实例为大家分享了vue实现计时器的具体代码,供大家参考,具体内容如下 这里做的是点击按钮开始与结束倒计时的功能 <div class="time" v-if="rptType">{{str}}</div> <div class="receipt" :class="rptType?'jdz':'jiedan'" @click="receipt">开始</div&g

  • 使用vue实现计时器功能

    本文实例为大家分享了vue实现计时器功能的具体代码,供大家参考,具体内容如下 首先我们要知道setTimeout和setInterval的区别 setTimeout只在指定时间后执行一次,代码如下: <script> //定时器 异步运行 function hello(){ alert("hello"); } //使用方法名字执行方法 var t1 = window.setTimeout(hello,1000); var t2 = window.setTimeout(&qu

  • 浅谈Vue CLI 3结合Lerna进行UI框架设计

    当前大部分UI框架设计的Webpack配置都相对复杂,例如 Element. Ant Design Vue和Muse-UI等Vue组件库.例如Element,为了实现业务层面的两种引入形式( 完整引入 和 按需引入 ),以及抛出一些可供业务层面通用的 utils . i18n 等,Webpack配置变得非常复杂.为了简化UI框架的设计难度,这里介绍一种简单的UI框架设计,在此之前先简单介绍一下 Element 的构建流程,以便对比新的UI框架设计. 一般组件库的设计者将引入形式设计成 完整引入

  • vue cli使用绝对路径引用图片问题的解决

    前言 Vue是什么,是一套构建用户界面的渐进式框架(官网解释),什么叫渐进式框架呢,简单回答就是主张最少,这些概念只能自己去看,自己去理解,一千个读者一千个哈姆雷特,不过多的解释.Vue官方文档 很全面的. Vue是近两年来比较火的一个前端框架(渐进式框架吧),本文将给大家详细介绍vue cli使用绝对路径引用图片问题的相关内容,分享出来供大家参考学习,下面话不多说了,来一起看看吧. 正文: 在页面中使用绝对路径可通过在js中用 require() 引入 data (){ return { sr

  • 一篇文章,教你学会Vue CLI 插件开发

    前言 如果你正在使用Vue框架,那么你肯定知道Vue CLI是什么.Vue-cli 3,它是Vue.js 开发的标准工具(脚手架),提供项目支架和原型设计. 除了日常构建打包项目,Vue CLI3 的一个重要部分是cli-plugins,插件开发. 本文将教你如何科学的创建一个Vue-CLI 插件,以及项目独立npm包. 1. 什么是CLI plugin 它可以修改内部webpack配置并将命令注入到vue-cli-service.一个很好的例子是@vue/cli-plugin-typescri

  • 使用 Vue cli 3.0 构建自定义组件库的方法

    本文旨在给大家提供一种构建一个完整 UI 库脚手架的思路:包括如何快速并优雅地构建UI库的主页.如何托管主页.如何编写脚本提升自己的开发效率.如何生成 CHANGELOG 等 前言 主流的开源 UI 库代码结构主要分为三大部分: 组件库本身的代码:这部分代码会发布到 npm 上 预览示例和查看文档的网站代码:类似 Vant.ElementUI 这类网站. 配置文件和脚本文件:用于打包和发布等等 编写此博文的灵感 UI 框架库( vue-cards ),PS:此 UI框架库相对于Vant.Elem

  • vue cli 3.0通用打包配置代码,不分一二级目录

    1.项目根目录下新建vue.config.js,进行如下配置即可 module.exports={ publicPath:'', }; 补充知识:Vue-CLI3.0更改打包配置 在实际项目开发中,我们一般会直接使用vue.vue-cli来搭建项目.vue框架的宗旨就是让初学者轻松上手,所以,对于打包配置的一些东西,vue的脚手架已经帮我们做好了完美的封装,让我们达到安装既用的效果,也不用担心太多不会做打包配置的问题. 在前期使用Vue-CLI2.0搭建项目时,我们可以在build目录下,直接修

  • Vue前端框架搭建过程

    目录 一.安装 NodeJS 二.安装 vue-cli 三.创建项目 一.安装 NodeJS 见 Windows下安装NodeJS. 二.安装 vue-cli 1.vue-cli 2.x 升级到 3.x (1)卸载 2.x 版本 npm uninstall -g vue-cli (2)安装 npm install -g @vue/cli (3)查看版本 vue -V vue -V@vue/cli 5.0.8 三.创建项目 1.vue-cli 2.x 项目 (1)创建 vue init webpa

  • Vue.js框架路由使用方法实例详解

    Vue.js框架路由使用方法实例详解 html代码: <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name='viewport' content='width=device-width,initial-

  • Vue Cli与BootStrap结合实现表格分页功能

    1.首先需要在vue-cli项目中配置bootstrap,jquery 2. 然后新建vue文件,如index.vue,index.vue内容如下: 3.配置路由即可运行实现. <template> <div class="tTable container body-content"> <div class="form-group"> <div class="form-group"> <div

  • 通过命令行生成vue项目框架的方法

    本文介绍了通过命令行生成vue项目框架的方法,现在分享给大家 -- 安装nodejs 用命令行生成vue项目框架需要npm包管理器来安装,而npm又是在安装nodejs的时候同时安装的, 所以首先要安装nodejs,学习vue有必要了解下nodejs和npm的基本知识: nodejs安装: http://www.jb51.net/article/113457.htm npm 介绍: http://www.jb51.net/article/87893.htm -- 安装命令行工具 npm inst

  • Vue cli 引入第三方JS和CSS的常用方法分享

    第一种方法: 直接在index.html中引入 js <script type="text/javascript" src="static/mui.min.js" ></script> css <link rel="stylesheet" href="static/mui.min.css" rel="external nofollow" /> 第二种 在单页面中用impo

随机推荐