N
Nuxt7d ago
Rednib

reactive issue: component <-> composable

Hi, i have a composable useThemeConfig which exports a reactive themeConfig:
export function useThemeConfig() {
const themeConfig: ThemeConfig = reactive({
themeLight: {
"--primary-color": "#1a73e4",
...
},
...
return {
themeConfig,
...
};
export function useThemeConfig() {
const themeConfig: ThemeConfig = reactive({
themeLight: {
"--primary-color": "#1a73e4",
...
},
...
return {
themeConfig,
...
};
then in a component i want to use it and change themeLight['--primary-color'] for example:
<script setup lang="ts">
const { themeConfig } = useThemeConfig();
...
themeConfig.themeLight["--primary-color"] = "#ff0000";
</script>
<template>
<!-- Correctly shows #ff0000 -->
<div>{{themeConfig.themeLight["--primary-color"]}}</div>
</template>
<script setup lang="ts">
const { themeConfig } = useThemeConfig();
...
themeConfig.themeLight["--primary-color"] = "#ff0000";
</script>
<template>
<!-- Correctly shows #ff0000 -->
<div>{{themeConfig.themeLight["--primary-color"]}}</div>
</template>
it updates correctly in the component, but the themeConfig in the composable did not change.. How can i achieve reactiveness between the composable and the component?
2 Replies
kapa.ai
kapa.ai7d ago
Hi @Rednib. I'm kapa.ai, your friendly support bot. I will try to answer your question by searching through the knowledge base. :wave: ---------------------- To achieve reactivity between the composable and the component when using Nuxt 3, you need to make a few adjustments to your code. The issue you're experiencing is related to how reactivity works with nested objects and how composables handle state. Let's address this step by step: 1. In your composable, use useState instead of reactive to ensure the state is properly shared and reactive across components:
export function useThemeConfig() {
const themeConfig = useState('themeConfig', () => ({
themeLight: {
"--primary-color": "#1a73e4",
// ...other properties
},
// ...other theme configurations
}));

return {
themeConfig,
// ...other returned values
};
}
export function useThemeConfig() {
const themeConfig = useState('themeConfig', () => ({
themeLight: {
"--primary-color": "#1a73e4",
// ...other properties
},
// ...other theme configurations
}));

return {
themeConfig,
// ...other returned values
};
}
2. In your component, when using the composable, you'll need to use .value to access and modify the state:
<script setup lang="ts">
const { themeConfig } = useThemeConfig();

// Modify the state
themeConfig.value.themeLight["--primary-color"] = "#ff0000";
</script>

<template>
<!-- Access the state -->
<div>{{ themeConfig.themeLight["--primary-color"] }}</div>
</template>
<script setup lang="ts">
const { themeConfig } = useThemeConfig();

// Modify the state
themeConfig.value.themeLight["--primary-color"] = "#ff0000";
</script>

<template>
<!-- Access the state -->
<div>{{ themeConfig.themeLight["--primary-color"] }}</div>
</template>
By using useState in the composable, you're creating a reactive state that is shared across components and properly handled by Nuxt's state management system. This approach ensures that changes made in one component will be reflected in the composable and other components using the same state. It's important to note that when working with nested objects in reactive state, you should consider using the reactive function from Vue or create computed properties for deeper reactivity if needed. For more information on state management in Nuxt 3, you can refer to the Nuxt 3 State Management documentation (https://nuxt.com/docs/getting-started/state-management). Remember that reactivity in Vue and Nuxt can sometimes be tricky, especially with nested objects. If you encounter any issues, you might want to consider flattening your state structure or using more granular state management for complex objects. ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ----------------------
kapa.ai
kapa.ai7d ago
<@778291831766515793> Kapa.ai is still learning and improving, please let me know how I did by reacting below.
Want results from more Discord servers?
Add your server