Data reactivity in Vuejs - issue with loading data from and to multiselect

55 Views Asked by At

I am using vue-multiselect and I would like to store and later load selected values using localStorage. Storing data is quite OK for me, but I struggle with loading data back into the select component.

I was able to acomplish this task within one file, but in order to improve project readability, I have separated multiselect definitions into another file. Although it has improved the readability, but all other things get worse.

Please note, that there are more multiselects and more fields under formData.

  • Vue 3.x
  • vue-multiselect 3.0.0-beta.3

func.js

import VueMultiselect from 'vue-multiselect'

export const TimeframeDropdown = {
  data() {
    return {
      selected: ["5m"],
      timeframes: ["5m", "15m"]
    };
  },
  watch: {
    selected(newVal) {
      formData.multiselect_input = newVal;
    }
  },
  render() {
    return (
      <VueMultiselect
        v-model={this.selected}
        options={this.timeframes}
        multiple={true}
      />
    );
  },
};
//There are more dropdowns in my code
...

page.vue

<TimeframeDropdown />
<AnotherDropdown />
<YetAnotherDropdown />
<button @click="store">store</button>
<button @click="load">load</button>

<script>
import * as t from './func.js'

export default {
  components: {
    ...t,
  },
  data() {
    return {
        multiselect_input: '',
        another_multiselect_input: '',
        yet_another_multiselect_input: ''
    }
  },
  methods: {
    store() {
      localStorage.setItem('test_key', JSON.stringify(this.formData.multiselect_input));
    },
    load() {
      const savedData = localStorage.getItem('test_key');
      this.formData = JSON.parse(savedData);
    },
   }
</script>

EDIT: I have merged formData into vue file as suggested

1

There are 1 best solutions below

0
danielRICADO On

youy need to pass formData as a prop to the form, here you have just imported the formData.js file into each component. I'd get rid of formData.js together

  data() {
    return {
      formData: {
        multiselect_input: '',
        another_multiselect_input: '',
        yet_another_multiselect_input: ''
        //...
      }
    }
  }

then pass the value as a prop

<TimeframeDropdown :selectedValue="formData.multiselect_input" />

in the TimeframeDropdown component

  • recieve the new prop
  • set it to a local state variable in the setup() method
  • handle the user selecting a new Value by emitting that back to the parent and update the formDataValue from there.

nb never try to mutate a prop passed from a parent, recieve a prop assign a local variable, emit the result back to the parent to handle

here it looks like you've just imported a static file into both components, thats not going to be reactive it'll only import the contents of the file as written on disk

import formData from './formData.js'

A term to search for is Parent Child Communication in Vue3, there's a bunch of tutorials about that explain how to do this with the various api's the vue offers. eg here is a codesandbox example I quickly found thats comes close (just doesnt show applying the prop) https://codesandbox.io/p/sandbox/vue3-parent-child-component-communication-4vhwi?