如何在vue 3中创建Global State



我已经创建了一个反应值,但我希望它从整个应用程序中更改。

为了创建反应状态,我有包含的src/store/index.js

// ** 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 };
}

我在组件中使用这些值

// ** 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 "./components/Scores.vue";
export default {
components: {
Scores
},
setup() {
const { timer, toggleTimer } = useTimer();
function switchtimer() {
console.log(isRef(timer));    // true
toggleTimer();
}
return { switchtimer };
},
};
</script>
// ** src/components/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作为组件导入到app.vue中。即使我在这个描述中犯了任何错误,应用程序中也没有导入问题。这个错误可能是在发布时重写的过程中发生的。

当按下switch at scores按钮时,计时器在分数组件中切换,但按下switch at app按钮时,定时器不会在分数组件内切换

我想让计时器作为全局状态,这样当从app.vue更改计时器时,更改后的值也会显示在scores.vue中。

修复非常简单,您需要使ref变量持久化

// ** 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 };
}

通过将其从函数范围中移除,您将不再在每次调用函数时创建新的timer变量,而是引用同一个变量,就像singleton一样。

这似乎非常适合依赖项注入。由于在整个应用程序中绝对会有一个定时器状态的实例,因此很好地将";更新单个状态";到服务提供商(在本例中为App.vue(,并由子组件调用处理程序inject

你的方法和Daniel的方法会起作用——这可能是有争议的,是否将单态实际耦合到工厂函数,但在这种特殊情况下,我会求助于DI。

App.vue(父级(

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(儿童(

import { defineComponent, inject } from 'vue';
export default defineComponent({
name: 'Home',
setup() {
const toggleTimer = inject('toggleTimer');
return {
toggleTimer
}
}
})

最新更新