【问题标题】:How to start stopwatch from state time using Vue js如何使用Vue js从状态时间开始秒表
【发布时间】:2021-11-29 03:01:42
【问题描述】:

我有一个使用 Vue 3 和 Vuex 的秒表代码,它具有可以启动、停止和重置的功能。

这是代码:

存储/秒表/index.js

export default {
  state: {
    time: "00:10.000",
    timeStarted: null,
    timeBegan: null,
    timeStopped: null,
    stoppedDuration: 0,
    started: null,
    running: false,
    temp: {
      min: "0",
      sec: "0",
      ms: "0",
      secondsPassed: 0
    }
  },
  actions: {
    start({ state, commit, dispatch }) {
      if (state.running) return;
      if (state.timeBegan === null) {
        state.timeBegan = new Date();
      }

      if (state.timeStopped !== null) {
        state.stoppedDuration += new Date() - state.timeStopped;
      }

      commit("start", {
        callback: () => {
          dispatch("clockRunning");
        }
      });
    },
    async clockRunning({ state, commit, dispatch }) {
      let currentTime = new Date();
      let timeElapsed = new Date(
        currentTime - state.timeBegan - state.stoppedDuration
      );
      let min = timeElapsed.getUTCMinutes();
      let sec = timeElapsed.getUTCSeconds();
      let ms = timeElapsed.getUTCMilliseconds();

      commit("newTemp", {
        key: "secondsPassed",
        value: parseInt(Math.abs((state.timeStarted - new Date()) / 1000), 10)
      });

      if (state.running) {
        await dispatch("zeroPrefix", { num: min, digit: 2 }).then(
          (zeroPrefixResponse) => {
            commit("newTemp", {
              key: "min",
              value: zeroPrefixResponse
            });
          }
        );

        await dispatch("zeroPrefix", { num: sec, digit: 2 }).then(
          (zeroPrefixResponse) => {
            commit("newTemp", {
              key: "sec",
              value: zeroPrefixResponse
            });
          }
        );

        await dispatch("zeroPrefix", { num: ms, digit: 3 }).then(
          (zeroPrefixResponse) => {
            commit("newTemp", {
              key: "ms",
              value: zeroPrefixResponse
            });
          }
        );
        state.time =
          state.temp.min + ":" + state.temp.sec + "." + state.temp.ms;
      }
    },
    zeroPrefix(context, payload) {
      return new Promise((resolve) => {
        let zero = "";
        for (let i = 0; i < payload.digit; i++) {
          zero += "0";
        }
        resolve((zero + payload.num).slice(-payload.digit));
      });
    }
  },
  mutations: {
    newTemp(state, payload) {
      state.temp[payload.key] = payload.value;
    },
    addSecondPassed(state, second) {
      state.temp.secondsPassed += second;
    },
    resetSecondPassed(state) {
      state.temp.secondsPassed = 0;
    },
    start(state, payload) {
      state.started = setInterval(() => {
        payload.callback();
      }, 10);
      state.running = true;
    },
    stop(state) {
      state.running = false;
      state.timeStopped = new Date();
      clearInterval(state.started);
    },
    reset(state) {
      state.running = false;
      clearInterval(state.started);
      state.stoppedDuration = 0;
      state.timeBegan = null;
      state.timeStopped = null;
      state.time = "00:10.000";
    }
  },
  getters: {}
};

App.vue

<template>
  <div>
    <span class="time">{{ $store.state.stopwatch.time }}</span>
    <br />
    <button @click="start">Start</button>
    <button @click="stop">Stop</button>
    <button @click="reset">Reset</button>
  </div>
</template>

<script>
export default {
  methods: {
    start() {
      this.$store.dispatch("start");
    },
    stop() {
      this.$store.commit("stop");
    },
    reset() {
      this.$store.commit("reset");
    },
  },
};
</script>

这是codesandbox上的演示代码

上面的代码从 10 秒开始,然后单击开始按钮,秒从数字 0 开始,然后是 1、2、3。不要从 10 号继续。

如何从 10 秒的状态时间开始秒表?

所以当点击开始按钮时,秒数从 10 继续到 11、12、13 等等。

【问题讨论】:

    标签: javascript vue.js vuex vuejs3 stopwatch


    【解决方案1】:

    看起来问题是 10s 没有添加到 timeBegan。如果你减去 10 秒,它应该可以工作。

    if (state.timeBegan === null) {
      state.timeBegan = new Date() - 10_000;
    }
    

    附带说明,突变应仅限于突变

    此代码在突变中添加和删除间隔,与突变的工作方式背道而驰。

        start(state, payload) {
          state.started = setInterval(() => {
            payload.callback();
          }, 10);
          state.running = true;
        },
        stop(state) {
          state.running = false;
          state.timeStopped = new Date();
          clearInterval(state.started);
        },
    

    并且从突变中执行回调也不好。并不是说它不起作用,而是它创建了一个奇怪的状态流,违背了商店的工作原理。

    【讨论】:

    • 有没有办法使用state time: "00:10.000" 作为开始时间参考?不要使用号码10_000。因为我的需求会不时更改state time,并根据更改后的state time运行时间。所以我只需要setstatestate time中的state来更改初始时间,当秒表启动时,它将按照state中的set的初始时间运行。如果我必须使用10_000 之类的示例编号手动更改,我会感到困惑。我试过state.timeBegan = new Date() - state.time,但它不起作用
    • 您也可以调整 state.stoppedDuration?‍♂️ 但 state.time 的值会被覆盖,因此这不是要更改的变量。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-09-16
    • 1970-01-01
    • 2023-03-20
    • 2018-06-30
    • 1970-01-01
    相关资源
    最近更新 更多