Vue.js is a frontend framework. But the different modules, such as the reactivity engine can be imported on its own. Let's have some fun and explore possible use cases for Vue reactivity in the backend.
Taking Vue.js to the Backend
AI Generated Video Summary
This talk explores using Vue.js in the backend, specifically focusing on Vue 3 Reactivity. It discusses how Vue 3 Reactivity leverages ES6 proxies to update changes and intercept hooks. The talk also covers implementing Vue.js backend with live demos, showcasing the modification of proxies and the use of reactive functions. It demonstrates the creation of a reactive array and the implementation of join, leave, and message functionalities. The talk concludes by mentioning the possibility of using computed properties and inviting further questions.
1. Introduction to Vue.js in the Backend
Hello, and welcome to my talk about taking Vue.js to the backend. I am a self-employed software developer based out of Luxembourg. This talk is not about a very production way of how to build Vue.js backend. It's more about how to provoke the thought for some things we could use Vue.js in the backend for, and this is Vue.Reactivity.
Hello, and welcome to my talk about taking Vue.js to the backend. My name is Mark. I am a self-employed software developer based out of Luxembourg. I work a lot with Vue.js and Nuxt. Also with Node.js in the backend.
And I have a podcast. It's called Decoding the Code and you can always find me on Twitter. I'm quite active there. So if you have any questions raising up from this talk, just hit me up and I will follow up with you of course.
So yeah, Vue.js in the backend. You might think, are you insane? Why would you do that? So a quick disclaimer. This talk is not about a very production way of how to build Vue.js backend. It's more about how to provoke the thought for some things we could use Vue.js in the backend for, and this is Vue.Reactivity. And I got the idea for this talk earlier this year, and I even tweeted about it. I wrote to Evan Yew. Hey Evan, do you see any problems using Vue 3 Reactivity Engine in a Node.js backend? And I was glad that he replied, so he wrote, just be mindful what you want to make Reactive. The API defaults to Deep Reactivity because that makes more sense in the browser environment, but in Node.js, you'd want to avoid deep-proxying Node, Node build-ins. Make sure to use shallow ref and shallow Reactive. So we basically have the thumbs up from Evan Yu to do this and I got another reply from Alexander Lichta. He actually pointed me to that, Oscar Spence had a talk about it in Vue.conf.us. He wrote this totally great talk by Oscar Spence about Vue 3 Reactivity in the back-end context, which was exactly what I wanted to do. So some of this code that I am going to write today is inspired by Oscar Spence's code, a little bit different, but the idea bases a little bit on his talk. So thank you Oscar for the ground work you made for this.
2. Using Vue 3 Reactivity in the Back-end
We want to use Vue 3 Reactivity in the back-end. Reactivity allows us to update changes wherever they are needed. This is achieved by listening to changes and triggering effects. Vue 3 reactivity leverages ES6 proxies to overwrite getters and setters for object properties. Proxies have the superpower of intercepting hooks, allowing us to replace setter and getter methods. Let's dive deeper into this concept and see it in action during the live demo.
All right, so we want to use Vue 3 Reactivity as in the back-end. So before we get to that, we first have to know what is reactivity really. So reactivity is when you change one thing and you update it wherever it's needed. So in order to do that, we need to listen to changes and we need to notify when a change happens. So we can do some something that's called an effect, a side effect, something that should happen when something changes. For example, the number value changes from 3 to 5. So the slider has to be on another position, for example.
Alright, so yeah, this is the observer pattern. So view 3 reactivity, in view 2 we use the object.define property and in view 3 we overwrite the getters and setters for object properties by leveraging the magic of ES6 proxies. We are going to go a little bit deeper into that.
So what is a proxy? So if you create a proxy from an object, by default it behaves the same way as the object. So for example if I write a value to this it writes it to the object, to the target and also when I read from it it returns the value from this target. So it behaves exactly as we think it should work, which is great. But proxies have a superpower, and this superpower is that we can intercept these two hooks. Of course you can intercept more hooks, but these are the two that are interesting for this use case. So you can write whatever code you want to replace the setter and getter methods with. In the demo we are going to see what we do with this. Let's get this party started or better let's get this live demo started.
3. Understanding ESX Proxies and Modifying the Proxy
First, let's get an insight into ESX proxies and then we'll see how to implement Vue.js backend with a live demo. We start by creating an object called person with a name and age. Then we create a proxy from this object using a handler. By default, the proxy updates changes as expected. However, we can modify the proxy by overriding traps or functions in the handler, such as the getter function. This allows us to access and manipulate the original object through the proxy.
All right, let's get started with proxies. To show you how it works, I will just create an object first. This is called person and this person has a name Mark and it has an age of 34. Perfect. And we create our proxy as such. A new proxy from person and it expects a second argument which is called handler and we are going to see in a bit how that works.
For now, I can play around with this on this side of the screen. Let's just see first what is in there. So this is proxy and what we passed here. So nothing spectacular so far. But when we go there now and say proxy.age is 35. It sets it to 35. When we read it again, it actually updated. So this is pretty much what we expect how it should work. And that is how the proxy is shipped by default.
But we can modify the proxy by overriding some so-called traps or functions in this handler. For example, the getter function. It takes two arguments, target and key. And let's just see what it is. Console log target and key. Alright. And let's see. So this is invoking the get method. So here we can see it logs out what we want to log out. The target. Now we can see what is the target. The target is nothing else than the original, the real object and the proxy is just like the front of that. So this is what is like in the back of the proxy if you will.
4. Understanding Vue 3 Reactivity
And the age is the key we want to get. Let's just call this here get so we see what we are working with. We have to re-code the functionality. Let's overwrite the setter. Set key to value. Now when we try to read the name, hey, it updated. So now we intercepted these functions, but what should we do with it? In view reactivity we track and trigger. I have another conference talk where I go deeper into Vue 3 reactivity, but for now, this is enough. Vue 3 has a function called reactivity.
And the age is the key we want to get. So in this case age. And when we say the name, well it says name, perfect. So let's just call this here get so we see what we are working with.
And you might have noticed that it always replies undefined, why is that? Well because we are not replying anything. I told you we can completely overwrite this function but now we broke it. We have to re-code the functionality. So what we are going to do is we are just going to return the target with the value key. Alright, let's see if that worked. Like a charm. Perfect.
Now let's overwrite the setter. Setter takes one more argument, value. So let me just be lazy and copy this. Set key to value. What happens when we set the name to Jimmy, for example. Yeah, set and then name. What do we want to set the name and to which value to? Jimmy. So now when we go to, when we output the name it didn't change, why? Because again, we didn't set it. We just overwrote our original function and broke it. Okay, let's fix that. Let's set the key in the target to the new value and let's try again. Name is Jimmy. And then when we try to read the name, hey, it updated, perfect!
So now we intercepted these functions, but what should we do with it? In view reactivity we do something like, here in the get, we track, do something that's called track, and here in the setter, something that's called trigger. Well, it's actually, we pass the target and the key here. So what this does is the track is, so we notice that there's something that, in effect, something that wants to be observed, so we just take it in and we write it as a dependency, and then when something changes, when we set a new value, we trigger that. So we tell the system, hey, something changed here. But that goes all way too deep, and I have another conference talk or various conference talks about this topic where I go a little bit deeper into the Vue 3 reactivity, but for now, this is enough. Also, in the real version of Vue 3 reactivity, we don't use this, we use something called reflect to solve some caveats, but I'm not going to go into that too much, because we are looking at something different now. So, Vue 3 has a function called reactivity, and it's more or less something like this.
5. Using VueJS in the Backend
Function, it's not called reactivity, it's called reactive. We make a proxy out of the target and return it. To make an object reactive, we use the reactive function. In the demo, we have an express server with three routes: join, leave, and message. No authentication or real user interaction for now. First, we add VueJS to the backend using yarn add Vue.at.next. Then we import the necessary functions and create a reactive array called users.
Function, it's not called reactivity, it's called reactive, sorry. So we pass here target, and what do we do with it? We just make a proxy out of it, just like this. And we return the proxy, and here, it's not the person, it's the target we pass. So now if we want to make an object reactive, all we have to do is reactive this.
Okay, let's try it out. Alright, let's go ahead and get the value, for example, the age. So it invokes our get hook where we lock things out, and in the real version of your reactivity, we track. So we tell the system, we want to know when the age changes, and then when it does change, we trigger it. So we tell the system, hey, this changed, and then do your thing and execute that side effect that needs to be done.
Alright, so this is proxies. Now we're going to move on to some demo where I'm going to use all of this in the back end. Alright, this is my back end, nothing impressive going on here. It's just my express server, boring, and three routes that I work with. One is join, leave, and message. They also replicate in my REST client, called Insomnia. Login, it just passes the username, message, which username and which text. And then we leave, and again the username. So there's no authentication here, there's no real interaction with real users. Those are all stuff we have to imagine that will be added later. But for the moment, let's just focus on the reactivity for this one. Alright, so the first thing we have to do, we have to add, actually, VueJS in our back end. How do we do that? We'll yarn add Vue.at.next, if you do Vue.at.next, it's version 3, alright, it's installed. Let me hide the sidebar, perfect. OK, so let's first import a few things that we need. RequireVue. And what do we need? We need the reactive function we saw earlier, we need effect, we're going to come to that later, what exactly that is, and we might use a computer property. Alright, so far so good. And let's create a reactive array that's called users. isReactive and it's an empty array to start with. Alright, so far so good, nothing happened yet because we didn't write any real code yet, but let's start by join.
6. Adding User to Array and Displaying Join Message
Okay, when we execute the join function, we add the user to the array. The first effect we use is to console.log the length of the array. We pass a function that executes when the length of usersChanged changes. We want to display 'User [username] joined the chat' for the last user in the array. To do this, we access the last index of the array and check if the user exists. If not, we ignore the rest of the function.
Okay, join. When we execute this, we want to add this user to the array. So this is the easiest part. We just go users.push, and what do we push? The body of our request, which is exactly this, so just the username.
Alright, when we do this now, nothing really happens yet because we're not reacting to it. That's our first effect. I told you I would explain what this effect does, but to do that, let me write the effect first and then I'll explain this. Here we console.log usersChanged and let's just go to the length of the array. When we go there now, we say usersChanged 1, 2, 3, 4, 5.
This effect, how it works, is you pass a function here that if something inside this function changes, then execute the function again. It might seem a little bit complicated, but that's the easiest way to put it. If something inside a function changes, execute it. In this case, the length of usersChanged, so it's executed. So it's just an output.
But we don't want to access here only this. We want to do something like this. User this and this joined the chat. And it's going to be something like user.userName. We just have to get the user first. So the user is going to be the last one in the array, because when you push something to an array, it's on the last position. This is convenient for us, because it's an easy thing to do. We just access the index of length minus one. And here again, because here we access the length of the user, this is executed when it changes. So hopefully this works. It did not work. Why? Username of undefined. Of course, it's undefined at the beginning. So we have to make a small check here. If there is no user, just return and ignore the rest. All right, let's see.
7. Implementing User Leave Functionality
Now it works. We set the leave to true when a user wants to leave. Then we find the user with the same username as in the request body and filter out those who have already left. If there is a user, we set their leave status to true.
Now it works. Then we send the request and BAM! It worked. This is perfect. So the user mark joined. Awesome.
Now to leave, that's the next thing we're going to code. How? When the user leaves. And this is a little bit more tricky because we're going to do something a little bit more unconventional. So let's say the username, we have something like this, right? What we do is we set the leave to true. So this user is leaving. And then our effect is going to catch that and is then going to set left to true. So we know when a user wants to leave. And then we know when the action is completed. So that's what we are going to do.
So first, we need to use it that's leaving. And then we're going to do it like this. Where the user is, we find. We find a user where the username is the same as we pass here in our request body. So a request body. Come on. Body username. Alright. And also if they haven't left already. So we filter out the ones that have already been marked as left. Alright. And then again, here we might run into some trouble if there is no user. So if there isn't a user, just do nothing. And if there is, set the user leave to true. Alright. So yeah, this is going to find the user with the username is the same one as we passed here and which hasn't left yet.
8. Implementing User Leave and Sending Messages
To allow users to leave, we create an effect that sets the 'left' property to true for users who want to leave and logs the user's username. Next, we implement sending messages by adding a reactive array called 'messages' and pushing new messages to it. We log the message's username and text. Unfortunately, we don't have time to cover more topics like computer properties. Thank you for your attention and feel free to reach out to me on Twitter for any further questions.
Just, well, he wanted to leave but the operation isn't completed yet. So to do that, let me create an effect. And here, we are going to do the following. I filter the users, for users that are leaving. Leave and, but not that haven't left yet. So, and not left. And for all of these, we do the following. Well, let's go in the next line. We, we set the left to true and we log out the user this and this left. And this is going to be user dot username. All right, let's try it out. Well let's first join, mark join, perfect. Leave, mark left, perfect. Again, not working because there's none in the list. Okay, perfect.
All right, the last part is to send messages. For that, we need another array, a reactive array, messages. And here we need to add the message. Messages.push, request body, awesome. And then we need a similar effect to the ones we had for the users. So I will just sneak that and I will replace user for message and we are going to log out another message. So we put the user in parenthesis and then we write the message. So it's message.username, awesome. And then message.text, oops. Okay, let's try that. Let's log in, works. Let's send a message and that works as well, awesome. And let's leave, awesome.
All right, unfortunately we are done. I would have loved to show you a lot more, for example, computer properties, but that's just not in the time, but this is how we could use Vue.js in the backend. Of course, this is not how you would exactly implement the chat, but it's just to visualize or to show you what is possible with Vue in the backend. With that, thank you very much for your attention and of course for not falling asleep. And if you have any more questions about this, make sure to send me a DM on Twitter, I will respond you and yes, have a great rest of the conference.