I am trying to create a VueJS component that does the following: 1) download some data (a list of options) upon mounted/created; 2) display the downloaded data in Multiselct; 3) send selected data back to parent when user is done with selection. Something like the following:
<template>
<div>
<multiselect v-model="value" :options="options"></multiselect>
</div>
</template>
<script>
import Multiselect from 'vue-multiselect'
export default {
components: { Multiselect },
mounted() {
this.getOptions();
},
methods:{
getOptions() {
// do ajax
// pass response to options
}
},
data () {
return {
value: null,
options: []
}
}
}
</script>
<style src="vue-multiselect/dist/vue-multiselect.min.css"></style>
This is mostly straightforward if the component is only called once in a page. The problem is I may need to use this component multiple times in one page, sometimes probably 10s of times. I don’t want the function to be called multiple times:
this.getOptions();
Is there a way to implement the component somehow so no matter how many times it is used in a page, the ajax call will only execute once?
Thanks in advance.
Update: I assume I can download the data in parent then pass it as prop if the component is going to be used multiple times, something like the following, but this defies the purpose of a component.
props: {
optionsPassedByParents: Array
},
mounted() {
if(this.optionsPassedByParents.length == 0)
this.getOptions();
else
this.options = this.optionsPassedByParents;
},
>Solution :
Place the contents of getOptions() in your App.vue‘s mounted(). Provide the returned data to your component through any of these:
- a state management plugin (vue team’s recommendation: pinia)
- props
- provide/inject
- a reactive object (
export const store = reactive({/* data here */})) placed in its own file, imported (e.g:import { store } from 'path/to/store') in bothApp.vue(which would populate it when request returns) and multiselect component, which would read from it.
If you don’t want to request the data unless Multiselect component is rendered, you should definitely use a state management plugin:
- multiselect calls an action on the store, requesting the data
- the action only makes the request if the data is not present on the store’s state
- additionally, the action might have a
forceFetchparam which allows re-fetching (even when the data is present in state)