Search code examples
vue.jsquasar

vue3 | Values between quasar q-tabs not preserved


I'm designing a screen where I can submit the form in modal using vue3 and quasar and I categorized the parts of the form by tabulating them. My problem here is that when I change the tab of the components I import into the form, the current selection disappears and when I return to that tab, it shows the old value. but it successfully submits the current value when the form submits, even though it shows the old value. I couldn't find the cause and solution.

enter image description here I protect the form value with v-model, but only my own component that I input to the form does not work properly.

enter image description here

Here is my component: (a simple dynamic q-select)

<script>
let dataArr = [];
export default {
  props: {
    UserProfile: {
      type: Object,
    },
    PropertyName: {
      type: String,
    },
    ParentName: {
      type: String,
    },
    readonly: {
      type: Boolean,
      default: false,
    },
  },
  data() {
    return {
      applicationName: this.$gf_p.Prospot,
      name: "UserProfile",
      controllerName: "Master",
      model: this.UserProfile,
      options: dataArr,
      parentName: "",
    };
  },
  methods: {
    filterFn(val, update, abort) {
      update(() => {
        const needle = val.toLowerCase();
        this.options = dataArr.filter(
          (v) => v.Name.toLowerCase().indexOf(needle) > -1
        );
      });
    },
    getUserProfile() {
      this.$gf
        .GetApi(this.applicationName, this.controllerName, this.name)
        .then((response) => {
          dataArr = JSON.parse(response.data.result);
          this.options = dataArr;
        });
    },
  },
  watch: {
    model: function (newModel, oldModel) {
      console.log("Model changed from", oldModel, "to", newModel);
      this.$emit("change", (this.model = newModel));
    },
    UserProfile: function (UserProfile) {
      if (UserProfile !== null) {
        this.model = UserProfile;
      }
    },
  },
  mounted() {
    this.getUserProfile();
  },
};
</script>

<template>
  <div>
    <q-select
      outlined
      dense
      v-model="model"
      use-input
      input-debounce="0"
      :options="options"
      @filter="filterFn"
      option-value="ID"
      option-label="Name"
      :label="$gf.getLabel(PropertyName, ParentName)"
      style="width: 100%"
      :readonly="readonly"
    >
      <template v-slot:append v-if="!readonly">
        <q-icon
          v-if="model !== ''"
          name="close"
          @click.stop="model = ''"
          class="cursor-pointer"
        />
      </template>
      <template v-slot:no-option>
        <q-item>
          <q-item-section class="text-grey"> No results </q-item-section>
        </q-item>
      </template>
    </q-select>
  </div>
</template>

Solution

  • It looks like you're having trouble because the variables aren't maintained across component renders, often a store like pinia or vuex is used to aid in maintaining state, but it seems like you might just need to properly configure the keep-alive features in Vue3.

    You can find examples of how to do that here. Hope this helps.

    keep-alive