Provide/inject or Vuex? - vue.js

I have a list of cars. Each item of that list has all the information about some of the cars. Also each item is a parent component to many other components - image, price, characteristics, etc - all that info is in separate components.
The information about all those cars is stored in Vuex. Now I am trying to think of a better way to pass that information to each of the list items.
Pass all the necessary data about another car to the parent component. And then provide it to the child components.
Each child component gets the necessary information from Vuex directly.

Provide-inject is mainly used to pass data to nested components.
Vuex on the other hand, keeps the app state shared.
You need to ask yourself whether the data you need in your component is coming from a parent-parent component or the data is used in many components in different parts of the app. If you need the first, then go with the provide-inject, otherwise, pick Vuex.
Both approaches are prone to be badly implemented and potentially impact negatively on your app development and maintainability, so be very careful and learn the basics in-depth ;)

Related

Vue - use vuex instead of eventbus for calculations with nested data & components

I have app when bind big JSON object into component, then some parts from this object into next components etc. - it's structure with many deep levels, but object is not copied, I use advantage that objects are passing by reference.
Components on the lowest level have fields like "price", "qty" etc. When user modifies them, I updated object and run recalculation using global eventbus - after recalculation is done, I also use eventbus to forceUpdate some components. For example parents of these with fields price/qt, to refresh "total" amounts in categories.
Now I move some code to vuex and consider also here. Think that recalculation after commit will be ok. The question is - how can I modify this big object using commit from children components? The problem is that commit must "know" what part of object has been modified (for example, one element inside one of many categories)... I can do it in other way, pass child and parent data in commit and update parent but... will it work? I also need reference to do this in proper way...
Maybe still use binding to pass elements, but call store action to only make recalculation (not sure, that provides automatic refreshes on all required modules).
Or maybe other, better solution?
I think you have some problems with architecture. Main idea here is to have some container (smart) component, that is connedcted with store (vuex), and simple (stupid) components, that recieve data from props. Also you must divide your store into modules, so it'll be easy to maintain. This approach will allows you to modify exactly pieces of data you want.

In Mobx can a complex component have it's own store?

I have built a complex date management component that itself is made up of many smaller components nested a few layers deep. The components at different levels need access to observables and actions that live in the root component. I am dealing with this by passing what I need through props. While this all works, the code would be much simpler and easier to follow if I could create a store in the root component, use provider, and then inject in the child components as needed. Exactly like we do when creating a store for app wide use.
So to summarize...
I want each instance of my complex date component to create it's own instance of a store. I want to then use provider and inject to pass this store instance to child components.
Before I proceed with this significant refactoring, I want to be sure that this approach will work and is sound. Is there an alternative approach that makes more sense. Am I overlooking something?
Note: Although I know code samples are useful, I'm hoping that what I am describing is straight forward enough that they are not needed in this case.
Yes, you can create stores for a component and use Provider and inject to pass them to child components. Actually that is what I do in my current project and it works well.
BTW, I think this is a big Pro of MobX compared to Redux. You do not need to keep all states in a single global store. You can create complicated components that work perfectly by themselves. It is object-oriented, which is the philosophy of React.

vue.js how to organize front-end data (e.g. product information)

What is the correct pattern to store e.g. static product information data within a vue2 single page application?
Previously I've used an external js file that included a JSON with product-attributed (e.g. name, weight, height etc).
I don't want to load via AJAX since the spa needs to work without a web-server.
While VueX is meant to provide to a single source of truth for dynamic data throughout your single page application, I think it's also the proper and clean way of storing static data. VueX allows you to write getters and setters (as mutations / actions), now if you simply leave those setters out of your module you'll have a centralized store module that is read-only but available in every component.
Why is that better than just using a static JSON file?
Using a JSON file will expose the entire content to every single component that uses that file. In some cases that might be what you want, but it's by far not as flexible as having multiple getters that allows you to define the exact scope of what each component should receive. Also VueX uses all observable patterns and best practices from Vue itself, so the integration of your data in for example computed properties is super easy. Due to the getters pattern you'll also be able to define any kind of filtering or sorting in one place that you can share in your entire application. While that might not be what you need right now, keep in mind your requirements may change over time and simply having the option to easily implement that later is also a good thing. Same goes for reading the data from an Endpoint instead of having it statically. Your application might not need that right now, but in case you want to do that somewhen in the future, vuex will make it super easy to transition to dynamic data without you having to change any component.
What speaks against VueX?
Not that much. While it's a little bit of overhead if you really only use it for static data, the possible scalability it offers you is worth that minor downside.

Performance impact of stacking multiple Vue components

I am building an application that uses Vue to display most of the data that my users will see (charts, tables, etc.)
Now, imagine I have a table built with Vue with a list of actions performed by each user. Now, the user name cell will be especially formatted with the user’s picture, social handle, etc. The way the user is presented in this table is the same as it will be in other components. It will also contain some especific functionality (e.g. hovering over the picture will provide expanded information about the user; but this functionality is only planned).
My objective is to reuse as much code as possible. This is why I was planning to have a small UserProfile.vue component inside my Table.vue component. Using this logic, I may repeat this for other information as well (think CompanyProfile.vue, ProjectDetail.vue, etc.).
Is this a good idea? Will it have cause significant performance issues to have multiple vue components inside one and other?
Vue has optimized the result of rendered html as far as possible. You don't need to worry a lot about it. Child components only update when their respective data has changed, that is usually quite cheap.
Good to keep in mind:
When authoring components, it’s good to keep in mind whether you intend to reuse it somewhere else later. It’s OK for one-off components to be tightly coupled, but reusable components should define a clean public interface and make no assumptions about the context it’s used in.
For larger applications, you may use Async Components
Vue will only trigger the factory function when the component actually needs to be rendered and will cache the result for future re-renders. For example:
Vue.component('async-example', function (resolve, reject) {
setTimeout(function () {
// Pass the component definition to the resolve callback
resolve({
template: '<div>I am async!</div>'
})
}, 1000)
})
I found some interesting topics that you might want to look:
Performance for large number of components
Performance degradation when using components
Unlock performance tracing in vue
Analyze runtime performance
So now, you know what to do. Hope, it helps.

Vue Js : Passing Data among siblings

Is there any other way to pass data between 2 siblings without using event bus or parent component in vue js?
I know that it can be passed with the help of Props and event emission. It can also be passed with the help of event buses.
If it is complex you would go you Vuex is the best solution in my opinion. However, if you just want a simple way to communicate between the components, you can simply go for OO Shared State. This is just a class that maintain your data that you can access from any components just pass it though, similar to singleton concept it OOP. There is a good example how to do this in Laracast website; have a look here https://laracasts.com/series/learn-vue-2-step-by-step/episodes/24.
A general question is going to get a general answer. You need to ask yourself why your siblings need to talk to each other. Most often it's because you're not using a store. It would be a mistake to think of vue components like objects in an OO language. Vue components are fed via reactive pipes from a store, the store is not a vue component. If you're doing this correctly, you don't often need to pass stuff between vue components.