I'm using Nuxt 3 and Vue 3 in my stack. I want my component changed based my parent state value. but the problem is only my state value changed then the computed in child component is not updating. I already try to pass my Props as reactivity in other variable and to move class binding directly in html :class="..." but still not updating.
This is my example code:
<script lang="ts" setup>
import FeaturedIcon from "~/components/icons/FeaturedIcon.vue";
const iconReactive = reactive({
theme: "light",
size: "md",
type: "primary",
});
</script>
<template>
<div>
<FeaturedIcon
:theme="iconReactive.theme"
:size="iconReactive.size"
:type="iconReactive.type"
/>
<button @click="iconReactive.theme = 'dark'">Click Me</button>
</div>
</template>
<script lang="ts" setup>
// Props
import { computed } from "#imports";
interface Props {
theme: FeaturedThemeProps;
size: FeaturedSizeProps;
type: FeaturedTypeProps;
}
const props = defineProps<Props>();
// * Class state for dynamic styling based on props used
const defaultClass = {
size: {
circle: {
xs: "h-[24px] w-[24px]",
sm: "h-[32px] w-[32px]",
md: "h-[40px] w-[40px]",
lg: "h-[48px] w-[48px]",
xl: "h-[56px] w-[56px]",
},
icon: {
xs: "text-xs",
sm: "text-md",
md: "text-xl",
lg: "text-display-xs",
xl: "text-[28px]",
},
},
color: {
materialIcon: {
primary: "bolt",
gray: "bolt",
error: "error_outline",
warning: "warning_amber",
success: "check_circle",
},
},
};
const featuredIconClassConfig = {
light: {
size: {
circle: defaultClass.size.circle,
icon: defaultClass.size.icon,
border: {},
},
color: {
circle: {
primary: "bg-primary-100",
gray: "bg-gray-100",
error: "bg-error-100",
warning: "bg-warning-100",
success: "bg-success-100",
},
icon: {
primary: "text-primary-700",
gray: "text-gray-700",
error: "text-error-700",
warning: "text-warning-700",
success: "text-success-700",
},
materialIcon: defaultClass.color.materialIcon,
},
},
lightOutline: {
size: {
circle: defaultClass.size.circle,
icon: defaultClass.size.icon,
border: {
xs: "border-[2px]",
sm: "border-[4px]",
md: "border-[6px]",
lg: "border-[8px]",
xl: "border-[10px]",
},
},
color: {
circle: {
primary: "bg-primary-100 border-primary-50",
gray: "bg-gray-100 border-gray-50",
error: "bg-error-100 border-error-50",
warning: "bg-warning-100 border-warning-50",
success: "bg-success-100 border-success-50",
},
icon: {
primary: "text-primary-700",
gray: "text-gray-700",
error: "text-error-700",
warning: "text-warning-700",
success: "text-success-700",
},
materialIcon: defaultClass.color.materialIcon,
},
},
dark: {
size: {
circle: defaultClass.size.circle,
icon: defaultClass.size.icon,
border: {
xs: "border-[2px]",
sm: "border-[4px]",
md: "border-[6px]",
lg: "border-[8px]",
xl: "border-[10px]",
},
},
color: {
circle: {
primary: "bg-primary-600 border-primary-700",
gray: "bg-gray-600 border-gray-700",
error: "bg-error-600 border-error-700",
warning: "bg-warning-600 border-warning-700",
success: "bg-success-600 border-success-700",
},
icon: {
primary: "text-white",
gray: "text-white",
error: "text-white",
warning: "text-white",
success: "text-white",
},
materialIcon: defaultClass.color.materialIcon,
},
},
};
const themeSelected = featuredIconClassConfig[props.theme];
const circleDynamicClass = computed(() => {
return `${themeSelected.size.circle[props.size]}
${themeSelected.size.border[props.size]}
${themeSelected.color.circle[props.type]}`;
});
const spanDynamicClass = computed(() => {
return `${themeSelected.size.icon[props.size]}
${themeSelected.color.icon[props.type]}`;
});
const materialIconContent = computed(() => {
return `${themeSelected.color.materialIcon[props.type]}`;
});
</script>
<template>
{{ circleDynamicClass }}
<div
:class="`flex justify-center items-center rounded-full ${circleDynamicClass}`"
>
<span :class="`material-icons-outlined inline-block ${spanDynamicClass}`">
{{ materialIconContent }}
</span>
</div>
</template>
I only need to move themeSelected
in function.
const circleDynamicClass = computed(() => {
const themeSelected = featuredIconClassConfig[props.theme];
// Do etch
});
Its not remounted when i put it in as outside variable. Thanks for the help.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.