Reusing Components and Maintaining State with Vue - vue.js

I have created a few linked Vue components that I reuse between multiple projects. Eventually I would like to do it with NPM or a tool like Bit, but right now I am doing it manually.
All of my components are just passing data between themselves using props and emits. This has gotten pretty inefficient as a lot of my components do not sit right next to one another all of the time, so I want to move them over to a more robust solution. Right now I am finding myself having to emit the same data multiple times just to get back up the chain.
Through reading I know that a global event bus can be used to maintain state between components, or Vuex could be used to maintain my overall application state, but how do I factor this into reusable components?
In my head it feels like if I base my components on either option, then I am committing to always using that component with a global event bus or Vuex. And obviously in some projects I may want to switch between using one or the other, depending on the application's complexity.
How do I best approach this? Do I need slightly different components depending on the overall application (this feels like I lose the reuse-ability) or is there something I am not taking into account here?
For one of my applications I have the following simplified component structure:
Root Component
Grid
Card
FilterDropdown
Graph
Currently I pass the data into my root component from the API, then pass it down to the Graph component through props at each stage.
On the other side, my FilterDropdown gets a distinct list of one of the data's columns, and provides a dropdown where the user can select a value. This values is then emitted 3 times back up the tree to the root component, where it is used to filter the data via a computed property, that is then passed down again using the same props.
Am I over-complicating things by thinking this needs changing? I can already imaging how I could achieve the same thing, with less overall confusion, by using an event bus or Vuex, but in my head I think I would lose some reuse-ability?

If an app is passing around props to unrelated components or it's becoming tedious to maintain a props/emit chain through multiple descendants, then it's probably a good time to use one of the options you mentioned. From the Vuex docs:
passing props can be tedious for deeply nested components, and simply doesn't work for sibling components.
If the architecture isn't that complicated, there's probably no need to switch. But if there is...
Vuex Modules
Since Vuex allows for modules, you can probably eliminate the question of whether it negatively impacts component reusability. You can think of the component(s) + their dedicated Vuex module(s) as a package. The Vuex module can encapsulate all of the necessary store functionality without affecting any part of the store of an app that utilizes it.
Plugins
You could even create plugins from these components and use dynamic module registration to register their associated Vuex module in the app's existing store.
You could do something similar with a plugin and event bus.
Instead of thinking of this as committing to a limitation, you can view it as the plugin providing an interface for apps to take advantage of its features. You could also go with an "all of the above" approach and create a solution for each option.

Related

What Portion of The Data Should Be Stored Using Vuex?

Hello I deciced to use Vuex for state management in my application.
I experiened with state management in Flutter before and most of the data is stored using state management in Flutter and not in the Widgets.
When I use Vuex should most of my data be stored in the store divided into modules? or should I use Vuex to store only global data and keep most of my data in the components?
I can't find a detailed answer about that, but I saw that if you need more than one emit in the tree of components then you should consider putting the data in the store.
Thank you very much for the help and I really appriciate every answer!
In my experience, it really depends on your application. But a good rule of thumb is keeping the store for data that is global and multiple components need to use it or WILL use it, think of the future as well in this case if the app will be extended in the future what data will be needed globally. That data can go into Vuex Store.
Additionally I found that using the Store for asynchronous calls and to process this data makes my components code way cleaner.
And for you question specifically, YES most of your data should be stored there. Think of it as your components are responsible for only what they do, they dont have to know how the data is getting to them and how the data is processed, they just know they need some data and they get it. This usually makes for more understandable code.
I have found these articles Should I Store This Data in Vuex or When Why and How to use Vuex that sum up most of my findings and experiences on this topic, you are welcome to read more here.
Also as a side-note using classes helps a lot too, if it is kind of learner project for you, try experimenting with different styles of project structures. For example you can have a [some_name]_helper.js or [data_type]_processing.js file that contains logic for processing data, or handling data that you use widely in your application, like dates, making your code as modular as possible helps a lot, and ultimately that is what Vuex tries to make easier for you.
(Try to learn the Vuex pattern (getters, mutations, actions) and understand it as much as possible, that is the best way for you to decide what data where goes in you project specifically)

When to split a Vue component into multiple components (sub components)

When creating Vue components, how does one decide when to separate out a component into a parent component with multiple child components versus just having a single component with more logic?
I am using Vue in a few places on a non-SPA website. On one of the pages of the site I need to display a list of items, with some icons next to each item to do some simple things like show/hide. I am building the list as a Vue component, lets call it ProductList. But I am not sure whether to make each item within that list a separate component or not. When is it appropriate to split a component into multiple sub components?
My own reasoning tells me that components should only be created for things that need to be able to stand alone. Since the items are not going to be used outside of a list, there is no point in having them a separate ProductListItem component to put inside the ProductList component. I should just have all the code in the ProductList component. Right?
But when I look at other examples on the internet, many of them tell a different story. For instance, I recall seeing an example where there was an Article component, an ArticleTitle component, an ArticleBody component, and an ArticleEnd component (or something like this). The template of the Article Component had <article-title>, <article-body> and <article-end> within it. If an ArticleTitle component or an ArticleBody component is only going to be used inside the Article component, not standalone, why bother having it be a separate component? Am I missing something here? Is there a technical criteria on which to base the decision of whether to have multiple components or is it just personal preference?
Interesting question, I think this really depends on the developers and its all gonna become agree to disagree. However, wanna share my experience if it helps:
In a most optimised system design, it should be split into components, because thats what modern frontend framework beats pure html coding ( component-based coding). When should we split the components, I think Decade Moon's answer makes a good and clear point. However, I want to write more about the type of components:
1/ View components ( or dumb components): only for purpose of display, no logic of data flow
2/ Control components ( or smart components): display many dumb component and contain data flow logic
3/ Containers (or views): contain many control components, usually put the logic of server interaction here ( api call ,.... )
When we divide like this, it would be easier for maintenance because we control how the data flow better.
So back to your example: the Product list is like a control component, and the list item is likely a view component. Therefore, i actually support the idea of separating them.
Splitting components will make the directory structure become longer, however with good naming and filtering, I think it still better than having single file components with too many code lines.
Typically it is best to create a new component in the following situations:
if the component will be used more than once across your app, especially if it isn't coupled to the parent component.
if the component has a lot of logic, or a big template, etc, then it is best to separate it so it doesn't bloat the parent component. Try to keep your components small and easy to reason about.
if the component has logic that can be tested in isolation from the parent component.
if the component has some internal state that would be easier to implement as a separate component with its own internal data that the parent shouldn't have to manage.
As for your list component, it seems like each list item is specific to the product list and won't be used elsewhere and probably isn't very complicated, so it's fine to keep it within the list component. Separating components out unnecessarily just increases complexity and memory usage (especially for lists with lots of items) with no benefit.

Refactoring into Vue Components: Readability vs Complexity

Background
I have a large form in Vue that I want to refactor to make it easier to see whats going on from a developer point of view. i.e. I'd rather work on sub-sets of the form in different files instead of trying to work on a single file with 100s of lines of code.
The form is simple (just inputs with v-model binding to data), and the main bulk of code is in the <Template> tag that Vue uses.
To reduce the parent file, my initial go-to solution was to refactor different parts of the form out into their own components. This achieves my goal of creating an easier to read parent file, and be able to work on small areas of the form in isolation.
The problem however is that now I have to deal with the complexities of parent <-> child component communication. This is easy when you have one parent with many children, but once the child components are refactored further and they too have children, passing all the form data back to the parent becomes overly complex with standard Vue coding.
The go-to solution for this problem is to use Vuex. But here lies my question:
Question
I've tried to improve the readability of my large form by refactoring into components, but in the process I've add the overhead of component state communication. Have I missed some more obvious way to refactor out my large form? Or do we just have to live with the complexity of components if we want to improve readability?

Vuex store vs component props: When use each method for component communication?

I learnt Vuex about 2 weeks ago. I think I have a pretty solid understanding of what Vuex (or Flux) is and how it works.
What I still haven't got is the feeling for when I should put a property in a store and when not. Do you know some guidelines on when to do it?
An obvious situation is, when components that need the same information are far from each other in component hierarchy. But what if they are close (are siblings or in a parent-child relation)? Do you always use component props to communicate values in such situations? If not, then when not and why?
Going extreme, in many situations I could imagine most of the values stored in a store and components having almost none props at all. Such situation would feel weird to me, but I'm wondering if maybe there is nothing wrong with such approach.
they say, Vuex is like glasses, you know when you'll need them.
But this is presumptuous at best. So at the risk of this question being closed as primarily opinion based...
I would say that using Vuex has three benefits:
Ease of access to data, no matter how far the components are
The store is a single source of global state
Good at handling asynchronous data changes
if you can meet two criteria, then it's a definite yes. But just because you have data between a parent and a direct descendant, doesn't mean you shouldn't use vuex. I often use vuex for items in the same component, but if the data is available to other components or especially if it is asynchronous (uses API) then it can still go into vuex.

Why use state management in VueJs SPA?

I'm trying to learn vue/vue-cli to make a Single-Page-Application.
I'm using the default vue init webpack
I want to use some data in multiple components. I also want to use some 'computed' variables in multiple places without having to 'recalculate' them.
For shared data everyone seems to recommend a state management system such as Vuex (or simpler alternatives of a plain object, yet from what I understand a plain object can't share a computed, and each component would have to recalculate that computed itself).
Since it's an SPA, there's a single focal point which I believe is App.vue, why can't I just have all my 'data' variables, and my 'computed' variables in App.vue, and in any other component just access the data I need via $root.SharedData or $root.MyComputed or something similar?
Am I misunderstanding something? Is there a major downside just using $root? I can't find much info about it.
To get started you may find it easy to have everything at one place like App.vue, But in later stages it will be headache to seek synchronisation between different components/modules, it is always recommended to have all common stuff to reside in the 'state' and avoid direct DOM manipulation using actions and mutations. Go through the state diagram of VUEX and its life-cycle to understand the importance of state management, however Vue js is light-weighted.