In this lesson, we move the component definition to a function, defined in a script tag in the HTML document.
We then iterate through an Array of Objects with the x-for
directive in Alpine JS. We use a <template>
tag to wrap the HTML element we want to repeat for each item, and put the x-for
directive on that template tag.
We also define a "computed" property by adding a method on our function, which checks if a given ID matched the currently active tab id. This computed property allows us to determine wether or not to apply the "active" classname to our tab buttons.
Instructor: [0:00] Instead of defining the components data directly inside of x-data here as an object, we can also extract it into a reusable function, which we can call from here. Down there, we'll open a script tag and define the function tabs(), which will return an object. Let's start by returning our activeTab set to , so things still work as they used to.
[0:23] Let's have the data for our three tabs as an array of objects. The first one has an id of , the title of Tab 1, and a text value as well. We'll do the same for the two other tabs.
[0:37] Instead of having three buttons, we will iterate over our tabs data. To do so we need to use a template tag. That template tag will have an x-for directive, which will let us iterate over each tab in tabs. Tabs here refers to a data object. Tab represents each item as we iterate over the tabs. We'll also set a key attribute that is set to tab.id.
[1:03] Let's copy our first button here inside the template tag and get rid of the other two. We'll replace our id in our click events and in the class attributes and use tab.id instead. We will also replace the button text with an x-text attribute set to tab.title. Looks like it's still working correctly.
[1:26] We'll do the same with the tab content now. Create a template tag which has an x-for of tab in tabs and a key of tab.id. We'll copy the first <div> inside the template tag, get rid of the other two, update the with tab.id and replace the paragraph text with x-text=tab.text. It's still working and now we are generating tabs based on data rather than hard code it in the HTML.
[1:57] One more thing. Notice that we are doing the same thing two times here. Check if activeTab is equal to the tab id. Not a big deal, but we could perhaps add a property to our data object, a method called getActiveStatus() which receives an id and then checks if that id = this.activeTab. Now I can replace my two checks with the getActiveStatus method and pass tab.id as the id parameter. Still works.
[2:26] As a recap, we moved the definition of our component into a function called tabs, defined in a script tag. We created an array of objects with our tabs data and then used the x-for directive to each array over that data.
[2:40] We used the template tag for that with a unique key value. Inside, we placed a single item with the data from the current tab index in the array. We repeated the same process for the tab content.
[2:52] Finally, in our data object, we added a method that takes an id and checks if that id matches the currently active tab. We then used that in our component mockup.