Transcript for:
Vue.js 3 Expense Tracker Overview

[Music] what's going on guys so it's been a while since I did any kind of vue.js project so I wanted to jump in and build some kind of application with vue.js 3 well 3.3 to be exact and the composition API and it's important to mention that because there's really two ways to structure your view components there the options API which is the traditional way that groups data and methods by option hence the name but in version three the composition API was introduced which is supposed to be a more organized way to structure the logic of your view components and it also promotes reusability readability as well as reactivity which allows components to automatically update the the UI when the data changes and eliminates the need for manual Dom manipulation and of course that's what every front-end framework aims for is reactivity I mean the most popular one is called called react but the composition API gives us ways to achieve that very easily and as far as the project goes it may look familiar to you because it was actually part of my 20 vanilla JavaScript projects course and I also did a react version of it on my channel a while ago but basically we keep track of our various income and expenses so at the top we have the total balance then we have the balance of income and the balance of expenses and under that is the history or the transaction list and you'll see if it's an expense it has the red border and the minus sign if it's a deposit uh not a deposit but income then it has the the green border and we also have the delete when we hover over uh each of the transactions and then at the bottom we have a form to add a new transaction with a text in an amount field so if we go ahead and add let's say a course I created a course and made um $500 so we just add just the amount and that gets added we get a um a toast up here because we're going to be using the view toastify want to add an expense what we would do let's say we bought um I don't know a video game so if we bought a video game then we just put a a minus amount in front or a minus symbol in front of the amount so we'll say 70 and we can we can do decimals as well we'll say 79.99 and then you'll see that that gets added as an expense and has the red border and our balances have have changed it's reactive and of course if I wanted to delete something I could just click this x we get another toast saying transaction deleted and if I reload you'll notice that it all sticks because at the end we're going to implement local storage we'll start off with everything just being in the Dom but then we'll we'll add local storage functionality as far as the code I have the link in the description to the GitHub repo with everything and you'll probably have to just copy the CSS and maybe some of the HTML from here I also have the GitHub link to the 20 projects course um to the projects and you can see there's an expense tracker if I click on that that's the vanilla JavaScript version so you may just want to take a look at it see how that works but that's it so let's go ahead and get started all right guys so I have VSS code open and of course you can use any text editor that you want and I have an empty folder called view expense tracker and then down here I have my my terminal and I also have the final repository here as well as the vanilla version because we're going to just need to grab some CSS and maybe some HTML from there as well all right so let's start off by generating a New View app using the vew CLI so we can use npx just make sure you have no JS installed on your system and we can say create Das view at latest and then I want want to generate everything in the current folder so I'll just put a period and then it's going to ask us some questions so the package name I'll call it view Das expense D tracker and then all these I'm basically just going to say no so typescript no jsx support the router we don't need it because even though we have multiple components we only have one view or one screen so we'll say no to that pinf for State Management we'll say no no for testing and no for eslin all right and you can see it just generated a bunch of files and folders so we do have to run npm install or npmi and then we can run the dev server with npm runev all right now I know let's just open this up it's on uh 5174 and we just see the welcome page now I know a lot of you have experience with vue.js but just because there are some people that may not I'm just going to explain some of these files real quick so in the package.json you can see for our main dependencies we just have View and then under Dev dependencies we have vit so vit is is is a local Dev server so that's basically the tooling that we're using to to have this server run and have hot reload and all that and we can install plugins to V and the view plugin obviously is is all set up and if we look at the V config file you'll see that view plugin and you're not really going to have to touch this file I mean if you want to change something like maybe the port number you can do that from here and you can check out this URL for for any options all right now the index HTML file is the single page of this single page application so there's not much here there's just this script tag using the type of module so this isn't like webpack where it constantly gets compiled or or or transpiled every time we save it's actually loading that main JS as a module and that main JS is in the source folder and I'll get to that in a minute and then there's this div with the ID of app that's basically where our UI is rendered okay and then that's pretty much it as far as this file if you want to change the title you can I'm just going to call it expense tracker whoops expense tracker and if I save you'll see it just reload so we have hot reload uh we don't have to refresh the page or anything like that and then if we look in Source the main.js that's basically the entry point for vuejs and there's not much here either you can see it's very light so we have this create app function and that takes in the main component or the parent component whatever you want to call it and that's in this app. viw file okay and then it's mounting that to that div that I just showed you with the ID of app and then it's just bringing in a main. CSS and we're actually going to wipe out all the CSS in a second um then there's the app. view file as you can see it's importing a couple components from this components folder so hello world and so on again we're going to delete all of this and in the assets that's where the CSS files are all right and there's nothing in the public except a favicon which I actually have another one I'm going to use of course this is completely optional but you can get it from the final so I'm just going to replace that and it's just a little um little e-commerce no not e-commerce what is it it's like a yeah I guess like a little e-commerce thing all right so let's um let's start off by deleting all of these files that we don't need so everything in the assets folder these three files we're going to delete those everything in the components folder including the icons folder delete those and in the app view let's just get rid of everything and just put in a template and just say my app all right now for the styling like I said we're going to get that from the the either the final project here or the vanilla project it's both the same exact stylesheet so this style.css I'm just going to copy the code from here and what I'm going to do is in assets I'm going to create a file called style.css and I'm going to paste that in here and if I save that we go back to our application well actually it's not going to show yet because we have to bring it into the main.js so I changed it to style so we want to import that and now you should see something like this okay everything's going to be centered because if we look at the stylesheet the body we actually have uh displayed as a flex box and we have Flex Direction and align items I'm sorry uh align items and justify content to the center and if you want to look through the CSS you can it's nothing nothing special all right so now that we have that we can close up main.js and what I'd like to do is just create all the component files that we're going to work with just so we can kind of map things out and we know what we're doing so if we look at the screenshot here there's basically five different components I want to break this up into and when you use a framework like view or react or angular or spelt that's the idea is to break your UI into different components and then you can pass different data different props into each one so we're going to have the header component which is just basically an H2 but if you want to add something else to it you can we're going to have the to the balance component which will be the total balance we'll have the income expenses component which will be this both income and expense the transaction list which will be this and then the add transaction component which will be this and we're going to have them all work together and everything's going to be reactive so for instance when we add something it's good this component will be reactive and the income or expense will change as well as the total as well as the transaction list all right so that's the beauty of a framework like this is that everything is is reactive and data is sent to any component that needs it so let's create those files in components I'm going to create a header. view so all compon components have a view extension and you want to use an uppercase um convention for the titles and then let's create the next one which is balance. view okay then we have income expenses. view then we have the transaction list so transaction list. viw and finally we have the add transaction which is the form okay so we have our files created and I'm just going to CL close these up for now and I'm going to leave the header open because what I want to do is just get the UI just get the the the layout so we can get the HTML from the um from the the vanilla project here if you want to type it out you can you can see it's it's really not much but for the header it's going to be very simple it's just going to be H2 now the way that view templates work for those of you that are brand new to to this framework we have everything in a component we have the output or the HTML or the template whatever you want to call it we have the JavaScript which is the logic or the functionality and you can also have the style which for us we're we're just putting everything in one Global style sheet but you don't have to do it that way now the output is going to go in a template tag like this and I just just want to have that H2 now if I wanted to put some logic in here some JavaScript then I would add a script tag and I'd put my JavaScript in there and in addition if I wanted to have styling I could put a style tag in there and when it has the scop that just means that any CSS I put in here is only going to pertain to this component it's not going to you know leak out into into affecting other areas of the of the app but for the the header I just want a simple template just the output bring the header into the app. view and have it show in the browser we have to then open up some script tags because we're importing something that's within JavaScript so we're going to say import header from and then SL components slhe header. viw okay now the way that the way that I'm doing it right now if we want to embed it like let's go up here and let's get rid of my app and let's put in the header tag to embed that component if I do it you'll see it's not showing the the the header it's not showing expense tracker because with with the way we're doing it we actually have to have an export default and then we have to register the component with components which would be an object with any components you want to show in this file so we have to register it here then if I save it shows however there is a way around this using the newer script setup syntax which I'm going to get into in a little bit but I want to show you this way first because this is kind of the traditional way of doing it whether you're using uh composition or the options API so next let's do the balance so I'll go back to the just the regular HTML here and notice everything else is in a div with the class of container so in the app let's go under the the header and create a container class and then all of our other components will go in there so the balance is going to be this H4 and this H1 that's it so we'll grab that and remember everything has to go in a template for our output and we just have a zero balance for now okay I'll close that up we can close the header up and now let's import we'll just copy that down and we'll bring in balance balance and then we'll register it down here balance and then up top let's go in the container and that's where we want to show the balance okay so if we come back to our application let me make this the first tab you can see the0 balance all right the next thing we're going to want if we look at the screenshot is this income expense so if we go to the HTML that's going to be this div right here so if we go to income expense we'll open up our template paste that in save it and we'll bring that in as well so that's going to be [Music] income is it yeah expenses income expenses. viw income expenses we'll register it down here and we'll add it up at the top so income oops expenses okay so now that should show all right cool so next we have the transaction list so that's going to be this H3 of history and this ul and it just hasn't a commented out hardcoded list item which I'll we'll we'll uncomment that but let's put it in transaction list. viw so we'll paste that in and we'll uncomment this list item just so we have something there um and I'm going to put another one as well so let's copy that so the the way that we get the green or red border is with the class so a class of minus gives a red border so let's make this one a class of plus and take away the minus sign and we'll say um uh I don't know paycheck so we'll say that we got a paycheck of let's say 800 all right so we'll save that and then let's bring it into our app. viw so that one that component is called what transaction list and we want to bring that in down here transaction list okay save that let's check it out and there we go so you can see paycheck has the green border cash has the red because it has this is a class of minus that's a class of plus so that's just CSS stuff same thing with the hover right here with the X so let me just show you real quick where that comes in um there's the plus and minus class so we just have the delete button which is styled but it's set to let's see the opacity is set to Zero by default but then when we hover over it then or I should say when we hover over the list item we have the opacity set to one there's also a transition on it which gives it that fade in Fade Out so just in case you're wondering because some I know CSS can be really confusing to uh to a lot of people including myself so the last thing we want to do is the add transaction form the last thing as far as the you know just the the layout so we'll grabb this H3 down to the ending form tag okay don't get the DI that's the container so we just want that and let's go to add transaction add our template save it bring it in I just think it's better to just take care of this now rather than you know do it all different times so add transaction that's going to be from components slad transaction. viw okay and then we're going to register that and down up here add transaction all right so we should have the the whole layout here good obviously nothing works because we have no functionality but at least we have the output now I think where I want to stop start is with the transaction list so I just want to start off by having an array and render that as a list item with the transaction okay so we're going to go to our transaction list component and start here now at the moment we just have some hardcoded items here so we we can comment those out and now we don't have any showing so I'm going to start off by having the array of transactions in this particular component but remember the transactions that's part of our our what's called our Global or app level State because we need to access those transactions through by multiple components we need to get the balance we need the income expense we need to be able to to add to them so that's Global state so you're ultimately you're not going to want to keep those in this one transaction list component we're going to want to keep it in our main app. viw because then we can send anything we want down into those components okay and then you could also use a third a state manager like like Pia or Redux or something like that but that's more for larger applications for smaller applications usually you'll you'll keep your Global state in your main app. viw file now we're going to be using the composition API but just to give you an idea for those of you that are kind of brand new to vue.js I'll do it first with the options API so show you how we would how we would add data to this component so of course we need our script tags and what we would do is export uh export as default and then in these curly braces we can Define our data so it's actually a function that returns an object okay and again this is the options API and and I I think I mentioned this already but it's not that the options API is like deprecated and you shouldn't use it anymore it's it's you can pick one or the other so I just want you guys to know that you can still do it this way so here we could say transactions which would be an array and for now I'm just going to grab some dummy data and just put that in there so if you want you can copy that okay now having this in our data we should be able to access it in our template so and it's an array so we're going to want to Loop through it and we're going to want to Output one of these list items for each one so let's do that let's say list item and the way we can do this is using what's called a directive so in in your template there's different directives you can use for conditionals and loops and um form input binding things like that so to Loop through something we can use the V4 directive so if we say V4 equals and this could be on any element but we're putting it on An Li so in the four right here we're going to say transactions or transaction in transactions okay so this this could be anything this transactions pertains to to this right here so this just represents a single transaction now this has to have a a key as you can see right here it says elements in iteration expect to have a VB key and a key is just uh it's it's going to be a unique value just like when you when you map over something in react and you create a list you need to have a key as well so we can say v-bind key equals and then we'll set that to the transaction ID so transaction. okay so this right here should match whatever this this is I could make this T if I want but then I need to make this T right um and then for we can make this shorter we don't even need to add the V bind we can just do colon key as a as a shorter way of doing this okay now what we want to do inside the LI is is have one of these list items so I'm going to copy that and I'm going to paste that in uh actually I'm sorry I don't want the LI because we already have that I just want what's inside of it which is this yeah so we'll do that and then I'm going to delete the comments so let's save that now we're seeing cash four times because we have four items in the transactions array and we're hardcoding the word cash so what we can do is get rid of that and in here we can use double curly braces and we can say transaction Dot and then whatever field we want want in this case text and then for the amount let's do we'll keep the money sign there and then we'll have our double curly braces and we'll say transaction do amount so now if I save that we see the text or the title here and then we see the amount uh I just want to get rid of that minus sign and that's kind of the next thing that I want to do is handle the what are these are these income or EXP expense right and we do that we can tell the difference with the class of minus or Plus on the list item so we can actually use the class directive so I'm going to go onto the list item here and go after the key and use colon class you could also do V bind colon class and this can actually have a a conditional in it so that you can have a class based on some condition so let's say if the transaction. amount and let's just close that up so if the transaction amount let's say if that is less than zero right because if we're doing a negative then let's make that class minus okay we'll put single quotes around that else and we're just using a Turner here else then it's going to be plus so now when I save that you can see the expenses have the red border and the incomes have the green border so what we've done here is we've added data to our component to our component State a transaction array and then we looped over it using the V4 directive and we added the the key and we used the class directive as well to give a conditional class and then we're outputting the transaction data so again this is the options API and this is kind of how it is you any data you have you put in this data function and you return an object so if I wanted to put something else here I could put you know whatever name something and so on and then if we have methods that we want to use we would go after the data and we would do methods and then we could Define methods all right but we're not going to be using the options API so now I'm going to switch this to the composition API and there's actually two ways to do it there is using the explicit setup function because that's the idea is you have this main setup function and then you can put whatever data whatever uh functions you want inside of that parent function that setup but there's a new syntax as of version 3.2 where you can just put setup right in the script and you don't have to explicitly Define that function so I'm going to show you both ways so I'm going to just grab the transactions here and then I'm going to get rid of everything in the export default all right and what we would do is again have a setup function like this and then we could create uh con transactions so just like a regular variable oh I already had transactions all right I'm just going to set that equal like that and then if we do it this way where we have the explicit setup function let's go under see how it doesn't uh it's not working anymore it's because we have to return down here we just have to return from the setup function the transactions and I'm going to show you a shorter way in a second but if I save notice how it's working again so this is a is a little more clear and concise at least in my opinion because we're just you know simply creating a a variable of transactions and returning it and then we can use it up here now like I said there's an even uh shorter way way of doing this and by the way if you wanted to create a function you could just say you know my function create it and then just return it here my function just like that and then you could use it wherever um now I'm going to show you the the newer way to do it which is by just putting setup right in the script tag and then not only do we not have to return and not only do we not have to use the setup function explicitly we don't even have to use export default so we can simply do this save it and it works so how cool is that now like I said we don't want to have the transactions in this transaction list function we want this to be in our Global state so we're actually going to move this to the app. view now before I do that I'm also going to set this to use setup in our script and watch this we don't even have to do this anymore we don't have have to export default this components object we can completely get rid of that save it and it still works so all I'm doing is importing and using them in the template so I'm going to move the transactions I'm just going to grab that and then we can get rid of these script tags okay that's going to the the transactions will go away for a minute then we're going to put them in here like that now before I do anything else when you want uh a value or for instance this array we want this to be reactive meaning if we change something if we add uh add a transaction delete whatever we want this to update so we want it to be reactive so there's a function that we want to bring in called ref and anything you want to be reactive you want to wrap in that function so right here what I'm going to do is say import and in curly braces we're going to import ref from View and then I'm simply going to wrap the array in ref like that so that will make this reactive and it's not going to show right now because we still have to pass it down to our transaction list in order for it to show so let's do that next since we have this here we can simply go to our transaction list function and we can say colon transactions and just set that equal to our transactions okay so we're taking this data this array and passing it in as a prop to the transaction list component now in order to use that in the transaction list we do have to um we have to use something called Define props with the composition API so let's add in our script tag again or script setup so pretty much everything that we do now is going to have a script set up so we can do things kind of the easy way and I'm going to import Define props from View and then we can do const props we don't even have to do export default or anything like that we can just say Define props and we're going to set that to uh we're going to or we're going to pass in an object of transactions because that's the prop we're passing in and then we can just add a type to it so the type is an array and we can also say that it has to be required so we'll say required true all right now if I save that you can see that the transactions are back so now we're not storing the transactions in this one component it's in our main app component so we can use these wherever we can pass them to any components we want and they're going to be reactive so no matter you know if we're deleting adding whatever we're doing it's going to update in the transaction list component all right so hope that makes sense when you want to pass props in you do it like this and you just use Define props in the in the component that you're passing them to that's going to have the total so it's going to add all these together and if it's negative then obviously it's going to subtract it right if you take 29997 and you add negative 1999 it's going to subtract 1999 so we're going to end up with the the total all right now we're going to use something called the computed property which is a way to create reactive and cached values and it can depend on one or more reactive properties in this case it's going to depend on transactions so we can use computed we do have to import it so right here let's say import computed from View and then we're going to put it down here okay so I'm going to create a variable called total and that's what's what I like about the this API is that we don't have to put it in methods or in that then the object the main object we just create a variable or a function and and we can just use it so we're going to set this to computed and what computed takes in is a function so we're going to pass in an arrow function and what I'm going to do is return from this transactions now trans I have to use the dot value if I'm going to use uh one of these variables here I have to use do value in fact let me just comment that out for a second you guys don't have to do this but I just want to show you if I do a console log of transactions uh that's spelled wrong transactions all right so I'm going to reload and then open up the console here okay so what I get get is this this this object and you'll see there's a value property right here and that is the actual if I if we look in here um right here so this is the actual data so that's what you get with just transactions however if I do dot value like that and reload that gives me the actual array so you can see right here array and then it has the the indexes and the values so we want to use transactions value when we when we're when we're in this you know in this function so let's get rid of that let's uncomment that and let's say return transactions. value and what I want to do is add them all together so this is a a good case for reduce so let's say do reduce and in reduce we're going to pass in a function and we're going to pass in the accumulator we'll say ACC and and then the individual transaction and we just want to uh return the accumulator plus the transaction. amount okay and then after the function the call back function we're going to pass in zero because that's where we want the accumulator to start so it's going to start at zero it's going to Loop through and it's going to add all of the transaction amounts and that's going to be put in total now total is what I want to pass into the balance so up here where we have uh where we have balance all we have to do is bind total so we're passing in a prop of total and we're going to pass in that value that we get from from here all right now we need to go into our balance component and just like we did with the with the transaction list if we want to be able to take in a prop we have to use Define prop and we're going to say script setup and let's do uh import and we want to bring in Define props from View and then const props Define props and let's pass in to we're passing in total and total is going to be a number so let's say type number and we'll set that to required true all right so now up here we're going to replace the um the Zer dollar here we'll keep the dollar sign but we'll put in our double curly braces and then output the total and there we go 41998 okay so anytime any of the transactions change this is going to change because it's reactive so if I go to the the the um down here to the data right actually I mean this this isn't a good example because I'm just changing it here but if I were to change it within the app that would react to it as well but obviously if I change this to you know 300 and save then that total is going to change as well all right so now we have the transaction list we have the the balance let's move on to the income expenses so that's going to show the total of the income and the total of the expenses and we're going to do something similar to what we did here in fact I'm going to just put a comment here we'll say get total and we're going to want to get um let's say get income and then we're going to want to get the expenses and in order to do that I'm going to use a couple high order array methods we we'll use reduce but we also need to filter out if it's an income or or if it's um if it's an expense so I'm actually going to copy this because it's pretty similar so we'll change this variable here this property to um let's change it to income and we're going to use computed we're going to use the transactions value but before we reduce it so I'll put that on the next line before we reduce it I'm going to use filter so we want to filter out let's pass in our function and we want to say if the transaction um do amount if that is greater than zero because it's the income right it's if it's if it's positive so if it's greater than zero then we're going to reduce we're going to uh add it all together and then I'm just going to add on to the end of this dot to fix because I want to have two decimal places so we'll say two fixed and two all right and and then to get the expenses is going to be very similar almost the same thing except let's change this to expenses and we just want to change this right here in the filter we want to say if the transaction amount is less than zero and then we'll add those together and then we'll um you know two decimal places so now we have the the two pieces of data that we're going to want to pass in as props to this component right here income expenses so let's say income set that equal to income and then expenses set that equal to expenses okay then we have to accept those props in that component so let's go to income expenses and let's see we're going to just come down here script setup and if you're coming from the options API I'm sure you can see just you know how much easier this is so let's import um Define props from View and then let's create our props okay so we have income the type will be a number the uh required set that to true all right then we just have our expenses so we'll copy that expenses and then we should be able to use those up here uh let's see so I'm going to go right here that will be income this will be exp can't type expenses all right so let's see that still says zero what did I do wrong let's open up the console um extru non props attributes total could not be calculated component renders fragment root nodes unhandled eror transaction transaction is not defined let's see um the hell did I do wrong oh in the filter I should probably spell it right we want to put make sure we put transaction in there so it didn't know what the hell this was all right let's save that and there we go so now the expense and the income we got $449.99 which is this plus this 29.99 which is this plus this all right cool so the next thing is the form so this is probably going to be the the most complicated part because we're we're adding a uh either income or expense but we need to add it outside of this component right we need to send it up into the app. view because that's where the state is right it's not in the form component and then we have to pass it well it's already being passed down it's it's already going to react here um but yeah so let's let's go to the form so add transaction and let's see where should we start so the form is going to be submitted so we need to have a submit event so what we can do is go in the form tag and say at submit and we're going to set that equal actually you know what I'm going to do is use do prevent because if you do it like this then you don't have to pass in you know e or event and do e. prevent default it'll it'll take care of that so we'll say submit event or prevent sorry and then we'll call it onsubmit right and that's going to be a function that we call in this um in this component so let's come down here let's say script and uh and we're going to add setup here and let's create that function so we'll say const on submit and set that okay and then we'll just do a console log submit for now just to make sure that that works so open our console type check failed for prop um oh so what's going on here is real quick in the income expenses it's defined as a number but it's being passed in as a string so right here where it's being with being passed in these are strings so what we can do is we can just add a plus sign in front of them and that will make them numbers and if I save that those those errors go away okay now back to the form here let's submit and see what happens okay we get a console log submit now we need to bind these inputs to a couple variables down here and the way we do that the way we bind form data is with the V model attribute so I'm going to go into this first input and it's called text right has an ID of text so I'm going to say v- model and set that to text and then for the amount let's go to down to the input I'm actually going to make this a text not a number um just so that we can have decimals and then I'm going to put v- model and set that to amount okay now what we can do is come down here and we're going to add refs to the the text and the the amount so let's do uh let's import ref I don't know why I just put an uppercase import ref from View and let's go right above the onsubmit and let's create variables for text so we'll set that to ref and that's just going to be an empty string same thing with uh amount okay and then in the console log just to make sure that we're getting those values let's do text and it has remember it has to be value if you're using it down here so amount. Val so now if I put something in here whatever hello 12 so you see I get hello 12 all right now before we we um you know pass this data up to the app. viw I want to have some validation because I don't want to be able to submit just empty inputs like this because I can do that right now as you can can see so I want to have some some validation but I want to use I want to have a nice display I don't want to just do a stupid alert a browser alert so we're going to use a package called view toastify so let's install that real quick I'm going to go down to my terminal I'll just open up a new one here uh I'm so I'm going to do npm install and then it's going to be view Dash toastify and if youve ever use react toasttify it's basically the same thing so let's install that what happened could not resolve dependency um oh view toastify let's do at next I think that yeah that's what I did all right so now that should be installed if you look in your package.json you should see see view toastify use this this um view toastify so up at the top here um I'm actually going to yeah let's move the CSS down actually I'm just going to put it right there I want the create app to be at the top and then right under that I'm going to import toast and I'm going to import that from view- toos ofic now we need some styling with that so there's a CSS file that we also want to import and again this is just direct from the documentation so it's going to be view Dash um toas ofic slist SL index.css so that'll be be the styling and this blue line that's just my spell checker um obviously you know toastify isn't a real word so just ignore that and then let's see what else do we want to do we have to kind of dismantle this right here because we have to call app.use and pass in that toast that we brought in so what I'll do is create a variable called app set that to create app like that and then we can say app. Mount here so that's that's doing the same thing but I want to do something in the middle here um I want to do something in the middle I want to do app.use and then pass in toast I think that's all we have to do so let's save let's make sure we don't have any weird errors all right so now we should be able to use our toes so let's go back into the add transaction cuz that's where we're going to do the valid validation so we'll do the validation here and then once that's done whatever the values are we'll pass that up to the app. viw into the main state so in the onsubmit let's get rid of the well we'll keep the console log for now and let's do an if statement so I'm going to say if not text. value right or if not um amount. value then I'm going to want to display uh an error now to use the toast is uh I do have to bring in up here let's go right here and we're going to say import and we're going to bring in use toast and that's going to be from view toastify okay and then I just have to initialize it so I'm going to go right here and say const toast set that equal to use toast like that and then I can come down here and I can say toast Dot and I can use success or error so this is obviously an error so I'm going to say toast. error and let's see we'll just say both Fields uh yeah we'll say both Fields must be filled and then we'll return okay and then if there is a text in amount value then for now we'll just console log but after that I do want to just clear the fields so we can say text. value equals nothing and amount. value equals nothing so let's try that out so we won't put anything in I okay both Fields must be filled okay if I put one in still doesn't work if I put just the amount in same thing if I put both in that works okay good now since we have the validation we want to be able to emit an event that we can then basically catch in the app. view so that we can update the transaction list or update the state which will then update the component in turn able to emit an event we're going to let's go right here and say const Emit and we want to set that to Define emit I'm sorry Define emits and then we're going to pass in here the an array with the events the custom events we want to submit so you can call this whatever you want I'm going to call it transaction submitted okay so that's going to be a custom event that we can emit so let's come back down here where we have the console log and get rid of that and I'm just going to create an object that has both the text and the amount in it so I'll call this transaction uh transaction data and set that to an object that has text set that to the text. value and then we want the amount and the amount is going to be a string by default and I actually want to parse it as a float so I'm going to say parse float and then pass in amount. value all right so we have the transaction data now let's call emit because we want to emit that custom event so it's going to take in two things the name of the custom event which is transaction submitted and then the data which is transaction data so if I if I submit this now it's we're not going to see anything here but it is going to be emitting the event so we can go up to our app. view now and we can basically listen for that event so we can do that by going to the add transaction because that's where it's being emitted from and let's say at so just like you would do like at submit if you're listening for a submit but we're listening for a custom event called transaction um transaction submitted okay so when that happens then we want to call a function I'm going to call that handle transaction submitted a plus sign to Total as well just to make sure that that's a number okay so all three of these should have plus signs so now we need to create the handled transaction submitted function so let's come down here and let's go right down at the bottom and let's say add transaction so say const handle transaction submitted so that gets passed in the transaction data right so right here which is going to be this text and an amount so let's pass in here transaction data and just to see just to make sure that that works let's console log what do we want to console log transaction data whoops so let's check it out say hello 12 and let's open our console um that's nothing that'll go away so let's add and we we see the object text hello amount 12 okay so we know we're getting the data so now what we want to do is add it to this right add it to this transactions now notice that these these have an ID right but we don't have an ID when we submit the form so we're just going to have to create a a helper function that will generate a unique ID for us so let's come down here let's get rid of this console log and let's say transactions so the transactions array we want the the value of the array and then we're going to push onto that and we want to push and object that has an ID which we're going to set to a function called generate unique ID make sure you put parentheses here and then the text is going to come from the transaction data. text and then the amount will come from the transaction data. amount so that will add to the to the transactions array now let's just create that generate ID real quick so we'll say generate unique ID and you can do this however you want I'm just going to do something really simple so we'll set that oops uh we'll set that to return let's say math. floor and then we'll use math. random and we'll multiply that by let's say a million all right and and then I just want to come up here and I want to make sure that that ID is there so I'm just going to do a console log of um of let's say um I guess I just want to see the ID so we'll say generate unique ID just to make sure that that function is working and it should get added to the array it should get added here so let's just say test 10 add okay so you can see it gets added and then we see the ID down here good now I do want to just show a toast that says it's been added successfully so we can do that but we we we need to just bring in the um the toast package or use toast so we'll do that right here let's say import use to wait is it default or no let's see what do we do here um yeah we need this okay and then we just need to initialize it so I'll go right here and say const toast equals use toast and then let's go back down to where we add the transaction and just say toast. suuccess and we'll say transaction added so now if I add something here we go and that was added as income if I wanted to add an expense like let's say TV minus 200 if I add that you can see that now that gets added as an expense and it takes away from the balance and adds to the expense good of course it doesn't stick if I reload because we haven't dealt with local storage yet but what I want to do before that is I want to be able to delete these as well so let's close all this stuff up we just need the the app. viw and transaction list. viw because that's where we have the delete button which right now obviously does nothing so let's add an event to this um we're going to say at click okay so when we click this button we're going to call delete transaction and we're going to want the um we're going to want the ID so we'll pass in here transaction. ID and then we're going to come down here and create that function delete transaction it's going to take in an ID okay and then we just want to emit up to the app. viw obviously because that's where our state is right that's where our trans actions are so to emit a custom event just like we did in the ad let's say const emit equals Define emits which takes in an array and we can add our custom event here which I'm going to call transaction deleted and then all we have to do down here is emit that event transaction deleted and we can pass along the ID okay so now let's go to app app. View and we're going to catch that or listen I should say listen for that event up here in the transaction list component so here we're going to say at and then what what do we call it transaction deleted when that's fired off we're going to call handle transaction deleted so we'll come down here and let's say delete transaction so const handle transaction deleted and that's going to take in an ID and for now let's console log the ID just to make sure that works so if we do that see we get one four good show it's so we're getting the ID and just to test out if we add something here and then we delete it we get the ID which is just generated from our function okay so in this function what we're going to want to do is just filter out the transaction from the Dom from the state right and then we'll deal with local storage after so to do that we can say transactions. value which is the array in our state we're going to set that to transactions do value. filter because we want to filter out let's pass a function in here and say for each transaction we want to just filter out where let's say transaction. ID is not equal to the ID that's passed in and then we'll do a success so toast. success and we'll say transaction deleted okay so now let's click this we get transaction deleted and you can see everything reacts to it right so flower if I get rid of that the expense goes down to 10 uh I don't want that negative sign there twice let's see um no that's not the right component income expense yeah we want to get rid of that I thought I already did that but all right so we can add we can delete the only thing really left to do here is local storage because we want to be able to we want it to stick right otherwise it's a pretty useless app so let's go into our app. viw and let's get rid of the dummy data we'll just have this be just a an empty array so now that stuff's gone and the first thing I'll I want to do is check local storage and if there are items there if there are transactions there then we want to show them so we can actually use a life cycle method called unmounted which which fires off automatically when the component mounts so let's say on mounted we're going to bring it in from View and then we just need to Define down here on mounted which takes in uh a function it works similar to use effect in in react and then what we're going to do is cons let's say saved transactions and we want to check local storage so I'm going to run it through json.parse because only strings are in local storage this will turn it back into a regular array we'll check local storage with local storage. getet item and it's going to be called transactions that's the key and then we just want to check to see if there are any saved transactions so if saved transactions then let's set the transactions. value equal to the save transactions so it it's so straightforward and that's that's something that I think is is unique from you know I shouldn't say unique but different from react um with react is and I'm not talking about nextjs or anything like that you know server side server rendering um Frameworks but with client side react dealing with side effects dealing with state is is kind of messy in my opinion um and it's getting better but it it's just it's not as straightforward as this you know you you're not just setting the the actual value in the state to something you have to do it in in Silly Ways in my opinion and I'm not trying to on react it's it I would say it's my favorite front end framework but there are some things that just I feel could be better and I think that Vue does a good job J of that anyways so I didn't mean to go on to uh you know off on a rant so now if I if we look at here I don't have anything because there's nothing in local storage but if there were then it should show here now we need to make sure that when we add or delete that it it changes local storage it either adds or removes so we can create a single function to do that so down here let's say um save to local storage right and whether we're adding or deleting we're saving to local storage even if we delete we need to save the you know the rest of the items to local storage with that one deleted so let's uh and this is going to be pretty simple so let's say const save trans or save not saved save transactions to local storage okay and then all we're going to do is then set local storage set item and we want to set transactions and then we just want to wrap the transactions in json. stringify because local storage saves strings and then we can pass in here our transactions. value okay and then all we have to do is call this function when we add or delete so in the handled transaction submitted right after we change that state we can call that function okay we'll just do it right before the success make sure you add the parentheses and then same thing with the delete handle transaction delete we'll do it right here all right so now if I add something here let's say paycheck 900 and then I reload it stays because it's in local storage if I go to my application tab you can see it right here so there's the ID text amount and so on okay if I let's say I bought a TV say minus 200 reload that gets added now if I delete the TV it goes back and if I reload that's still gone okay so it's being it's being saved whether we add or delete all right so that's it guys we have an expense tracker and we're using the uh the composition API along with the the newer script setup syntax which I really really like I think everything is is laid out nicely and we we simply have variables and functions we don't have to put them in data functions or or methods method objects stuff like that I mean it it's fine if you if you want to use the options API I just think that this is is cleaner and uh you know just just less boiler plate so I like it and uh and hopefully this was clear feel free to to add on to this if you want to be able to update the the history or the the transactions that would be a nice option or a nice feature but uh but that's it thanks guys and I will see you next time