This is a vue/vuex app and we have an object: myObject, that has a set of children: myObject.kids.
.kids is not loaded when the object is initially loaded by vuex.
Now I want to create a component that works on .kids.
What is the vue/vuex approach to this situation?
Should I create a root-level set to hold the kids or is there a way to load them (via ajax) into the myObject already in the store?
You can do whatever you want, load it vie ajax, create the property if it doesn't exist on component load, etc. The most important part is creating a reactive property, however. I would recommend the following:
this.$store.commit('SET_KIDS', payload)
Which would translate to a mutation in your store receiving a payload:
Vue.set(state.myObject, 'kids', payload)
This is important because the property needs to be reactive in order to be observable and for the store to record changes to the property.
Related
So i know how Vuex implements two way data binding using set() and get methods on the computed property of the component. i.e return the store state or the relevant geeter in the get() method and commit a mutation in the set method which then mutates the state value. I also know how to use mapGetter() helper from Vuex to simply map Vuex getters to the computed property of the component.
My question is how to implement two way data binding when mapGetter helper is used without writing set and get methods for the computed property.
One of the best vue packages around
https://github.com/maoberlehner/vuex-map-fields
Taken from the package description
Enable two-way data binding for form fields saved in a Vuex store.
I have 3 Components in my 'Search' (parent) View; 'SearchForm', 'ResultList', 'DetailPage'. I switch from the SearchForm to the ResultList when I have received a response from the backend.
<keep-alive>
<component v-bind:is="currentComponent"></component>
</keep-alive>
When a response is recieved in my 'SearchForm' I save it to the searchBus;
searchBus.$emit('searchIssue', response.data);
Then, in my ResultList I want to retrieve it again and display the results;
mounted() {
searchBus.$on(['searchIssue'], (search) => {
this.table_items = search;
});
}
I display a loading animation (also a component) until the response is fully loaded and the ResultList is displayed.
Due to the Vue lifecycle everything is working when all components are displayed in one View, as they are already listening when the bus is updated.
Should I choose a different approach? E.g. using v-show or pass the response back to the Parent and inserting it again with a prop (Idk if it would work as not all components have the same props).
Is there a way to use the Bus anyway ? And how could it be solved making it one linear hierarchy and still hide the non-relevant components? (SearchForm -> ResultList -> DetailPage)
Should I choose a different approach?
I thing that is coming time for using Vuex
At the center of every Vuex application is the store. A "store" is
basically a container that holds your application state. There are two
things that make a Vuex store different from a plain global object:
Vuex stores are reactive. When Vue components retrieve state from it, they will reactively and efficiently update if the store's state
changes.
You cannot directly mutate the store's state. The only way to change a store's state is by explicitly committing mutations. This
ensures every state change leaves a track-able record, and enables
tooling that helps us better understand our applications.
I am experimenting with Vue and VueX and while everything is working well, there is one aspect that is troubling with regards to the store mechanism.
I have a component that loads a set of data from a remote service via axios. It works correctly and is called when the component is created.
export default {
created() {
this.$store.dispatch('foo/getBar');
}
...
}
This correctly populates the "bar" variable in the component with the valeus returned from the api call.
When I next view the component in the application, the created function is called again and the api called again, which returns the same data.
What is the best practice way of avoiding subsequent calls until we know that there is different data to be collected? Or more precisely, how do I invalidate data in the store when necessary so that api call is made only when it needs it?
You can put your api call to the parent or root component then place a refresh button to the child component.
Or you can check if variable bar is empty then make the api call.
I'm losing track of reactivity overhead best practices in a Vue 2 Component. I need to generate a one time string with genId() and assign it to the component' id attribute. It seems like overkill to have any watching going on after that.
Is :id="myID" the right way to insert this into the html id?
And then when setting up the source where do I put the non-reactive data? I had 3 thoughts:
Add property myID: genId() to data. But doesn't that add it to the watchlist automatically even though it won't change? Causing overhead?
I read on Vue Forum from a year old answer that myID: genId() should go in the created hook. Are using hooks for this kind of thing a best practice? I thought hooks were discouraged.
Or I could put it in the component methods and then call it directly with :id="genId()
Is there a Vue way to do this?
Use method 2 for non-reactive data (and you use that component many many times on the page that the small overhead of adding the change listeners has any impact.)
created() {
this.myId = genId()
}
The 3 methods behave differently:
Method 1: data
This will call the genId() when the data object is created and add change listeners.
Method 2: created hook
This will call the genId() when the component object is created and doesn't add change listeners.
Method 3: method
This will call the genId() every time the template re-renders. Which happens every time a change is detected on a variable the view is listening to or a $forceUpdate() is called.
Ps. Vue objects already have a unique id: this._uid
but this is a private property and might change in a future version of Vue.
I am coding a web app with vuex and firestore. In my main.js, under created(), I am calling a vuex action (defined in a store module) to query the firestore db and bind a certain subset of the objects in the collection to vuex, restricted programmatically. Summing up:
Let me simplify my question. Here is my structure:
<template> has a v-for list feeded by the computed() property below.
mounted () a function calling vuexfire action binding db RESTRICTED collection to state.ref
computed () some c. property returning a list of state.ref
methods () some method callong vuexfire action binding db UN***RESTRICTED collection relative to some WHERE TO parameter to state.ref
I want to be able to call the method sometimes to reset state.ref to the UNRESTRICTED set of db objects.
My problem is that calling the method triggers no error, but seems to fail: the computed() list returns no object.