Vue-cli framework implements timer application

Vue-cli framework implements timer application

Technical Background

This application uses the vue-cli framework and uses custom components (splitting buttons into separate components) and vue templates.

Instructions

Start counting up: Click the "Start counting up" button on the toolbar. The shortcut key is the "Enter" key.

Start countdown: After entering the time in the input box, click the "Start countdown" button to start the countdown.

Pause timer: Click the Pause timer button to pause it.

Clear forward/countdown: Click this button and the timer will return to the initial state and wait for a new countdown.

Restart timing: Click this button and the timer will restart.

Resume Timer: Click this button to resume from paused state.

Code

First initialize the project

vue init webpack <project name>

Put the file in the components folder: 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 == "Start counting") {
      this.styleObject.countup = true;
    } else if (this.text == "Start countdown") {
      this.styleObject.countdown = true;
    } else if (this.text == "Clear countdown" || this.text == "Clear countdown") {
      this.styleObject.clear = true;
    } else if (this.text == "Pause timer") {
      this.styleObject.pause = true;
    } else if (this.text == "Restart timing") {
      this.styleObject.restart = true;
    } else if (this.text == "Resume timer") {
      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>

Change App.vue to

<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">Hour</span>

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

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

        <counter-button text="Start counting up" v-on:click-button="startCountUp" id="countup"></counter-button>

        <counter-button text="Start countdown" 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="Pause timer" v-on:click-button="pauseCounter" v-show="pauseSeen" id="pause"></counter-button>
      <counter-button text="Restart the count" v-on:click-button="restartCounter" v-show="restartSeen" id="restart"></counter-button>
      <counter-button text="resume timer" 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: "Counting down to 12:20:00",
      clearText: "Clear countdown",
      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 = "Timing is running";
          this.clearText = "Clear positive time";
        } 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 =
            "Countdown" +
            this.format(this.recordHour, this.recordMinute, this.recordSecond);
          this.clearText = "Clear countdown";
        }
      } 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 = "Pause timing";
          this.clearText = "Clear positive time";
        } 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 =
            "Pause countdown" +
            this.format(this.recordHour, this.recordMinute, this.recordSecond);
          this.clearText = "Clear countdown";
        }
      } 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 =
          "Countdown" +
          this.format(this.recordHour, this.recordMinute, this.recordSecond) +
          "Ended";
      }
    },
    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);
      }
    },
    //Keyboard event 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>

Finally in the directory use

npm run dev

to run the project.

The above is the full content of this article. I hope it will be helpful for everyone’s study. I also hope that everyone will support 123WORDPRESS.COM.

You may also be interested in:
  • Implementing a simple timer based on Vue method
  • Using Vue to implement timer function
  • Vue.js implements simple timer function
  • Vue implements a simple timer component
  • How to implement Vue timer
  • Detailed usage of Vue timer
  • Solve the problem of timer continuing to execute after Vue component is destroyed
  • Vue example code using timer to achieve marquee effect
  • Implementation code of vue timer component
  • How to encapsulate timer components in Vue3

<<:  Basic usage examples of listeners in Vue

>>:  Analysis of the solution to Nginx Session sharing problem

Recommend

Detailed explanation of Vue3's sandbox mechanism

Table of contents Preface Browser compiled versio...

The 6 Most Effective Ways to Write HTML and CSS

This article shares the 6 most effective methods,...

A comprehensive understanding of Vue.js functional components

Table of contents Preface React Functional Compon...

How to implement the jQuery carousel function

This article shares the implementation code of jQ...

This article will show you the basics of JavaScript: deep copy and shallow copy

Table of contents Shallow copy Deep Copy Replenis...

Tips for Mixing OR and AND in SQL Statements

Today, there is such a requirement. If the logged...

SQL fuzzy query report: ORA-00909: invalid number of parameters solution

When using Oracle database for fuzzy query, The c...

How to submit the value of a disabled form field in a form Example code

If a form field in a form is set to disabled, the ...

VMware Workstation is not compatible with Device/Credential Guard

When installing a virtual machine, a prompt appea...

Setting up a proxy server using nginx

Nginx can use its reverse proxy function to imple...

A brief introduction to Tomcat's overall structure

Tomcat is widely known as a web container. It has...

How to get form data in Vue

Table of contents need Get data and submit Templa...