Reputation: 367
There is Home.vue
and Statistics.vue
pages. Home.vue
render the TableFields.vue
component. At Home.vue
there are fields numbers with initial value "3" set on page load. Set interval on calculate function adds numbers every two seconds. How to achieve, that when going from '/' to '/statistics' all the changing should be paused, and on returning back it should be resumed? Bellow each field at home page, already there are buttons that toggle setInterval()
function and stop/resume calculations. Basically, when going from "/" to "/statistics" clearInterval()
should be triggered that stops the calculations at "/" page. @Saksham TableFields.vue:
<template>
<div>
<table class="table-a">
<tr>
<th>A</th>
<td class="sign">{{ this.randomSign.A }}</td>
<td>{{ initialValue.A }}</td>
<td v-show="this.randomSign.A == '+'">⬆</td>
<td v-show="this.randomSign.A == '-'">⬇</td>
</tr>
</table>
<button @click="toggleIntervalA()">
<span v-show="this.startStop.A">Stop</span>
<span v-show="!this.startStop.A">Start</span>
</button>
<table class="table-b">
<tr>
<th>B</th>
<td class="sign">{{ this.randomSign.B }}</td>
<td>{{ initialValue.B }}</td>
<td v-show="this.randomSign.B == '+'">⬆</td>
<td v-show="this.randomSign.B == '-'">⬇</td>
</tr>
</table>
<button @click="toggleIntervalB()">
<span v-show="this.startStop.B">Stop</span>
<span v-show="!this.startStop.B">Start</span>
</button>
</div>
</template>
<script>
export default {
name: 'TableFields',
props: {
changesA: {
type: Array,
required: false
},
changesB: {
type: Array,
required: false
}
},
data () {
return {
fields: ['A', 'B'],
startStop: {
A: true,
B: true
},
initialValue: {
A: 3,
B: 3
},
randomNumbersArray: [],
randomSign: {
A: '+',
B: '+'
},
signsArray: ['+', '-'],
interval: {
A: null,
B: null
},
localChanges: {
A: [],
B: []
},
timer: undefined
}
},
computed: {},
methods: {
firstObjects () {
for (let i = 0; i < this.fields.length; i++) {
const date = new Date()
const obj = {}
obj.field = this.fields[i]
obj.value = Number((Math.random() * 1 + 1).toFixed(2))
obj.time = date.toLocaleTimeString()
this.changesA.push(obj[0])
this.changesB.push(obj[1])
this.$emit('update:changesA', this.localChanges.A)
this.$emit('update:changesB', this.localChanges.B)
}
},
replaceNumbersArray () { // replace random A, B numbers at time interval
const n1 = Number((Math.random() * 1 + 1).toFixed(2)) // n1 = first number (A)
const n2 = Number((Math.random() * 1 + 1).toFixed(2)) // n2 = second number (B)
this.randomNumbersArray.splice(0, 2, n1, n2)
},
toggleIntervalA () {
this.startStop.A = !this.startStop.A
if (this.startStop.A) {
this.interval.A = setInterval(this.calculationsA, 2000)
} else {
clearInterval(this.interval.A)
}
},
toggleIntervalB () {
this.startStop.B = !this.startStop.B
if (this.startStop.B) {
this.interval.B = setInterval(this.calculationsB, 2000)
} else {
clearInterval(this.interval.B)
}
},
calculationsA () {
this.randomSign.A = this.signsArray[
Math.floor(Math.random() * this.signsArray.length)
]
this.randomSign.A === '+'
? (this.initialValue.A += this.randomNumbersArray[0])
: (this.initialValue.A -= this.randomNumbersArray[0])
const date = new Date()
const newChange = {}
newChange.field = 'A'
newChange.value = this.randomNumbersArray[0]
newChange.time = date.toLocaleTimeString()
this.changesA.push(newChange)
this.$emit('update:changesA', this.localChanges.A)
},
calculationsB () {
this.randomSign.B = this.signsArray[
Math.floor(Math.random() * this.signsArray.length)
]
this.randomSign.B === '+'
? (this.initialValue.B += this.randomNumbersArray[1])
: (this.initialValue.B -= this.randomNumbersArray[1])
const date = new Date()
const newChange = {}
newChange.field = 'B'
newChange.value = this.randomNumbersArray[1]
newChange.time = date.toLocaleTimeString()
this.changesB.push(newChange)
this.$emit('update:changesB', this.localChanges.B)
}
},
mounted () {
this.firstObjects()
setInterval(this.replaceNumbersArray, 2000)
this.initialValue.A = this.$root.initialValue.A || 3
this.initialValue.B = this.$root.initialValue.B || 3
this.timer = setInterval(_ => {
this.interval.A = this.calculationsA
this.interval.B = this.calculationsB
}, 2000)
},
beforeDestroy () {
clearInterval(this.timer)
this.$root.initialValue.A = this.initialValue.A
this.$root.initialValue.B = this.initialValue.B
}
}
</script>
<style lang="scss" scoped>
.table-b {
margin-top: 15px;
}
.sign {
width: 12px;
text-align: center;
}
button {
border: 1px solid transparent;
border-radius: 0;
background-color: #42b983;
color: #ffffff;
margin-top: 7px;
padding: 5px 10px;
&:hover {
opacity: 0.9;
cursor: pointer;
}
}
</style>
Project repo: link
Upvotes: 0
Views: 115
Reputation: 9380
Try using the beforeDestroy()
hook to push the counter to either the root component or to vuex store (if you are using one) and fetch the counter in the mounted()
hook once you return to the route to resume from there.
and use in your component as
export default {
...
beforeDestroy () {
this.$root.counter = this.counter;
},
mounted () {
this.counter = this.$root.counter || 0;
}
...
}
I have created a sandbox at https://codesandbox.io/s/preserve-timer-state-2osi7 which preserves the state of timer when we move out of the route and starts the timer from where we left.
Comment Notes:
As per you comment, it seems that you are trying to set a property to an object which is undefined. Initially there is no property by the name initialValue
in the root component and you are trying to access a property A
inside it.
You need to first check if initialValue
is defined and then try to check for A
this.initialValue.A = this.$root.initialValue && this.$root.initialValue.A ? this.$root.initialValue.A : 3
Also make sure your data has initialValue
as an empty object
initialValue: {}
Upvotes: 1