Ionic-vue problem with IonSelect

So, I found another issue here (probably a bug). I created an IonSelect component and it does not behave properly when I test it. The initial value were sometimes get rendered and sometimes disappear for no obvious reason.

No errors, no warnings.

The update screen took the initial value fetched from the previous screen so, the data was exactly there when I open the devtools.


And I don’t think I made any mistake on my script as well. Would you guys please help me to make sure where was exactly the problem is? Just to make sure… If you guys think I didn’t make any mistake, I’ll have some time creating a reproduction steps and file it to the Ionic Team.

Here is my script, please have a look:

CSelect.vue

<template>
  <IonLabel position="stacked">{{ label }}</IonLabel>
  <IonSelect
    class="ion-text-capitalize"
    mode="md"
    interface="action-sheet"
    :placeholder="placeholder"
    :value="modelValue"
    @ionChange="onChange($event)"
  >
    <IonSelectOption
      class="ion-text-capitalize"
      v-for="item in items"
      :key="item.id"
      :value="item.id"
    >
      {{ item.name }}
    </IonSelectOption>
  </IonSelect>
</template>

<script lang="ts">
  import { IonLabel, IonSelect, IonSelectOption } from '@ionic/vue'
  import { defineComponent, PropType } from 'vue'

  export default defineComponent({
    name: 'CSelect',
    components: {
      IonLabel,
      IonSelect,
      IonSelectOption,
    },
    props: {
      label: {
        type: String,
        required: true,
      },
      placeholder: {
        type: String,
        required: false,
        default: undefined,
      },
      items: {
        type: Array as PropType<Array<any>>,
        required: true,
      },
      modelValue: {
        type: [String, Number],
        required: false,
        default: '',
      },
    },
    setup(props, { emit }) {
      const onChange = (e: Event & { target: HTMLInputElement }) => {
        console.log(e.target.value)
        emit('update:modelValue', e.target.value)
      }

      return {
        onChange,
      }
    },
  })
</script>

<style scoped>
  ion-label {
    padding-left: 0.75rem;
  }

  ion-select {
    background-color: white;
    border-radius: 10px;
    min-height: 3.25rem !important;
    padding: 0 1.25rem !important;
    margin-top: 0.25rem;
    font-size: 1rem;
  }

  @media (prefers-color-scheme: dark) {
    ion-select,
    ion-action-sheet {
      --background: #131313;
      background-color: #131313;
    }
  }
</style>

FormStatus.vue

<template>
  <IonSlide class="ion-padding">
    <IonItem lines="none" class="ion-no-padding ion-margin-bottom">
      <CSelect
        v-model="personalInfoClone.maritalStatusId"
        :items="maritalStatuses"
        label="Marital Status"
        placeholder="Select Status"
      />
    </IonItem>
    <IonItem lines="none" class="ion-no-padding ion-margin-bottom">
      <CSelect
        v-model="personalInfoClone.religionId"
        :items="religions"
        label="Religion"
        placeholder="Select Religion"
      />
    </IonItem>
    <IonItem lines="none" class="ion-no-padding ion-margin-bottom">
      <CSelect
        v-model="personalInfoClone.bloodTypeId"
        :items="bloodTypes"
        label="Blood Type"
        placeholder="Select Blood Type"
      />
    </IonItem>
  </IonSlide>
</template>

<script lang="ts">
  import { IonSlide, IonItem } from '@ionic/vue'
  import { defineComponent, onBeforeMount } from 'vue'

  import { CSelect } from '@/components'
  import {
    usePersonalInfoComposition,
    useMaritalStatusComposition,
    useReligionComposition,
    useBloodTypeComposition,
  } from '@/compositions'

  export default defineComponent({
    name: 'FormStatus',
    components: {
      IonSlide,
      IonItem,
      CSelect,
    },
    setup() {
      const { personalInfoClone } = usePersonalInfoComposition()

      const {
        maritalStatuses,
        maritalStatusIsLoading,
        fetchMaritalStatus,
      } = useMaritalStatusComposition()

      const {
        religions,
        religionIsLoading,
        fetchReligion,
      } = useReligionComposition()

      const {
        bloodTypes,
        bloodTypeIsLoading,
        fetchBloodType,
      } = useBloodTypeComposition()

      onBeforeMount(() => fetchMaritalStatus())
      onBeforeMount(() => fetchReligion())
      onBeforeMount(() => fetchBloodType())

      return {
        personalInfoClone,
        maritalStatuses,
        maritalStatusIsLoading,
        religions,
        religionIsLoading,
        bloodTypes,
        bloodTypeIsLoading,
      }
    },
  })
</script>