This course has been updated! We now recommend you take the Introduction to Vue 3 course.
Transcript from the "Mixins" Lesson
[00:00:00]
>> Sarah Drasner: A common situation that you might have is you have two components and they're pretty similar. They have a bunch of different things going on. So you kind of come to a crossroads and you say all right, well I could split this into two components and have them live separately.
[00:00:17] But then if the functionality is similar enough you have to go update the functionality of both of them, kind of defeating the premises of dry. The other option is we have all of these things available to us with prop, so we could create one component and change them with a lot of props.
[00:00:36] But once we get to a lot of props, you get into an issue where in order to read that component, the person has to understand a lot of context before they get going and able to use it. So Enter mixins. This is where mixins are really exciting. I really like this quote Michael Feathers, object oriented programming makes code understandable by encapsulating moving parts.w Functional programming makes code understandable by minimizing moving parts.
[00:01:03] And so I think when you're using mixins properly, they are really, really great for a functional programming mod Model. We are encapsulating one piece of functionality so we are creating something that's smaller that we can re-use in a couple of different places. Like let's say two components were pretty different but they share one common functionality that you know is always gonna be tied.
[00:01:25] That's a really good instance where you might wanna create a mixin and create a small function that's pure that you ca use for both instances. So if written correctly, they are pure they don't modify or change this outside of the function scope, so you always reliably get the same execution value with the same input on multiple execution.
[00:01:51] That's basically like our really big core tenant of functional programming is keeping things pure. So that can be really really powerful. I'm gonna show you a tiny example of this because otherwise it will be a little bit too much to take in at once. So we looked at that model before.
[00:02:10] The model just toggles. Again, this is like a really, really simple example so it's not probably the use case I would it for but just for the purposes of understanding. If we have a model we saw this model earlier where it's toggling the state of showing or not showing.
[00:02:27] Let's say we also have a tool tip and that's also showing or not showing but they look different and there's a lot of different pieces to them. Tool tips have slightly different content, they have different layout, same with motors. But that core functionality is similar. What we could do is we could extract just that functionality and say something like const toggle and then data return is showing false, that's just the toggle that we have.
[00:03:01] And then the modal and the tool tip become smaller, and we say mix ins toggle, mix ins toggle and we're basically able to consume that small function into these components and reuse them, so that can be really, really nice. So if we have a modal, Show child, put Click Here Please and then I have Tool tip and a modal and they work slightly differently as well and the functionality because we're clicking on different things and we have different slots for each one.
[00:03:40] So actually let's show you the code. So in here, let's go to CodePen.
>> Sarah Drasner: In here we have this const toggle like we mentioned. Here is our Modal, here is our Tooltip, and here is our Vue instance with our components. We have appModal and appTooltip and a divider.
[00:04:06] And here's our modal, we have a bunch of things in here like hiding the child, and showing the child, and toggling. And we have another kind of markup for the tooltip. They don't share the same markup. Some examples of uses for mix ins getting the dimensions of the view port and component.
[00:04:30] That might be something you do on a few different components and they don't really share any other thing about them. Maybe gather mouse move events. That might be something that you execute on differently on different components but you need to still gather the same events. You don't want to redo all of that code and they're not really the same component at all.
[00:04:47] I showed that example with SVG earlier where I made charts and created the axes. And something like that is something that I've used in a few different components. Because I don't want to keep rewriting these base elements of charts or something like that. There's also a really great repo by, I'm not gonna try to say his last name, Paul [LAUGH].
[00:05:12] And there's a bunch of different Vue mixins in there. One caveat I will say is that they use CoffeeScript, so if you're with CoffeeScript, it might be different from the way that you're used to working. There is a concept of merging with mixins because you're actually bringing it into another component that has different kinds of values.
[00:05:35] So by default mixins will be applies first, and the components will be second, so that we can override it as necessary. So the important piece of this is that the component has the last say. You're gonna Vue assumes that you probably need the thing that the components is dong, so if you accidentally have two things that are happening that are similar, and I'll an example of this as well.
[00:05:57] So if I have something like these two mounted, you know actually another thing to mention is that mixin's have all of the life cycle methods available to them just like the components do. So we have mounted and we have a console.log('hello from mixin') and a mounted in the instance or the component and we say console.log('hello from vue instance').
[00:06:20] So if both of these things are in the mounted they both execute and we get hello from mixin, hello from vue instance. Both of those things will happen, but let's say we have something like a method where they're both called say hello. Like I have a method that I've called say hello and mounted, I execute that method.
[00:06:44] Then I do the same thing, this one is hello from mixin and this one is the Vue instance or component What we're gonna get in the output in the console is both of those things firing, because we called, just like in the other one, both of those things are gonna execute.
[00:07:01] But one of them is gonna be overridden because it's going to say, wait you have another thing called say hello. The component has the last say, the component is going to win and we're going to say hello from Vue instance Global mixins. Warning signs. [LAUGH] Lots of warning signs.
[00:07:21] Global mixins are different from filters or components that we could register, or something like that, where we create it and we can use it as we want. Global mixins are literally applied to every, single component. So I would say almost never ever use these. One example that I've had that people have found them useful, if you deplug in development and you need access to all of the components, but even then I would say really use this with caution.
[00:07:52] The use is extremely limited and should be considered with great caution. We're, so if we say something like, this view.mixin, so that's how we would register a global thing in that main.js file right before our Vue instance, we would say Vue.mixin. That console log, but now appear for every single component.
[00:08:16] For this instance, you have a noisy console. But there's other things that could happen that could be really bad. If you want, I'll take a look at a real-life example. We could go to the Mickson's example in the repo. So you go
>> Sarah Drasner: So, here we've got the modal and we've got the tool tip here and then we've got merging.
[00:08:59] So I'm gonna open up the console and we've got that hello from merging component, hello from merging component for both. Let me go show you what that is. So in this one.
>> Sarah Drasner: In our source we have or mixins, we've got one called toggle that we had used in these components for tooltip and mortal.
[00:09:23] And then we also have this Merging Component. We sayHello for Merging Component and this.sayHello. We're also calling this component called hi that has that sayHello. So, the Hello for a Merging Component wins. I had mentioned that the Vue mixin would be registered in the main dot js file.
[00:09:41] So remember this main .js file we have our Vue instance. We can uncomment this and bring in this new global mixin. And now we have [LAUGH] Hello from global mixin. Hello from global mixin. And this is actually fired three times and then two times because it's firing for all of the mixins in all of the components.
[00:10:02] So no [LAUGH] use with caution, red flags everywhere. Mixings are I think are really useful. I would really use global mixins very carefully.