Search code examples
vue.jsvuejs3vue-composition-apivue-script-setup

Why is my component not reacting to the changes? Vue3


I have a child component that takes in some props to decide for a state:

  export interface IProps {
    selected?: boolean,
    answered?: boolean
  }
  const {selected, answered} = defineProps<IProps>()

Depending on answered / selected different styles need to be applied. I tried this using computed function:

//  in template
  <div :class="cardClasses" />

// in setup script
  const classes = {
    base: "w-40 h-20 m-0 rounded-xl drop-shadow-lg flex justify-center items-center text-white text-shadow",
    default: "bg-primary hover:bg-primary/70 hover:ring-2 hover:ring-primary hover:ring-inset cursor-pointer",
    selected: "bg-primary/70 ring-teal-900 ring-2 ring-inset cursor-pointer",
    done: "bg-primary/40"
  }

  const status = computed(() => {
    if(answered) return "done"
    if(selected) return "selected"
    return "default"
  })
  const cardClasses = computed(() => `${classes.base} ${classes[status.value]}`)

The initial value for status is always 'default' but after clicking the child component it should turn to 'selected'.

The state is hold by the parent component but I checked the value change for selected in the onUpdated:

  onUpdated(() => {
    console.log("updated")
    console.log(selected, status)
  })

selected changed to true but status is still on 'default'.

How to I make this reactive?


Solution

  • Destructing the props makes them loose the reactivity, you should wrap them by toRefs then destruct them :

    import {toRefs} from 'vue'
    
     export interface IProps {
        selected?: boolean,
        answered?: boolean
      }
      const props=defineProps<IProps>()
    
      const {selected, answered} = toRefs(props)