Svelte Components: The Building Blocks
Alright then gang. So before we write any code whatsoever, let's have a little look how everything works in Svelte underneath the hood. So as I said in the last video, we create all of our source code inside this source folder. This is where you're going to be writing 99% of your code and this is where we create all of our different Svelte components. And we have one already created for us, App.svelte.
Now, components are like building blocks of a website which can be put together and then output to the DOM or the browser to create a whole website. For example, we might have a component for a header, for a contact form, for a modal, for a footer, for a pop-up, etc. And then at the end, each of these components can come together and be injected into the DOM to make a whole website.
So like we said, Svelte has already created a root component for us called App.svelte. And by the way, whenever we create a component, it must have this extension .svelte. That way it knows that this is a component and it can compile it as such. So inside each component, we have three different things we can have. We can have a script at the top for any kind of component logic, we have an HTML template which is the stuff that is ultimately injected into the DOM, and then we also have a style tag at the bottom. And this is to style the template of this component.
The main.js Entry Point and DOM Injection
Now moving on to this main.js file, this is the file that kind of kick-starts the app. It contains the code that ultimately runs first and sets everything up for us. First of all, it imports the App.svelte component that's created over here. So when we create a component, it's automatically exported, and we can import it into another file. So we're importing that first of all. We create a new instance of that component and then we have inside that instance this object, and this object has a target property. And this is basically saying, okay, well we have this app component instance, now where do you want to inject it into the DOM or the HTML document? And we're saying we want to grab the body tag and we want to put this app component, so all of this template right here, inside the body tag. This is the selector for that tag, but we could use a query selector if you wanted a different tag, but generally we're going to be using the body tag because that is where all of the content is kept in an HTML document.
So we have inside public this index.html, and this is the file right here that is served up over here to the browser, and that's what we're seeing. If we inspect the element, we can see that we have this HTML stuff right here. Okay. Now what this main.js file is doing is grabbing the document tag inside this index file over here, so we have the body tag right here. It's grabbing that and it's injecting all of the app template into that body tag right there. That's what this is saying. It's saying, okay, we're creating this instance of the app component and injecting it into the body tag. We also see this props property right here, which is a way to pass data into a component. So at the minute, we're passing in this name property which has a value of world. Now we'll talk more about props later, but essentially if we go to App.svelte, we can see we're grabbing that right here and this export denotes that this value name is being set from a prop outside of the component.
Now I don't want to talk too much about props or anything like that at the minute, so I'm going to delete this export statement and we'll talk about those later.
Component Nesting and the Build Process
So hopefully now you understand the general idea here of how this is working. We create components and the component is then injected into the DOM. Now in the future when we create more components, we're generally not going to put them into the DOM this way. Instead, what we'll do is nest them into this component. This component is a bit like a root component. It's the top level component that is injected directly into the DOM this way, and thereafter we can just nest all the components into the root component, and we'll talk more about that later on. But anyway, that's kind of how it all works under the hood.
And when we build our prototype, what happens is that Svelte looks at all of our components, it compiles them into a single JavaScript bundle, and it outputs it right here into the build folder, which we can see right here: bundle.js and bundle.css. So all of the scripts from our different components and all of the styles from our different components are bundled together in single files right here. And then from our index, we are linking to these files and that's how it all works.
Defining and Outputting Dynamic Data
Right, so now that we know that a little bit of how it works under the hood, let's try writing a bit of code. So we've already seen this at the minute where we're outputting a name, and we're outputting a variable right here which is defined right here. Initially it was defined over here and we passed it in as a prop, but now we're not accepting it as a prop because we deleted that export statement at the start. So if we tried to save this now it would be undefined and this is not going to output a name at all. It says hello undefined.
So instead let's give this a value. So I'm gonna say let name = 'Yoshi' for example. And then to output a variable that we define up here in the script inside the template, we just use single curly braces, then the variable name, like so. Dead easy. So if we save that now, we can see hello Yoshi. Now I could create another one. So I could say let's beltColor equal to something, and that is going to be black. And then if I want to output that, I can do... I'm going to delete the current content inside the paragraph tag and instead I'm going to output beltColor like so. And I'll put the word belt after it so it will be black belt. Save that and preview. We can see black belt.
Alright, so that's how we dynamically output any kind of variable and data that we define in our script, which is nice.
Reactivity and Handling User Events
Now what if we wanted to change the data at some point or react to a user event like a click event on a button to change the data? Well we can do that. If we come down here and create a button first of all, and inside the button we'll just say update belt color. If we want to react to a click event on this button we can just say on:click is equal to something.
Now this 'something' it's equal to is going to be inside curly braces because we're going to dynamically output a function name that we're going to declare up here. So imagine that we call this function handleClick. We'd have to define that up here. So let me do that. I'm going to say const handleClick = () => {... You can use regular functions if you wish, I'm using arrow functions, and then inside this we could change the beltColor. So I could say beltColor is then equal to something else, so orange for example. Okay, so this right here is saying we're going to react to a user clicking this button and when they click that, on:click, we're going to run this function. Okay, so that should change the value of beltColor and when that changes, we're gonna react to that by updating this right here in the browser. So if we save that and go over here and say update belt color, it doesn't work.
Now why doesn't that work? That's because we've misspelled color over here. Done that the American way. So save that and now if we try this, it works. It updates it to orange.
Svelte Compilation and Basic Concepts Review
So this stuff right here, this is Svelte syntax. It's not regular HTML or JavaScript. And we can output variables using regular HTML like this. This is all Svelte syntax, and it makes it really easy to output dynamic data or change dynamic data or react to user events like click events on buttons. So that's really nice.
But what happens then is when we build our project, it runs across all of our different components, it takes this Svelte syntax, and it turns or compiles it into regular vanilla JavaScript, and that is the stuff that is output right here inside the bundle.js. Now that looks quite complicated for that little bit of code that we've done, but the more components that we create, it will become efficient when it creates these bundles for us. So now we've learned the basics of Svelte. We know how to define data in a component, we know how to output that data, we know how to handle click events on things. And by the way, you don't have to attach this to a button. This could be a paragraph tag or an H1 if you wanted it to be. Doesn't have to be a button. But now we know these basics, let's in the next video have a look at use imports and data binding.