Episode 54 - March 22, 2021

New in Vue 3 Ecosystem: Vuelidate, FormVueLate, Global-Vue-Events, & The Official Vue News with Damian Dulisz

00:00 / 00:00

Shownotes

Overview

Today we welcome Vue.js core team member Damian Dulisz onto the show to chat about Vuelidate and FormVueLate; two powerful tools for validating Vue.Js and building schema-driven forms. We open our conversation with a deep dive into how Vuelidate serves the Vue community. After exploring why Vuelidate is different from other validators, Damian shares details about its structure and current iteration. We talk about the benefits of Vuelidate’s ‘dirty’ function before looking at creating schema forms with FormVueLate. Linked to this, Damian explains FormVueLate’s architecture, adding insights on the high level of control that dynamic forms give you over values. Later, he touches on Vuelidate’s development cycle, using Vue global events to create shortcuts, and where you can go to hear the latest Vue news. From Queen’s Gambit to Alias Grace, we wrap our conversation by sharing our picks of the week. Listeners will hear how playing Demon Souls prepared Damian to train his puppy. Join us to hear more about what Damian is doing to take Vue to the next level.

  • Key Points From This Episode:
  • Introducing today’s special guest, Vue core team member Damian Dulisz.
  • Ari Clark talks about what Vuelidate has added to her workflow.
  • Exploring the role that Vuelidate serves in the Vue ecosystem.
  • Hear about the main change made to the current version of Vuelidate.
  • Insights into schema forms and terms like ‘touched’ and ‘dirty.’
  • When you would want to use schema forms.
  • The programming power of dynamic forms.
  • Damian explains FormVueLate’s uses and plug-in architecture.
  • Where Vuelidate is in its development cycle and the challenges that Damian has overcome.
  • We ask Damian about Vue global events and building global shortcuts.
  • Where developers can hear the latest developments in the Vue world.
  • From Queen’s Gambit to Demon’s Souls, hear our picks for the week.

Tweetables:

  • “The next step after schema forms is creating dynamic forms, where the users can set actions, or rules that allow the form to transform based on values inside and external to that form. It’s crazy powerful.” — @DamianDulisz [0:20:02]
  • “We’re in a moment where we can introduce breaking changes. If you're using Vuelidate, or plan on doing that and have some ideas, let us know.” — @DamianDulisz [0:32:55]
  • “Playing Dark Souls was challenging and quite frustrating. It was good training for when my puppy arrived.” — @DamianDulisz [0:46:55]

Guest's Picks

Links Mentioned in Today’s Episode:

Transcript

EPISODE 54

[INTRODUCTION]

[00:00:00] ANNOUNCER: This episode is brought to you by Ionic. For more information, please see ionicframework.com/vue.

[EPISODE]

[00:00:19] T: Hey, everybody. Welcome to Enjoy The Vue. I’m Tessa. Today on our panel, we have Ari Clark.

[00:00:25] AC: Hello.

[00:00:27] T: Our special guests for this episode is Damian Dulisz. Damian, would you like to introduce yourself?

[00:00:32] DD: Hey there. I'm Damian, member of the Vue core team. You might know me as the person that is sending you the Vue.js newsletter, and also the guy that is maintaining and creating several open source libraries, which you might know, the Vue-multiselect, Vuelidate, and Vue global events. Thanks for having me on the podcast and that's no end.

[00:00:59] T: Thanks for coming on the show, Damian. I'm curious what everybody, and I guess, by everybody, I really just mean Ari, and then I'll go — everybody's experiences with Damian’s packages if you've used them. Ari, do you want to go first?

[00:01:14] AC: Sure. Yeah, I'm a big fan of Vuelidate myself. Silly what I've used — sorry. It makes forums just so much easier. Because at first, I was trying to do form validation by ‘roll your own.’ God, that got nightmarish real quick. But it’s super easy Vuelidate. Yeah, I'm a huge fan.

[00:01:36] DD: Thank you. Do you have any reasons, like what did you enjoy the most? What's your favorite part of it, so we know what to focus on?

[00:01:44] AC: Well, it made it really easy — the built-in validations. The fact that you had an IP address one, because I actually needed to validate IP addresses. I was like, “Thank you.” Yeah, just it covers honestly, most scenarios. I did have to do a custom validator. Honestly, that was also super easy to implement. It's easy and intuitive.

[00:02:09] DD: Okay. Yeah, I can totally relate to your point, trying to first build your own foundations by hand. This is how Vuelidate, actually. I guess, every library starts this way, where you just have a problem, you try to solve it. You find finally, after a lot of struggles, you find a way that you think, “Hey, this could be something that I could share.” That's how Vuelidate has been created.

I think, at the time, it was pretty new, because the approach was, well, totally different. Where, instead of focusing on the form elements, we were focusing on the actual data model. So decouple it from actual inputs. I think it worked and I think it fit into the validation scene in Vue, where we have a couple of very good solutions. I think currently, V-validate is probably the most popular one.

In some cases, yeah, I agree. Vuelidate could be — because it is — the main idea behind it is different, it could fill its role, or fill a certain need. Which, I think it is good to have the option. In my case, it was trying to validate a lot of tables with cross-cell relationships, where the rules were dependent. In a row, specific cells were dependent on each other, but then the rows were – validating rows, were dependent on other rows. Then the rows were dependent on external data that was most affecting the validations.

It would be very hard to design it in a scalable way using just inputs, especially when, due to performance, you have to remove certain inputs. And just show the inputs on a click, like the cell is active, and then it's inactive. That was the main reason why the library was created. I'm so happy that people find it useful, even though it's maybe a bit less friendly for the beginners.

[00:04:18] AC: I guess, I can see that. I will admit, the first time I looked at it, I found it intimidating.

[00:04:27] DD: Understandable.

[00:04:28] AC: Maybe, I was supposedly just because like, I just look at this wall of text with a bunch of dollar signs. I’m like, “Mm-mm. Bye.” For those who haven't looked at the documentation, the first thing you encounter is yeah, what appears to be just be a wall of properties. Once I actually took the time to understand how it was working and what each property actually meant, I realized it was incredibly powerful and that I can choose what I want to actually key off of.

For example, you can check for errors on the entire structure, or just in one property. It allows you to validate not only on a field-by-field basis, but the entire form, which is so useful. Also, I liked the ability to track whether or not the input had been touched or not.

[00:05:24] DD: Yup. Although a lot of people have had a lot of issues with, like, the behavior of whether it should validate — even if someone hasn't been interacting with it, or not. This is actually something that we fixed in version two. For Vue 3 and for Vue 2, have you maybe tried it, the next version?

[00:05:45] AC: I have not.

[00:05:47] DD: That's okay. That's okay. It's still in the —

[00:05:48] AC: Haven’t had to do forms at my new job yet, which I'm grateful for.

[00:05:54] DD: It's still in alpha so it's probably not as stable. Although we do use it on production in at Course Dog, so the company that I work on.

[00:06:05] AC: Yeah. I feel that's different, because you maintain it.

[00:06:10] DD: I think it's already pretty solid. I think there are a few very nice additions that you might find very, very useful. One of them is that, and this is actually something that we have a very heavy case in Course Dog, because there is a lot of forms, and also forms that are built by users. Like schema-driven forms.

One of the use cases that we needed was, how do we handle cases where we need to let the parent component know of the validations results from a child component? The old version of Vuelidate doesn't really support this. The recommendation was to set up all the rules, the validation rules in the route component, and then just pass the errors. It creates an additional coupling, because then some form components can’t really have their own validations, because they are depending on validations coming from the top, and so on and so on.

Instead of that, we figured like, hey, then you provide — inject API in Vue 3 is much more powerful than in Vue 2. Let's just use that. Right now, if you have a nest component, and if you use Vuelidate, through use Vuelidate, or the old syntax, that results will be sent to the top if there is a parent that also has used Vuelidate. The composition function that we are exposing, or is using Vuelidate, and the results will be injected to the parent, and also combined in those aggregate properties. Like hey errors, invalid, and so on and so on. Another addition is that all the built-in validators, like the IP validator that you mentioned, have been in error messages that you cannot obviously overwrite.

If you have a component that has several nested components and those components could have another — more nested components, all of the validation results will be sent to the very true, the parent chain, without you having to actually do anything. The only thing that you need to get all child components validation results is just do the learn side V, or just Vuelidate results, whatever, equals use Vuelidate. It's just going to collect everything, built in the aggregates that will check whether the whole form is valid or not, will collect all of the validation errors, whether it's still key, whether there’s any deal or key nest inside.

You can also use the touch, or validate methods to propagate the patch through all of the nested components to — for example, if you want to have an enabled submit button that should disable itself once you click and turn everything red, you can do that very easily. You just, in the root component in the form, you just have the button and then some from inputs, or other components that have those inputs. All you need is you just get the Vuelidate. You do touch and then check whether it's invalid or not and make their button disabled, which I don't know how we never got to this in a previous version. I mean, that should be the most obvious solution there. I’m very sorry, everyone had to work with Vuelidate without this.

[00:09:49] T: If you get all the child validations is that a flat structure? Do you need to worry about naming collisions?

[00:09:56] DD: You can actually pass your own string that will be used to register the child validations. They will be shown as nested — similar, where, as right now, you have data property, and then you would have underscore or something. There, you would see the validations from that nested competent. You don't really have to do that because by default, will use the Vue component instance ID, which is unique. Even if you do V4 loops and so on, it's still going to work and it's going to work very nice.

Also, React if you had — you have a list of, I don't know, like form cards that you can add a new card and each of those cards has its own validations, which are duplicate rows. It's the same component. And it's still going to work, because those components, those have different component instances as an IDs and they are unique enough to handle that.

[00:10:58] T: It sounds like the main changes that we've discussed are creating a cleaner shape for the data and also, automatically getting data from nested validations by default, is that right?

[00:11:10] DD: Yup. There are other improvements. For example, you can pass a property called lazy, or $lazy as a config, and it will actually disable, make all validators lazy, and they won't evaluate until you interact with, or touch a field. To make it easier, you can use either or the whole Vuelidate config, or for specific properties, you can pass config param, called $autoDRT, set to true. Then whenever someone interacts with this property, it will set the DRT state to true, that's also triggering the validators to evaluate.

Although we made this by default, as validators being lazy, but it turns out like, it was a huge breaking change. I mean, obviously, it's a breaking change. We reverted back to having the validators be executed eagerly, immediately. Then if you want, you can make them lazy by default, or even make specific validators lazy. Which, I guess, might work very nicely for acid validators.

[00:12:27] T: Earlier, you mentioned schemas and our schema forms. I want to say, it was at VueConf this year, but it almost feels like that can't be true, where you surveyed the audience and asked them how many were familiar with and use schema forms. At least for the VueConf US audience, the numbers were pretty low. I'm wondering if for listeners who are in that demographic, if you could take a moment to explain what schema forms are. Also, while we're at it, I guess what dirty and touched mean?

[00:12:58] DD: Oh, yeah. The choose of words could be weird. Dirty means that a field has been interacted with. In terms of inputs, someone has typed something into the input, and the data has changed at least once. Touch means, I guess, like having a cake. If you put your finger in it, you touch it and it's just dirty.

[00:13:27] T: The cake is dirty, but it's not like the form is dirty, right? It's just touched?

[00:13:31] DD: Yeah. That's why you have, like, the any dirty. Just one piece of the cake is dirty. If you touch everything, the whole thing will be dirty.

[00:13:43] T: If I type something and then delete it, then that would still be dirty, right? Whereas, if I just put my cursor inside a field and then click out of it, then it's been touched, right? I don't even need to click out of it. No?

[00:13:57] DD: If you were to interact with — so type something and then delete, it would be touched, because you actually touched, or modified the data, even if it went back to the initial state. It's like, you got the cherry, you look at it and put it back. I mean, it has been touched. It could have been possibly dirty.

[00:14:18] T: I thought dirty was a subset of touched, or a super — whichever one it is. I thought, if it's dirty, it's been touched, but not vice-versa. That's not right?

[00:14:28] DD: I guess it depends whether you use the alt dirty config, which — if you interacted, it would change, or in the old Vuelidate, the dollar sign model helper. So that it's tracking interactions with the data model. Because Vuelidate is not really coupled to the specific inputs, but to the data, if you just move your cursor through, or click on an input and then just tap to something else, as long as the data hasn't been modified, it's going to be considered pristine, or yeah, not dirty.

[00:15:04] T: But touched?

[00:15:05] DD: No. Touched, there is no touched state. There is just touch as a method to make something dirty.

[00:15:12] T: Got you.

[00:15:14] AC: For example, I found it useful when I wanted to remind a user that they do need to enter their name. And if they skipped that one, as soon as they've skipped it, I'm like, “Hey, I need your name. Thanks.” If you click into it, but you don't type anything, it won't be dirty. But as soon as that element loses focus, I want to be like, “No, it's dirty now. It's not valid.”

[00:15:42] DD: You probably just use the add blur, and then touch the field.

[00:15:46] AC: Exactly.

[00:15:47] T: Got you. I always thought that was touched. I guess that makes sense to think of touched as a way to make things dirty.

[00:15:52] DD: I guess, touched might have been better. Yeah, breaking changes. I don't think we can change it right now. There is recent. You can make, undirty everything, which would be nice for a cake.

[00:16:05] AC: Just smooth it over.

[00:16:07] T: Right. So it’s like, when you go outside and come home, you want to wash your hands before you touch anything, and that will reset the virus off your body or something. I don't know. That was terrible.

[00:16:16] AC: Oh, COVID times.

[00:16:21] DD: Except, you would probably also forget everything that you experienced outside. I mean, from a foundation perspective, it doesn't really matter, because it's purely derived from the state.

[00:16:35] T: Yeah. That was actually a plot point last night in the show I've been watching. They were like, “Let's start over and forget everything we've gone through.” I was like, “Okay.”

[00:16:43] DD: Is this Dark? No?

[00:16:45] T: Oh, no. It's a comedy. The opposite of Dark.

[00:16:50] DD: Okay, what's the name of it?

[00:16:52] T: It's called Startup. I guess, I can talk about it more in the pick section. I forgot I was watching a new show.

[00:16:58] AC: Because yeah. I’m super curious now. Stay tuned.

[00:17:04] DD: Tessa, you mentioned the schema forms, right? The schema forms are forms that. to use them, you have to define a schema. Which usually looks like a JavaScript object, or a JavaScript array of objects. Then the schema is being used by a library, or your own component to create the matching form inputs based on the schema. Then the whole thing has its own foreign value. Then that can be used.

It's not really useful when you have just static forms in your application, where the fields are always the same, or maybe you have just a very basic like, well, if you check this checkbox, you have an additional selector, or additional input. It's probably super easy to just do it inside templates. Once you get to the point where you have a lot of logic in the form, where you have to use different components based on different data, and so on, and so on, it gets very complicated to maintain it.

Instead of that, you can use a schema form, or a schema-driven form, where, because it's usually easier to modify and manage JavaScript objects than whole template pieces. Instead of doing V if, as V if, as V fast and so on, you can just have a function that will just tell you like, “Hey, if that's the case, use this component and initiate it with those props.” A schema form is literally a component that is a wrapper on ‘component is,’ or back component column is, which will become one of the components that you pass there. If you pass a component is, same form select, it will transform into form select. That's the main idea. When is it useful? It's extremely useful when you need to have users create forms. For example, if you have type form, or Google Surveys, like what was the name?

[00:19:29] T: Google Forms?

[00:19:29] DD: Google Forms. Yeah. Surveys. Geez. For example, you have users build the forms. You have to save them as JSON. Then you have to be able to interpret it. This is where schema forms shine. At my current job, we ended up into taking the next step after schema forms, and actually creating dynamic forms, where the users can actually not only build a form, but they can set actions, or rules on forms that allow the form to transform based on other values inside that form and external values.

I think it's pretty crazy and very powerful, because you can literally program your own forms to fill in values, change the validation rules based on a combination of different conditions coming from other fields on the form, or may be coming from additional context. This is where schema form shines, because everything can be translated into a JSON object that we can save.

[00:20:46] T: Is it basically generating the correct type of input based on the data type?

[00:20:53] DD: Yep, but more.

[00:20:55] T: Got you. Right.

[00:20:57] DD: The base idea is super simple. It's just like a switch, where you just put the correct components, and you need a unified way to collect the value from it and combine it inside the form result. That's it. From there, you can just go crazy.

[00:21:15] T: Yeah. I mean, listening to you describe it, I feel there was maybe a missed, or future opportunity here to incorporate transformers into the library name somehow. There's even that aspect of — I don't know when it's called in English, but when you have a bunch of robots that are like a team, but then they can all combine to become a super robot, it sounds like that to me.

[00:21:40] DD: With Marina, mostly, we started working on —

[00:21:43] T: I was totally about to bring up her book. Nice.

[00:21:47] DD: We also build a library together, called FormVueLate, which actually has a plugin system. There are certain plugins, one for Vuelidate, one for a V-validate, which is the idea where you have to see the score formulate, I don't know, robot. Then you have other robots that can be added to it. It actually works as a transformer inside. The way it works underneath is you have the schema. Every field definition is being piped through the plugins. Then the plugins can apply transformations and add their own properties, or interpret the schema. So the actual content that is being put inside the components is a bit different. That's the first part.

Then you have the second part that is applied on the component level. Every plugin has its own component wrapper, which is usually a render risk, or higher order component. More like a higher order component, which takes the transformed schema, make something with it. For example, in terms of Vuelidate plugin, it sets up the Vuelidate, use Vuelidate validation rules based — and extracts the validations from the schema.

Then inside, it just renders the original field component that the schema form wanted to render. It just wraps it with the validation rules and then, potentially adds a validation error component, which shows the error messages. It doesn't really do anything. It doesn't require any additions towards the, or within the form inputs, or feed inputs. It's just the transformer and wrapper that are being added based on the plugins that you're using. We hope and still hope that there will be people interested in creating more plugins, because I assume the idea is very powerful. Yeah, it's a specific use case.

[00:23:57] T: Well, when you talk about plugins and plug in architecture, what does that mean? Because I feel like I see that described in so many places. For example, with Vue, a lot of the changes of the last years, we're moving towards a plugin architecture, and I'm like, I’m not sure I know what that means.

[00:24:13] DD: Okay. It's not a plug-in in terms of Vue plugin. It's more about, it’s FormVueLate plugin. The way it works, you have a factory function, where you pass all of the plugins, when you create the schema form component definition. Because, in Vue, a component is an object, until you create a new instance of it. Before you create the component and put it inside Vue, you can transform the object any way you want it. What actually happens there is we take the original schema from component, which is just this object with a setup function. Create a new object, which calls the original setup, from the schema form from the original implementation of schema form. Takes the original results from their setup that are being returned. Then it has to return them — those results. Then it can also apply some modifications, or add its own properties.

[00:25:19] T: It's like a decorator?

[00:25:21] DD: Yeah, yeah. That's like a decorator. I think it could be — well, that's probably — Wow, that's genius. Because I haven't seen anyone do this, at least not yet. Maybe someone has already done that. Because it's a higher order, or decorator, where you take the function, you decorate it with something. The way it works, it executes the original function, takes the result, does something with it, and then returns the modified version, which we could say the plugin system is applying decorators on top of the original schema form. Yeah, it can do a lot of things.

I guess, that's the benefit of the Vue composition API, because almost everything can be put inside the setup. Because you have just one point that you need to extend. Here is what goes inside. This is what comes back. You can do whatever you want and you just override some of the properties, add some new ones and so on. Which, I think, might have been possible with the options API, but it would have been much more complicated, because you would have to override specific methods and create a shadowed version of a method that you'd have to use the original method, rename it to something else, and then create your own method that would just mimic the original one, and then do something extra. Yep.

[00:26:54] T: It sounds like, if I was observing it just from the outside and not knowing how it was working, I might think it was middleware or something, because it's taking the input and giving me the output, but may be augmenting it in between. It's different, because I need to make sure that all of those changes, I apply them to the factory function before I ever use it. Otherwise, I'll be in a world of pain.

[00:27:18] DD: Yeah. That's also similar. I guess it's a popular pattern. The thing here is that from a user perspective, you don't really have to do anything, except for just, like, “Hey, input the plugin, import the factory function, create your own component. Yeah, put those ingredients and it's going to come up fine.

After that, you just pass a slightly modified version of the schema. In case of Vuelidate, you have those extra validations, property that you pass for each field. Those will be sent. Those will be sent in those wrappers. Then also in the root, you can just use Vuelidate and you will get all of the nested validation results, which is also one of the reasons why that change was so much needed. —

[00:28:13] AC: I will say that if listeners are interested in learning the foundational patterns behind building schema-driven forums, I do highly recommend Marina Mosti’s book, Building Forms with Vue.js. That was my first introduction to both the schema-driven pattern and also Vuelidate.

[00:28:31] DD: I second that. I had a look at it. I even have a copy. Yeah, it's very good.

[00:28:38] T: Yeah.

[BREAK]

[00:28:39] T: Oh. Hey there, Alex.

[00:28:41] A: Hey, Tessa.

[00:28:43] T: What's got you so down?

[00:28:45] A: I need to write a native mobile app, but I’m just a simple Vue developer. I don't know how.

[00:28:52] T: Oh, well. Have you looked at Ionic?

[00:28:56] A: The Alanis Morissette song?

[00:29:00] T: No, silly. Ionic. Ionic is a platform for building mobile apps with the web.

[00:29:06] A: Whoa. What is happening?

[00:29:09] T: With over 100 components and pre-build animations, Ionic gives you building blocks to make awesome apps with ease.

[00:29:16] A: Oh, no. We're trapped in an ad read.

[00:29:18] T: Best of all, it integrates with Vue. Getting up and running is easy. You can use your existing skills to ship native iOS apps, native Android apps, and progressive web apps without any hassle.

[00:29:32] A: Wait. I can use Vue to write a mobile app?

[00:29:36] T: Yeah, that's what I've been saying this whole time.

[00:29:38] A: Whoa. Hot, dang. I guess, it's high-time I give Ionic.

[00:29:44] NARRATOR: To get started, visit ionicframework.com/vue.

[00:29:52] A: The heck was that?

[00:29:54] T: Just the narrator. Don't worry about it.

[00:29:56] A: Oh, okay. Be sure to tell Ionic, you enjoy the Vue.

[EPISODE CONTINUED]

[00:30:08] T: Speaking of introductions to Vuelidate, I mean, Damian’s already heard this story, I think. Basically, I was trying to decide should I use Vuelidate, or V-validate? At the time, Evan was doing a deep dive Vuershop that I was in. He was like, “Blah, blah, blah. Vuelidate.” I was like, “Okay. I guess I'm going with Vuelidate.” I don't remember for sure, since I was flipping between the two of them at the time. I think it might have been Vuelidate. The changes were being pushed so fast that I didn't realize I was a version behind what was documented. I was trying to use features and I'd be like, “Why isn't this working?” Then I realized, “Oh, they pushed out a new version yesterday.” It was that fast.

[00:30:49] DD: Oh, yeah. That was the days of very crazy development. Right now, it's a bit more stale. I think we are getting close to a better version, which should be stable, pretty stable for a beta. Because we are still getting a lot of feedback on — and still getting some new feature requests. For example, one that I think would be very nice is to introduce scopes. But also, something that I want to call sub-propagate, which allows you to control whether which nested components validations you will collect.

From a parent perspective, you could say like, “Hey, I only want to collect validation results from this sub-form,” and then you have another — the same component, because you can have multiple use-validate usages inside a component. You could say like, “Hey, but I only want to collect the validation results from this list of forms.” This is a case that has come up when we had a user, have a component with a form where you have a model, and then the model had its own validation rules. Because there were some errors, those errors also showed up in the parent component, which — because it was a child component.

The model was a child component of the main component, which, well, it's pretty obvious, like right now, but we just haven't considered that this could be an issue when we were designing it. I think what we can do is either have the, or maybe both have the ability to specify which nested, or child components, like which we want to collect validation results from, or maybe have, for example, in the model, you can just add a conflict, like stop propagation, and it will just prevent those validation rows from being sent to a parent, or any ancestor. This should help solve this problem very nicely.

We still have a lot of ideas and we are open to — because this is the very moment where we can introduce new stuff, and also make some changes, even some breaking changes. Because once we roll into the stable, we probably will try to stick to and not make any drastic changes. If you're listening, and I guess you are, otherwise, you wouldn't hear me saying that. If you're using Vuelidate, or plan on doing that and have some ideas, what we could improve, besides the release frequency, let us know in the issues board on GitHub.

[00:33:36] T: Well, loyal listeners will know that I am very good at scope slots, so I can't wait to do an episode on scoped force. I'd like to shift the conversation to one of your other libraries, though. When I was in your workshop, I was describing to you this issue I had, where I was using this library called single-spa. Basically, the app that I was working on, it was a Vue app for the nav menu. Then every page on the app was another Vue app. We needed to sometimes communicate something via click to the menu to communicate it to another app. Ari is cringing and hiding. Yeah.

We couldn't figure out a way to do it. You suggested your Vue global events package, which I did end up using and it works fine on my repo. Then it ended up not working at all, just because I turned out that the library that we were using for our components doesn't accept programmatic clicks. I had asked why and they were like, “We don't know. It was a really long time ago.” That was the end of that story.

Since then, I've heard Vue global events described as basically, an event bus. I've worked on three Vue apps that all have event bus. To me, they feel different. I was wondering if you could share your thoughts on how they might be similar or different.

[00:35:03] DD: I would say, they are totally different. Although, if we want to be very specific, like every component is an event bus in Vue 2, because they implement the event bus interface. Yeah, that's just like nitpicking.

[00:35:19] T: That’s our job, right? To nitpick?

[00:35:23] DD: Yeah. The main idea behind Vue global events is to help users create shortcuts, global shortcuts. Yeah, maybe it should have been called Vue global shortcuts, instead of events. The way it works, so normally without it, if you wanted to listen to a shortcut, say Ctrl F, you would need to add, a listener to a window, or a document, then look up the key codes, set up the modifiers, and so on, and so on.

This is a bit tiresome, because then you have to remember to remove that exact listener. What I think a lot of people that are using Vue love about Vue is that if you have an input, and you can just do like, @Ctrl.F = listener, and it's going to work. Because Vue underneath, inside the template compiler, it translates the listeners, along with the modifiers, key codes, and so on. Even does the keyboard Windows versus Mac adjustments.

We figured like, “Hey, that's in the template in Vue, for forms, from inputs and so on. This is how we want to use it.” That idea was how we can make it. Like you have the same API for listeners on window, or a document which is global. We figured, that's probably quite easy. If you were to look at GitHub for the implementation, you would see that as a 100 lines of code, maybe a bit more, but it's super tiny, and there is almost nothing that can go wrong.

Just recently, I mean, yeah, a few months ago, with Eduardo, we did a pair programming session, and we rewrote it together to TypeScript, and migrated to version Vue 3, so it's compatible with Vue 3, in just one evening. I think it was two hours or something. It's super tiny. The biggest part was to update tests, actually. Because everything else was mostly straightforward. The idea how it works is when you use the template, and you set up the listeners on a component, and their library is actually a component that doesn't render anything, but it's a component, so you can use it in the template.

Then once you pass the listeners, like yeah, @key-up.control.shift, what the component will accept is listener’s argument, or you probably noticed, if you just $address and also, $listeners. Inside the $listeners object, you will have listeners that have all of the key codes, modifiers already applied to it. It actually does the job for you. We didn't really have to do any key code mapping and so on. The only thing that the library does is takes those listeners, do for each loop, add those listeners to window or document. Then on, before destroy, it just removes that. That's it.

[00:38:56] T: Maybe this isn't necessarily an issue. I'm curious, since Vue 3 is getting rid of $listeners, how does the same package work across both Vue 2 and Vue 3?

[00:39:09] DD: In this case, we have to, because it's using implementation specific properties, this is not compatible with both Vue 3 and Vue 2. You have two different versions, but yeah, the new one is for Vue 3. It still has the listeners. You still have the attributes and those attributes are if I remember correctly, all of the listeners are prefixed with a key up on something. We just need to extract just the listeners part, so we can use that to iterate on and set those, add those to the window.

[00:39:50] T: Makes sense. Speaking of what's new, before we close, I was wondering if you have any suggestions on where developers can learn about, I guess, for lack of better a word, new developments in the Vue world.

[00:40:05] DD: The Vue newsletter has been a bit inactive within the last few months, due to many reasons. The COVID situation was a factor. I'm very happy to say that starting this weekend, we should be able to resume the newsletter, which I hope will go out every two weeks. Yeah, this would be probably a nice way to keep track of everything that is happening.

Then besides, I would say, Twitter is probably the most reliable way to keep track of all of the news. Then it also consumes a lot of time to stay up to date. There are several Twitter lists, I think, that I can't really remember the exact names, that have several Vue-related developers listed that you can follow to get some more updates on Vue libraries and general Vue topics.

[00:41:05] T: Damian, you were supposed to say the Enjoy the Vue Podcast. I didn't even know you had a newsletter. I'm just kidding.

[00:41:12] AC: I was like, “Really, Tessa?”

[00:41:18] DD: Why should I? If someone is already listening, they already know that this is a good source. If they are not listening, there is no point of saying that, “Hey, you should listen to this podcast to get the news,” if they are not listening. Sure, I will mention the Enjoy the Vue in the newsletter, as I already did several times, back in the days when he was actually sent.

[00:41:40] AC: It made me feel special. It legitimately did.

[00:41:46] T: For our listeners who are not yet subscribers to the newsletter, as of the time of this recording, it sounds like when the newsletter will start back up again. It's going to be the first weekend of December.

[00:41:58] DD: Yep. You can join by going to news.vuejs.org.

[00:42:03] T: Great. Well, we'll include links to both the newsletter and the Vuelidate and formulate repos in the show notes. Damian, where can people find you on the Internet?

[00:42:16] DD: Mostly Twitter. It's Damian Dulisz. If you have trouble finding, you can also go to my website, which is dulisz.com. There is the link to my GitHub and Twitter, and also the libraries that I'm working on. I think so. Haven't updated it in a while. Yeah, that's the place where you should have all the places that you can follow me and see what's happening. Although recently, it's mostly my dog, Bento. He’s adorable. I'm totally not having to go to a different room to record that, because otherwise he would just, yeah, interrupt me.

[00:43:06] T: With that, it's time to move on to this week's picks. Ari, would you like to go first?

[00:43:12] AC: Sure. I won’t steal one of Damian's picks that I was totally going to pick, but just know that I was going to pick one of his picks. It's a show on Netflix. That's all I'm going to say. Instead, I will pick another show that you can find on Netflix, Alias Grace. It is based on the Margaret Atwood book. It is a limited series. I found it quite interesting. If you watch Letterkenny, you may recognize a couple actors, just saying, though in very different roles. Very different. Yeah, so that's my pick.

[00:43:48] T: Nice. How about you Damian? What are your picks for this week? I heard one of them might be a TV show, but that could be wrong.

[00:43:55] DD: Yeah. The TV show, and this is probably the last TV show that I was able to watch for a while, given the puppy, was Queen’s Gambit, which was very good. I think we binged it in two or three evenings. Yeah, it's about a chess player. It's just super well done. The characters are very believable. It just touched some of the patterns, I'd say. I haven't played chess professionally. I just did it for fun, once at an airplane, because the passenger next to me tried to play and they didn't know the rules and it was a night flight. I couldn't sleep, because the — for some reasons, the screens are very bright. I ended up teaching him the rules. We won the first game. Then lost the second one. Yeah. Tip here is get those A covers when you're flying and want to sleep.

Yeah, it was very fun. I enjoyed the show. It's very short. I think it's just seven, or eight episodes. Yeah, but they are pretty long, like an hour-long. So, Beth. Beth. Yeah, that's I think Beth, is like a prodigy kid that is super good at chess. It just shows her story from when she was an orphan, learned to play chess and then had to struggle to be the very top player. It's not based on real events, but I think it has been based on, or inspired by real players, or some of their stories. It was done in a way that was totally believable. I had to Google like, “Hey, is this based on the real story?”

The other picks for me were Demon’s Souls, which is the remastered version of the original from PS3. I managed to get the PS5, which I know wasn't that — many people weren't successful work for me, but that's the only game I have and probably the only game I managed to finish before the puppy arrived.

[00:46:17] T: That was pretty impressive, no?

[00:46:21] DD: Yeah, it’s —

[00:46:21] T: I heard it’s hard.

[00:46:22] DD: It's hard. Yeah. If you already beat the Dark Souls, then you already know the drift. It's not as hard. If you play mage, it's like easy bolt. Yeah, spoiler alert. If you pick royalty, which is yeah, it starts as a spell user, it's very easy. Because you can cheese a lot of encounters. Not that I did it, but I did. I did on the first playthrough. Yeah, it's fun. It's quite challenging, quite frustrating. Good training before a puppy. I mean, your patience. If you die to the same enemy 10 times in a row, that's a similar frustration. The second pick —

[00:47:11] T: Third pick.

[00:47:12] DD: Treats, or second gaming pick was Hades. This is something we played. I think there was a boom for that game in the core team, or with several people playing Hades. Just a very well-done game, like a rogue-like with Diablo-like perspective, where you just go through randomly generated levels and try to beat all of the bosses. Usually, the story in those games isn't that interesting. Except in this game, it was very, very well-done. I think it's from the creators from Bastion and Transistor. Yeah, very memorable voices, voice acting, music. It's a small team, but I think it definitely could be the game of the year, at least for me. Amazing game, gameplay, and it's also super hard. I don't know what's with those tough games.

[00:48:11] T: Oh no. I just bought it. Maybe I should return it. Go ahead, Ari.

[00:48:15] AC: At least the third time it's been picked on this show.

[00:48:18] DD: Okay. Give it a try/

[00:48:21] AC: Yeah. I guess, I should probably get it.

[00:48:25] T: I just — go ahead.

[00:48:27] DD: You definitely should. I mean, especially on the Switch. This is something that you just take — you need a break. I mean, if you're very good, you can finish it in 12 minutes. Normally, it takes around, I'd say 20 minutes to finish. Then you can just like, “Oh no. I'm not touching this game for another few hours,” because you get frustrated, or maybe you beat it as it's getting addicting. Yeah, that's one of the two options.

[00:48:57] AC: Yeah. I guess, I'm more worried that I won't put it down and it will take over my life.

[00:49:04] DD: Especially with a Switch, it makes it very hard to put down, because you can just take it everywhere. Yep. Not that it ever happened. Not that it ever happened.

[00:49:17] T: I just have a quick side question. Earlier, you said there was a small boom in the core team. Does boom mean it was popular?

[00:49:25] DD: Yeah, yeah. Okay, so I guess, there is new — I was thinking, maybe there is no word, like boom as in — because I know that there is a word in Polish that is there is a boom. I was thinking that it's coming from English.

[00:49:44] AC: It translated for me.

[00:49:45] DD: Maybe it's not.

[00:49:46] AC: It’s just you, Tessa.

[00:49:49] T: The reason I was curious was because in Japanese, there's my boom, which means what you're into now and then boomu is just what everybody's into. I know it's supposed to be boom, but this is my first time hearing it in English, so I want to know. Yeah.

[00:50:03] DD: Nice. In Poland, we just say like, [Polish 00:50:05], which means there is a yeah, a very big interest and people are being interested severely. It's getting very popular suddenly. Yeah, I think on the core team chat, like many people were mentioning they're playing the game. I think Evan got very good at it. He even, I think tweeted that he beat it in 12 minutes. That's why I said like, if you're good, you beat it in 12 minutes.

[00:50:34] AC: Challenge accepted.

[00:50:36] T: Maybe we should suggest it to Ben. He might like it, but I'm not sure.

[00:50:39] DD: I think he really played it.

[00:50:41] T: Oh, yeah. This is just me post-stealing Ben's pick, because he picked it before it was even released.

[00:50:47] DD: Well, yeah, because I think it was in an early access. Yeah, I haven't heard about it before the final release of this.

[00:50:56] T: Yeah. I too, am a Hades pleb. There's that.

[00:51:00] DD: Okay, cool. Although, I did play with the cheat mode on for a while, because I was so frustrated. I figured like, “Hey, I'm just going to make it a bit easier.” That’s yeah, me. Maybe people won't share that, like they might, “Oh, picks. Not really interested.”

[00:51:24] T: Well, I guess that please my picks. My first pick is — I know how to describe it. It's this Instagram video that Michelle Chenoweth shared. It's a multi-part musical number about Thanksgiving. I don't know what the background is behind this, but it's just amazing to me, because you watch the first video and you're like, “Okay, okay. It's a song about Thanksgiving.” I won't talk anymore about it, but yeah, you really need to listen to the description when it says watch all the videos.

[00:51:54] DD: Okay. Could I have another pick? Because I didn't know we could have videos as a pick. I don't think it's a very word for you. When I was waiting for the toddler puppy, which is the dog I have, we did some search on random TikTok videos with toddlers. There was one with the Baby Shark song, which I didn't know existed. It's just a super tiny puppy and someone is playing with his belly and he's just the cutest thing ever. It has this Baby Shark song, which stuck in my head for so long that I just like singing it to Bento every day when playing with him. Yeah, that's something that —

[00:52:40] AC: I think the only person who’s never heard it and I'm so grateful for that.

[00:52:46] DD: Oh, yeah. It just goes through your head and just doesn't want to go out. Should I send you the link to that?

[00:52:53] AC: No.

[00:52:55] T: We’ll link it in the show notes for the brave.

[00:52:58] DD: Yeah. The picks should be there, so they try to find it in the message log and send it to you. Yes. It's, it's adorable. Apparently, the song is super popular, which yeah, I never heard of it before that. So, it’s like like, “What is this? Why does it just digs in my head and just —”

[00:53:21] T: That's like my friend Kristen tweeted the other day, that she got the baby bottle pop song stuck in her head. I was like, “Oh, no.”

[00:53:30] DD: I don’t want and I don't think I want to know.

[00:53:33] T: Yeah. It's a jingle for a candy. My second pick, I guess, I can talk about this show Startup. It's another K-drama. It's about startups. I picked it randomly, which I don't know why I would pick a show about startups, because every time they're talking about startup stuff, I just feel extremely stressed out. It's a funny and cute show about these people who are trying to create a bunch of different SaaS products using artificial intelligence, which I feel is interesting to see the lens of what K-drama thinks tech startups are like. And what AI is like, and also a little bit stressful, because there isn't really any conversation about bias, or the other real-world problems that plague tech. I mean, as just a K-drama, it's fun and cute. Yeah.

[00:54:20] DD: Which platform is it?

[00:54:22] T: You can watch it on Netflix. They put a lot of time into making these graphic animations to go along with the show. Whoever did that, kudos.

[00:54:35] DD: Nice. Thanks. I don't think I've seen it. Maybe it's restricted based on — or maybe because I haven’t browsed to —

[00:54:42] T: Location?

[00:54:44] DD: Yeah, location. Maybe I haven't just browsed through the list of shows in a while. Yeah.

[00:54:53] T: Yeah. I think it probably came out around the time you got Bento.

[00:54:55] DD: Okay. It's just recently. Okay. Yeah, because he's here since Saturday. Yeah.

[00:55:05] T: Oh, nice. All right.

[00:55:08] DD: Cool.

[00:55:09] T: That's all for this week's episode. Thanks for listening, everyone. Until next time, Enjoy the Vue.

[00:55:15] DD: Thank you. Thank you for having me. Thank you.

[END]