DEV Community

Are you committing these mistakes as a Vue developer?

Nihar Raote on September 30, 2018

I recently subscribed to an awesome podcast on web development called Full Stack Radio by Adam Wathan. There was an episode on Anti-patterns in Vue...
Collapse
 
hybridwebdev profile image
Hybrid Web Dev

So you say
" So both of them are used to carry out the same task. In the first case, we passed a value to the parent via an event and the parent then executes a method or does what's needed with that value. In the second case, we passed the method to be executed to the child itself, expecting it to execute the method on behalf of the parent."

And then you say there's not much difference other than stylistic. This is completely wrong and misleading. By having a child emit and event up that the parent handles, you create a looser coupling. By passing down a method that the parent expects the child to execute, you've now tightly coupled those 2 component.

The difference is, that in the former scenario, the parent only needs to know how to handle an event it expects, and the child only needs to know to emit an event up. In the latter scenario, the child needs to know specifically what method it's expected to execute. Additionally, it now has to also declare a property to receive that method.

Whilst the difference may seem subtle, trust me in terms of tightly vs loosely couple components, and refactoring/boilerplate etc, it definitely makes a substantial difference.

Vue docs very clearly dictate that the coupling pattern of components is data down, events up. Objectively, you're doing your readers and their clients/future developers that will inherit their code a dis-service by going against this pattern.

If you're going to teach, teach the correct principles please.

Collapse
 
napoleon039 profile image
Nihar Raote

I'm not sure if you read the article from the start or not, but I'm not teaching anyone anything.

This is all that I got from the Full Stack Radio podcast episode that I linked to. I listened to the podcast episode and wrote what I understood in my own words to share with people who might not have heard about the podcast or prefer reading rather than listening.

Now I'm not saying what Chris Fritz said is wrong. It could be that I misunderstood what he said. I'll listen to it again closely and look at the Vue docs about the coupling pattern you mentioned. I'll make changes to the article when I increase my understanding of it.

Thank you for pointing it out :)

Collapse
 
mgandley profile image
Matt Gandley

Eh, I don't agree with your needlessly scathing criticism of this.

You are correct, that the Vue docs do teach the concepts in the way you described. You are incorrect that using a callback method as a prop instead of responding to an event is the correct way to do this (see this thread: forum.vuejs.org/t/events-vs-callba...).

Your statement that callback props enforce tightly coupling is wrong. You are assuming that the child component must have information about the parent component's function, and must pass the correct values to that function as a result. Flip this concept on its head - you can design your child components to call whatever callback function is passed with a set of values, in the same way that a child emits a set of values. No real difference - the onus is on the parent component to design its callback / emit-responding function to handle the returned data correctly. We have plenty of JS APIs that work this way - you don't dictate what DOM events return, you respond to the parameters that are being returned.

The advantage that the callback prop method has over the emit method is that callback functions can be required, validated, and defaulted. You cannot require a parent component to respond to an emitted event. You could lose hours of work figuring out silent "failures" where a parent component is not responding to an emitted event.

The advantage that the emit method has over the callback method is that your child component does not need to check for or validate the presence of a prop. Your child component can just emit events. It's the literal inverse of the callback method's advantage.

Collapse
 
jareddahlke profile image
Jared Dahlke

Some of the things that are recommended in this article are not good. Beware

Collapse
 
napoleon039 profile image
Nihar Raote

Um, I'm not sure if you read the beginning of the article, but this is from the podcast episode where Chris Fritz gave these tips. I'm not sure whether a core Vue team member would give incorrect recommendations. It's probably because I didn't interpret them correctly. Let me listen to the podcast episode again and verify it.

Collapse
 
jareddahlke profile image
Jared Dahlke

heΒ₯Β yes I understand that it's from a vue core team member. I applaud you for being so studious and learning so much. I am not trying to be mean or anything here. But I am just saying that the problems I pointed out were SOLID principles that were created by the pioneers of coding and engineering, not by me. I will take the pioneers' advice any day over some modern day framework creator.

Thread Thread
 
napoleon039 profile image
Nihar Raote

Yes, I understood your intention wasn't to call me out on it. I thought you hadn't listened to the podcast because there are some who don't like listening to podcasts πŸ˜…. After all, that was my original intention behind writing this article, the tips given in that podcast and topics discussed were too good to not be shared. I didn't intend to be arrogant about what I wrote. It is, after all, something I repeated from a different source.

Anyways, I listened to the podcast again carefully and I feel what I wrote was somewhat too general. Although what I wrote is close to what Chris said, there are some words I failed to remember and omitted them. I'll rephrase those 3 points to better reflect what Chris meant when he recommended using Vuex in those situations.

From listening to the episode again, I think the main reason he recommended using Vuex instead of using props and event bus in those situations is that with Vuex, it's easy to keep track of changes in the state since Vue DevTools provides a way to trace the changes in the state.

I agree that using global variables is bad, and using global state is more so. I think even if Vuex is okay to use in a situation, it will be better to only have the components that require the Vuex state to access it.

I am grateful you pointed this out. Otherwise, I wouldn't have paid close attention to this. Listening to the podcast again and reading your comments made me realize I should be careful not to use Vuex just because it looks like a good situation to use it.

Collapse
 
nataliedeweerd profile image
𝐍𝐚𝐭𝐚π₯𝐒𝐞 𝐝𝐞 π–πžπžπ«π

Can you give some examples?

Collapse
 
jareddahlke profile image
Jared Dahlke

here's one for example, per this article: "If you find yourself doing one or more of these things then that's a good indicator that you should start using Vuex to manage the complex states in your project:

When you keep passing a lot of props to a component
Have the parent component keep track of the state of a child so that the siblings may interact with each other via the parent
When the props passed to a component are not used by that component itself but needed for another component nested inside it"

I think of state stored in Vuex as just a global variable, because it is. I think if you do some googling around and reading you will find that global variables should be a last resort to use, they shouldn't be used because they are more convenient (ie. "passing a lot of props to a component", 'having to pass to a grandchild component'), they should be used for when multiple components share a common state and achieving your objective without creating anti-patterns would be otherwise unavoidable.

Thread Thread
 
jareddahlke profile image
Jared Dahlke

also, as a design principle, you only want to expose the minimal possible information to each component. (eg. the users component shouldn't have access to the inventory component variables) Storing variables in the global state is exposing every component to that variable.

Collapse
 
gustojs profile image
Darek Gusto

Hi and thanks for the article. Can I please ask for a code example of the "mixin as a function" pattern you mentioned? I can't find it in official documentation.

Collapse
 
napoleon039 profile image
Nihar Raote • Edited

Thanks for reading.

Honestly, I haven't used mixins a lot. About using mixins as a way to have dynamically generated component behavior, I have a few examples but can't find a way to implement them.

Chris mentioned in the podcast that mixins have very specific use cases so maybe that's why it's hard to come up with a situation that justifies making use of mixins. I think he must have come across such a use case or something similar to it. I'll try asking him and get back to you.

Collapse
 
gustojs profile image
Darek Gusto

Thanks. I'm asking because it was explicitly stated in your article that it is possible, and "how to achieve that" was the exact question I was asked just a few days ago by another developer. I thought you actually managed to make it work somehow. I'll try asking Chris too and if I get an answer, I'll paste it here. Thanks a lot. :)

Thread Thread
 
napoleon039 profile image
Nihar Raote • Edited

I asked Chris over the weekend. The example he gave was from a situation he came across. I think he even mentioned it in the podcast but I think I forgot about it πŸ˜› .

The situation is that you have some input components that you're using for multiple currency handling. So depending on the currency option selected, a function would dynamically generate a mixin.

I'll try my best to implement it. Once he gives the green signal that the pattern has been properly implemented, I'll post it here.