تماشای این درس نیاز به اشتراک حرفه‌ای دارد.

Fix Ref Highlighting0:29

And in fact, if I switch over to the browser, notice we do not have highlighting there. Okay, let's fix that real quick. In Vue 3, I only need to create a variable with the same name as my ref. So let block = ref(). I will need to import that. And we'll set it to null. And again, notice we're importing that from Vue. Okay, so now I could say block, and then of course, at least at the time of this recording, we need to grab the value there. So if I come back and refresh, there we go.

Add Header and Button1:19

Let's wrap all of this within a div. And then at the top, I'll have a header section. And for now, we're just going to have a single button that says copy. Okay, let's have a look in the browser. Refresh. And yeah, we just need to do a little bit of styling. So tell you what, once you give me one minute, or if you don't care about this part, skip ahead, and we'll get back to the JavaScript. Okay, so for the header, why don't we give it a background color of something dark, maybe background of gray, something just a little lighter than the background here.

Implement Clipboard Copy3:33

So instead, I like to think of these refactors as being required to fight for their existence. And if it doesn't feel gross after the first pass, then I don't even bother with it. At least that's my personal approach. Okay, so when I call this method, sanityCheck, let's alert and prove that we have our event listener hooked up. And we do. Cool. So we know that the code snippet itself is already stored as a prop. So we can leverage the JavaScript clipboard API, which you can grab from navigator.clipboard. And we can say writeText.

So we can leverage the JavaScript clipboard API, which you can grab from navigator.clipboard. And we can say writeText. Then let's grab our props here. So let props, props.code. Copy the snippet. And then I'll say alert copied. Okay, let's give this a shot. So just to prove it to you, let me copy something gibberish here. And now if I click on this again, if I switch back to my editor, and I'll just paste it in here, you can see that was stored in my clipboard.

And now if I click on this again, if I switch back to my editor, and I'll just paste it in here, you can see that was stored in my clipboard. But actually, one little note if you're working along. In order for this interaction to work, you need to have a secure connection. So notice I'm already on a secure connection here, HTTPS. So if you're working along, make sure you do that as well. And a quick little tip, if you're using Laravel Valet, for any site, you can say valet secure, and that'll set it up for you. Okay, otherwise, this is not going to work. You'll get some error about not having the proper permissions.

Add Copied State Feedback5:49

But there's no feedback other than that alert. Maybe after I click on this, when it's in my clipboard, this text should change to copied. How would we do that? Well, it sounds like we need to track another piece of data. So let's add one here, copied, and that will default to false. But then after you copy it, we'll say copy.value is true. Okay, so now we can track whether or not the copy has completed. And what we'll do is here, we'll say, if it was copied, then set it to copied, otherwise set it to copy. Okay, come on back, give it a refresh, click it.

set it to copy. Okay, come on back, give it a refresh, click it. And now we have some more visual feedback. You could even disable the button if that's something you want to do. I don't think we need to, but that would be an option. And actually, yeah, if you want, we could even set up a timer. So maybe we track that it was copied for three seconds, and then after the three seconds, it resets. Okay, so we could say setTimeout. You know, this is just a silly example, but you might want to do it.

Create Clipboard Composable7:56

And yeah, Vue 3 composables are a good option. They can do a bunch of things, but you can initially think of them as Vue 3's equivalent to mixins in Vue 2 with the options API. All right, so here's how we work with them. I'm going to go to my js directory, and let's create a new directory called composables. That's a common convention. And another convention is for each composable to take the shape of use and then the name of what it does. So in this case, we're going to use the clipboard, so I might call the file useClipboard.js. Okay, next, we're going to export a function with that same name.

So in this case, we're going to use the clipboard, so I might call the file useClipboard.js. Okay, next, we're going to export a function with that same name. Again, we're following conventions here. Okay, so now I can return to that highlight component, and we'll import it at the top, like this. import useClipboard from that file we just created, and I'll give it a reformat. So now let's do this. Let's grab all of this. I'm going to group it all together. Yeah, all of this junk here.

I'm going to group it all together. Yeah, all of this junk here. Let's comment it out and just think about what we would want from this composable here. What would we need to track? So I could say useClipboard. We're probably going to need to feed it the code snippet. So I will send that through, props.code. And then what sort of things might I want from that? First up, I, of course, need a way to perform the copy, so I will call that copy. Next, I need a way to determine if it has been copied.

First up, I, of course, need a way to perform the copy, so I will call that copy. Next, I need a way to determine if it has been copied. And then I think we might even notice here we were manually performing this check, but I can imagine places here where I want to detect, well, if isSupported, only on that condition do I want to, for example, display the header. So that might be something I want to track as well. So if I bring it back, supported, and you get the idea. These are the sorts of things that I might want this composable to provide to me. Okay, so let's do this. Let's open this up in a split here, and we decided the clipboard function needs access.

Okay, so let's do this. Let's open this up in a split here, and we decided the clipboard function needs access to the thing that we are highlighting, so maybe text. And then ultimately, it needs to return these three things. But of course, those three things need to be reactive. Okay, let's get going. First up, we need a copy function. So let's switch back over here, and we'll temporarily uncomment all of this. And let's have a look at our copy function. I'm going to grab all of this here and bring it in.

And let's have a look at our copy function. I'm going to grab all of this here and bring it in. So now I can get rid of that piece of code. So notice I'm just slowly moving code from here over to our composable. Next, I can update this prop to be the text. Remember, the text would be the code snippet. All right, what else? This timeout here to reset it, that was just an example. I'm not going to keep it. Now this copied value, yeah, we need to track that as well.

I'm not going to keep it. Now this copied value, yeah, we need to track that as well. And we'll say let copied equals, and we'll make this a ref. Initially, it's false. So do note I imported that at the top. Okay, so now when I call this function, we have made this variable a copied reactive, and it will change after we perform the copy here to true. Okay, finally, we noted that we might want to track if the clipboard API is even supported in the user's browser. So that doesn't even need to be reactive.

if the clipboard API is even supported in the user's browser. So that doesn't even need to be reactive. That could be a simple variable, like let supported =. And here's what we had before. But in this case, it will either be equal to undefined or the clipboard API object itself, when really I just want it to be a Boolean. So two choices, I could just wrap this and convert it to a Boolean. Or let's bring it back. A more common way would be to check, is there a clipboard in the navigator? And now we have a Boolean.

A more common way would be to check, is there a clipboard in the navigator? And now we have a Boolean. Okay, so now I could defer to our variable here, and then also return that here, and we'll give that a reformat. Quick draft, but I think that will get it done. The only thing I see here, maybe there's an argument that the text we're copying should be sent through this function rather than the initializer here. I might want to change that. So I will shut this and switch back to our highlight component. And now, here is what we end up with.

Integrate Composable in Component12:20

So I will shut this and switch back to our highlight component. And now, here is what we end up with. Notice that once again, all of that logic and setup and initialization is tucked away behind a file. Which means if I need to create a different component in some other area of the site, I don't have to rewrite that logic, I simply import my composable. Then I call the function, and that will return to me all the data I require. Okay, so now we can use these. Our function is no longer copyToClipboard, it is copy. The copied one stays the same.

Our function is no longer copyToClipboard, it is copy. The copied one stays the same. And then if we want, we could say, because right now we only have a button within that header, only display the header if we support the Clipboard API. All right, let's cross our fingers, we made a bunch of changes, but with any luck, if I switch back and give this a refresh. Okay, so if I copy this again, it looks like it worked. Let's paste it in, and we're in business, it works. And yeah, that's the gist of it.

Clipboard APIVue Composables

دوست دارید گاهی خبرهای Laracasts را ایمیل کنیم؟