【发布时间】:2021-09-22 05:24:45
【问题描述】:
我刚开始学习 Vue 和 Vuex。我正在尝试设置一个倒数计时器,当它被点击时,它从 5 秒开始计数。逻辑已放置在 Vuex 存储中用于状态管理,但我无法让计时器运行(它卡在 5 不变)。
在父级 (Home.vue)
<template>
<div class="home">
<Header
@change-game-button="changeGameButton"
:gameInActive="gameInActive"
:gameActive="gameActive"
/>
</div>
</template>
<script>
import Header from '../components/Header'
export default {
name: 'Home',
components: {
Header,
},
data() {
return {
gameInActive: true,
gameActive: false
}
},
methods: {
changeGameButton() {
console.log("Game button fired");
this.gameInActive = !this.gameInActive;
this.gameActive = !this.gameActive;
}
}
}
</script>
在组件(Header.vue)
<template>
<div class="header-container">
<StartResetButton
@btn-click="$emit('change-game-button')"
:buttonText="gameInActive ? 'Start' : 'Restart'"
:buttonColor="gameInActive ? '#90ee90' : '#FED8B1'"
@click="gameInActive? 'resetCounter' : 'startCounter'"
/>
</div>
<div class="initialInstruction" v-if="gameInActive">{{ initialInstruction }}</div>
<div class="gameStartTimer" v-if="gameActive">{{ gameStartTimer }}</div>
</template>
<script>
import StartResetButton from "./StartResetButton";
import { mapActions, mapMutations, mapState } from "vuex";
export default {
components: {
StartResetButton,
},
props: {
gameInActive: Boolean,
gameActive: Boolean,
},
computed: {
...mapState(["gameStartTimer", "initialInstruction"])
},
methods: {
// ...mapMutations(["countDown"]),
...mapActions(["startCounter", "resetCounter"])
},
emits: ['change-game-button']
};
</script>
在商店 (index.js)
import { createStore } from 'vuex'
export default createStore({
state: {
gameStartTimer: 5,
initialInstruction: "Press Start to Begin"
},
mutations: {
stopCounter(state) {
state.gameStartTimer = 5
},
counter(state) {
if (state.gameStartTimer > 0) {
setTimeout(() => {
state.gameStartTimer--;
}, 1000)
}
}
},
actions: {
startCounter(context) {
context.commit('counter')
},
resetCounter(context) {
context.commit('stopCounter')
}
},
modules: {
}
})
StartResetButton.vue
<template>
<button
class="btn"
@click="onClick()"
:style="{ background: buttonColor }">
{{ buttonText }}
</button>
</template>
<script>
export default {
name: "StartResetButton",
props: {
buttonText: String,
buttonColor: String,
},
methods: {
onClick() {
this.$emit('btn-click')
}
}
};
</script>
关于为什么计时器不会触发的任何提示?
【问题讨论】:
-
因为这个片状的表达?
@click="gameInActive? 'resetCounter' : 'startCounter'"。它评估为“resetCounter”字符串,而不是方法。不要在模板中写出比你应该写的更多的逻辑。突变也应该是同步的,你正试图在那里做动作的工作。 -
谢谢。我现在通过将大部分逻辑放到操作中来简化代码。我设法让 setTimeout 倒计时 1,但它只减少了 1 秒并停在那里。我正在弄清楚如何循环播放它,直到 5 秒结束。
标签: javascript html vue.js vuex