Child component not updating in Vue 3

Viewed 622

I have a Vue3 app which I want to validate a step. so as you see pageControl is the child component that should receive the props.

The problem is that child component gets the props at first but when I update the values(props) inside the parent component (line that starts with const firstName = computed(), child component will not triggered or updated.

Any idea would be appreciated it?

Here's my parent component :

<template>
     <input type="text" v-model="firstName" />
    {{ nextStep.isDisabled }} //**** here the value will change *****//
    <pageControl :previous-step="previousStep" :next-step="nextStep" />
</template>

<script lang="ts">
import { defineComponent, inject, computed } from "vue";
import { useRouter } from "vue-router";
import pageControl from "@/components/pageControl.vue";

interface State {
  firstName: string;
  lastName: string;
  githubUsername: string;
  email: string;
  hasAcceptedTermsAndServices: boolean;
}
interface Store {
  state: State;
  methods: () => void;
  getters: () => void;
}

export default defineComponent({
  name: "RequestForm",
  components: {
    pageControl
  },
  setup() {
    const store: State | undefined = inject("store");
    const router = useRouter();

    const nextStep = {
      action: () => {
        router.push("/github-info");
      },
      isDisabled: true,
    };
    const previousStep = {
      action: () => {
        router.push("/");
      },
      isDisabled: false,
    };
    const firstName = computed({
      get() {
        return (store as any).state.firstName;
      },
      set(val) {
        (store as any).methods.updateFirstName(val);
        nextStep.isDisabled = !(store as any).getters.isValidPersonalInfo();
      }
    });
    return {
      store,
      nextStep,
      previousStep,
      firstName
    };
  }
});
</script>

child component:

<template>
  <nav class="page-control__container">
    <button
      v-if="nextStep"
      :disabled="nextStep.isDisabled"
      @click="nextStep.action"
    >
      {{ nextStep.label }}
    </button>
  </nav>
</template>

<script>
import pageValidator from "@/utils/pageValidator";

export default {
  name: "pageControl",
  props: {
    nextStep: {
      type: Object,
      required: false,
      default: null,
      validator: pageValidator
    },
  }
};
</script>
1 Answers

In order to have reactive data which vue understand the changes, you need to define your values within reactive() method.

    import { reactive } from "vue";
    const nextStep = reactive({
      action: () => {
        router.push("/github-user");
      },
      isDisabled: true,
    });
Related