
Lesson Description
The "Using defineExpose" Lesson is part of the full, Intermediate Vue course featured in this preview video. Here's what you'd learn in this lesson:
Ben briefly discusses defineExpose, which allows child components to share properties with their parents. While this can be useful, it risks breaking encapsulation. He emphasizes that it should be reserved for edge cases to avoid messy code.
Transcript from the "Using defineExpose" Lesson
[00:00:00]
>> Ben Hong: Before I do the exercise, I'm gonna give you all a sneak peek into something that it is not heavily documented, this is an intermediate view thing, so we're gonna talk about it. And so this leans a little bit more advanced, but what I wanted to show you before we moved on to the exercise is there is something inside of Vue.
[00:00:20]
There is a new thing. At least I think it's new for a lot of people. It's called Define Expose. What Define Expose does. Actually, let me just caution this. I can't put a warning enough on this. This is an advanced technique. You should not be reaching for this.
[00:00:41]
I wanted to share this because I do think people will find use for it, but this should not be your default thing to use. I cannot stress that enough. Okay, disclaimer said define expose. Everything I said about slots, where I said, like, you know, you're exposing it specifically to the slot.
[00:00:57]
Define expose kind of like blows that up. And so it says, in this particular case, let's say double count, and then this can just be a method that then says, current count value equals current count value times 2. Easy enough. What it does is you give it an object and you say, hey, I want my parent to have access to these properties wherever.
[00:01:36]
So you're thinking, okay, how does that work exactly? Well, the way it works is you need to first access the child component itself. And so if you haven't done this before, this is known as a template ref. So we can basically say slotDemoRef = useTemplateRef. And so what that does is it basically allows you to assign an ID to your component that basically allows you to fetch the DOM element you're actually picking up.
[00:02:01]
So in this case, I'll just call it slot demo. And then here we go, just like that, okay? And then once you have that, you can basically then say if slot demoref exists, because when the component is initialized, it does not. You will notice value. Everything is exposed or sorry, everything you define is exposed.
[00:02:35]
That thing where I mentioned that, count is only stuck to the slot. Define Expose says, actually, we're going to let you expose it up here and you can play with it. Okay, so this is clearly kind of dangerous [LAUGH] because it blows open the walls, right? You're like, man, no boundaries.
[00:02:54]
This is amazing. With great freedom comes great responsibility. I remember when I first learned about this, my first thought was, why the heck would I ever use scope slots? I'm just gonna expose everything, right? That's dangerous, for obvious reasons. The reason you Scope things is because you want it to be used within a certain context.
[00:03:16]
That is still the advantage of a scope slot. And why I would say you really should be still using that as your default. The reason you might expose however, in particular methods and I reached out to the community and talked to a few people. Some of them had like let's say a modal dialogue, right?
[00:03:32]
A modal dialogue that would close itself. That's really not something you want to like have to like abstract out. And especially if you're generating a different closed modal for each modal that you're generating, it's kind of weird to like abstract that out so that the parent also can get access to it.
[00:03:48]
And so define expose is actually in this regard a very elegant way to say, hey look, you want to close this child's modal, right? Right. So again, again, just for the sake of documenting, if there was a function called like close modal and it would just, you know, set whatever.
[00:04:04]
So const isOpen = ref(true) and it's like, isOpen.value = false. Like we already have this built into here. Then there's really like especially because a lot of times we are doing things programmatically, right? Like it's nice when you have a button that you click that closes the modal.
[00:04:23]
But a lot of times we might be chaining events together, right? If we know that the parent is doing something at the top where then it eventually needs to close as a child. Well now you can actually then call that and just say ref value. And you always need the optional because remember that the component is not necessarily mounted at the initial part and then at that point then you can say close modal and now you can programmatically invoke the child's method.
[00:04:48]
Again, I can't stress this enough. Everyone I've talked to says I struggle to find use cases for this, but it does exist. There's a reason this API exists. I want people to know about this because I think that's part of our role as developers is to understand these kind of techniques which at face value if used incorrectly of course can make a lot of spaghetti code make our lives miserable.
[00:05:09]
But we're learning to use the trade offs and more importantly when we don't have a choice. I think someone else I talked to, they have third party UI libraries where they have methods that are built into those UI libraries. It's kind of redundant to create a composable that refers to the components UI library that then you kind of like redirect and so they just expose those methods directly through define Expose.
[00:05:35]
And then they're just leveraging the APIs directly. And so again, is this an edge case? Yes, that should first thing when you see this edge case. But define expose is a thing. And so, yeah, now that you know. Now you know.
Learn Straight from the Experts Who Shape the Modern Web
- In-depth Courses
- Industry Leading Experts
- Learning Paths
- Live Interactive Workshops