I have created a reactive value but I want it to change from the entire application.
To create the reactive state I have src/store/index.js
that contains
// ** src/store/index.js
export function useTimer() {
const timer = ref(false);
const toggleTimer = () => {
if (timer.value == false) {
timer.value = true;
} else {
timer.value = false;
}
};
return { timer, toggleTimer };
}
And I am using these values in ponents
// ** src/app.vue
<template>
<Scores/>
<button @click="switchtimer()">switch at app</button>
</template>
<script>
import { isRef } from "vue";
import { useTimer } from "./store";
import Scores from "./ponents/Scores.vue";
export default {
ponents: {
Scores
},
setup() {
const { timer, toggleTimer } = useTimer();
function switchtimer() {
console.log(isRef(timer)); // true
toggleTimer();
}
return { switchtimer };
},
};
</script>
// ** src/ponents/Scores.vue
<template>
<button @click="switchtimer()">switch at scores</button>
<p>{{ timer }}</p>
</template>
<script>
import { isRef } from "vue";
import { useTimer } from "../store";
export default {
name: "Scores",
setup() {
const { timer, toggleTimer } = useTimer();
function switchtimer() {
console.log(isRef(timer)); // true
toggleTimer();
}
return { timer, switchtimer };
},
};
</script>
Scores.vue is imported in app.vue as ponent. There is no importing issue in the app even if there is any mistakes I did in this description. That mistake might have occurred during rewriting while posting this.
When switch at scores
button pressed the timer toggles in scores ponent, but switch at app
button pressed the timer does not toggles in scores ponent.
I want to have timer as global state, so that when changed it from app.vue, the changed value also shown in scores.vue.
I have created a reactive value but I want it to change from the entire application.
To create the reactive state I have src/store/index.js
that contains
// ** src/store/index.js
export function useTimer() {
const timer = ref(false);
const toggleTimer = () => {
if (timer.value == false) {
timer.value = true;
} else {
timer.value = false;
}
};
return { timer, toggleTimer };
}
And I am using these values in ponents
// ** src/app.vue
<template>
<Scores/>
<button @click="switchtimer()">switch at app</button>
</template>
<script>
import { isRef } from "vue";
import { useTimer } from "./store";
import Scores from "./ponents/Scores.vue";
export default {
ponents: {
Scores
},
setup() {
const { timer, toggleTimer } = useTimer();
function switchtimer() {
console.log(isRef(timer)); // true
toggleTimer();
}
return { switchtimer };
},
};
</script>
// ** src/ponents/Scores.vue
<template>
<button @click="switchtimer()">switch at scores</button>
<p>{{ timer }}</p>
</template>
<script>
import { isRef } from "vue";
import { useTimer } from "../store";
export default {
name: "Scores",
setup() {
const { timer, toggleTimer } = useTimer();
function switchtimer() {
console.log(isRef(timer)); // true
toggleTimer();
}
return { timer, switchtimer };
},
};
</script>
Scores.vue is imported in app.vue as ponent. There is no importing issue in the app even if there is any mistakes I did in this description. That mistake might have occurred during rewriting while posting this.
When switch at scores
button pressed the timer toggles in scores ponent, but switch at app
button pressed the timer does not toggles in scores ponent.
I want to have timer as global state, so that when changed it from app.vue, the changed value also shown in scores.vue.
Share Improve this question asked Nov 12, 2020 at 2:33 Rupam KairiRupam Kairi 1113 silver badges10 bronze badges2 Answers
Reset to default 9The fix is very simple, you need to make the ref variable persistent
// ** src/store/index.js
const timer = ref(false); // <=== outside of function scope
export function useTimer() {
const toggleTimer = () => {
if (timer.value == false) {
timer.value = true;
} else {
timer.value = false;
}
};
return { timer, toggleTimer };
}
By taking it out of the function scope, you will no longer create a new timer
variable every time you call the function, but rather reference the same one, like a singleton.
This seems like a perfect fit for dependency injection. Since there will be absolutely one instance of the timer state in the whole app, it's good to delegate the responsibility of "updating the single state(s)" to the service provider (in this case, the App.vue
) and have the handler inject
-ed by child ponents.
Your approach and Daniel's will work — and this is probably debatable to the extent of whether or not to have singletons actually coupled to factory functions, but I would resort to DI for this particular case.
App.vue (parent)
import { defineComponent, provide, ref } from 'vue';
export default defineComponent({
setup() {
const timer = ref(false);
const toggleTimer = () => {
timer.value = !timer.value;
}
provide('toggleTimer', toggleTimer);
return { toggleTimer }
}
})
Scores.vue (child)
import { defineComponent, inject } from 'vue';
export default defineComponent({
name: 'Home',
setup() {
const toggleTimer = inject('toggleTimer');
return {
toggleTimer
}
}
})