Good day everyone π
In this article i'm going to explain how to build a fully dynamic drop-down VueJS 3 component with HTML, Tailwind CSS 3 and Laravel 9. We will use composition API which was introduced in the latest version of Vue, our drop-down's content will be looping over Mysql database so it's a dynamic component and also we will introduce Vue3 click-outside npm package to close the drop-down when the user clicks anywhere else on the screen.
By the end of this 2 parts series you will be able to build this:
Table of Content:
- 0- What will You Learn?
- 0- Tools
- 1- Install Nodejs and npm
- 2- Start your Laravel Project
- 3- Install Database Management Tool
- 4- Create a Database
- 5- Connect to Database
- 6- Create fake users & Migrate with seed
- 7- Install Tailwind CSS
- 8- Install Vue and it's dependencies
- 9- Prepare your blade file
- 10- Enable Vue and make component
- 11- Build the Drop-down
- 12- Vue JS 3 click outside
- 13- Loop over users in Database
- 14- Finishing
By the end of this tutorial, you should know the below by heart β€οΈ:
- How to install Node and npm.
- How to create new Laravel 9 project.
- How to create and connect to a database.
- How to seed fake users to database.
- How to install tailwind CSS.
- How to install Vue, Vue Router and Vue Loader and activate them.
- How to prepare your blade file to receive your component via Vue-router
- How to make a dynamic drop-down vue js 3 component using composition API and click-outside package and style it with Tailwind CSS 3.
- How to receive Json data from database via route and loop over them with axios in Vue component.
A piece of advice before starting, this is a step by step guide so it's better if you code along as we will be using multiple frameworks and techniques. Let's get to it? π
0- I'm using
1- npm & Node
2- Laravel 9 π₯³
3- Table plus
4- Tailwind CSS 3
5- Vue JS 3 (With Vue Router & Vue Loader)
6- Windows Terminal
7- VS Code
1- Install Nodejs and npm:
- First thing you need to make sure that you have Node and npm installed on your machine.
- You can check that by opening up the terminal and type those two commands:
npm -v
node -v
- If you need to install them π DOCs for downloading Node and npm
- If you got that converged, move on π
PS C:\Users\Moose> node -v
v16.13.2
PS C:\Users\Moose> npm -v
8.4.0
2- Start your Laravel Project:
- If you already have a project, you can skip this step π.
- I use composer to create Laravel projects.
- You can download composer from here: https://getcomposer.org/
- Open up your terminal and create your Laravel project in the desired directory.
- The below command will create new Laravel 9 project for us.
PS C:\Users\Moose> cd F:\Projects
PS F:\Projects> composer create-project laravel/laravel dropdown-component
3- Install Database Management Tool:
- I use free version of table plus to manage my databases.
- You can download it from here: https://tableplus.com/
- This really doesn't require any instructions, keep clicking next and leave everything to default settings.
- You don't have to use it if you prefer another database management tool.
4- Create a Database:
- I will use MySQL Database. You're free to use whatever database you like.
- There are many ways to create Mysql Database, to know more you can visit this link.
- I will create a database using MySQL Command Line Client and name it 'dropdown'.
mysql> create database dropdown;
5- Connect to Database:
- Open your Laravel project in the preferred code editor, in my case I will use VS Code.
- Head to your
env
file in the main Laravel project directory. - In the below section make sure to update all the info to match your created database.
- Open table plus -> click on 'Create new connection' -> MySQL.
- Fill in the fields with the info you just created.
- You can name the connection with anything you want.
- After filling the fields click test then connect.
6- Create fake users & Migrate with seed:
- Head to
database\seeders\DatabaseSeeder.php
and remove the comment from the line inrun()
function. - This will allow you to create 10 fake users with Laravel Factory.
- Open up the terminal in the main project directory to run your migration command and --seed the fake users to database.
PS F:\Projects\dropdown-component> php artisan migrate --seed
- You can test that everything is as expected to this point, head to
resources\views\welcome.blade.php
and clear it, - Create new HTML boilerplate and in the body write the below code.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>dropdown</title>
</head>
<body>
@foreach ($users as $user)
<p>The name of the user is: {{ $user->name }}</p>
@endforeach
</body>
</html>
- Open the terminal and hit the below code within the project main directory to serve and see your project in browser.
PS F:\Projects\dropdown-component> php artisan serve
- You should see now that Laravel is looping over the database User's table and giving us back the name for each user.
7- Install Tailwind CSS:
- If you would like to install Tailwind CLI you can visit my article for a step by step guide on how to do that π CLICK HERE
- Or you can simply add the following line of code to import tailwind CDN in your project by following the steps in the documentation HERE
- In my case, I will use tailwind CLI for better results.
8- Install Vue and it's dependencies:
- Open the terminal in your project's main directory and run the below code to install Vue, Vue Router and Vue Loader.
PS F:\Projects\dropdown-component> npm install vue@next vue-router@next vue-loader@next
- I also prefer running
npm run watch
and leave it running in the backgroud while I'm working on my project.
PS F:\Projects\dropdown-component> npm run watch
- Head to
webpack.mix.js
file in your project's main directory and.vue()
right beforepostCss
.
mix.js("resources/js/app.js", "public/js")
.vue()
.postCss("resources/css/app.css", "public/css", [require("tailwindcss")]);
9- Prepare your blade file:
- Head to the
welcome.blade.php
file and clear the body then I will add empty divs that will contain our Vue component with router-vue. - Don't forget to add
id="app"
.
<body>
<main class="max-w-6xl mx-auto mt-6 lg:mt-20 space-y-6"
id="app">
<div class="max-w-xl mx-auto mt-10 text-center">
<div class="space-y-2 lg:space-y-0 lg:space-x-4 mt-8"
id="app">
<div class="relative lg:inline-flex items-center
bg-blue-100 rounded-xl">
<router-view />
</div>
</div>
</div>
</main>
</body>
10- Enable Vue and make component:
- Head to
resources\js\app.js
and add the below code and save to enable Vue JS.
import { createApp } from "vue";
createApp({
components: {},
}).mount("#app");
- Head to
resources\js
and create a subfolder calledcomponents
and within that folder createDropdownComponent.vue
file. - Inside the file write Vue default setup and leave a 'hello world' for testing.
<template>
<h1 class="text-red-500 text-bold">Hello world</h1>
</template>
<script>
export default {};
</script>
<style></style>
- Now it's time to create our route to this component.
- Head to
resources\js
and create a subfolder calledrouter
and inside it createindex.js
file. - Write the below code inside
index.js
file. - In this code you're basically telling your project
Hi, I want to use Vue router and import this component whenever I'm in that path
import { createRouter, createWebHistory } from "vue-router";
import DropdownComponent from "../components/DropdownComponent";
const routes = [
{
path: "/",
name: "home",
component: DropdownComponent,
},
];
export default createRouter({
history: createWebHistory(),
routes,
});
- Head back to
resources\js\app.js
and import your router and component. - End result below.
import { createApp } from "vue";
import router from "./router";
import DropdownComponent from "./components/DropdownComponent";
createApp({
components: {
DropdownComponent,
},
})
.use(router)
.mount("#app");
- Open up the terminal and stop your
npm run watch
if it's running and run it again to compile your files properly. - Now if you refresh you broswer you should see your hello world.
11- Build the Drop-down:
- Head back to
DropdownComponent.vue
and within the template you can start building your Dropdown. - I create a container div which contains a button and a div. I want when I press on the button I can see list of links.
- I will add a
@click
to the button and conditionally show the div with links if some condition is true.
<template>
<div>
<button
@click="showUsers"
class="flex max-h-52 w-full overflow-auto py-2 pl-3 pr-9 text-sm font-semibold lg:inline-flex lg:w-32"
>
Users
</button>
<div
v-show="usersToggle"
class="mt-1 w-full rounded-xl bg-blue-100 py-2"
>
<a href="#" class="block mt-1 w-full rounded-xl bg-
blue-100 py-2">
Testing
</a>
</div>
</div>
</template>
- Now let's move to the script tags to import what we need and write down our logic using composition API.
- I will import ref and onMounted then create a usersToggle and set it to false and make the click on the button change it to true.
<script>
import { ref, onMounted } from "vue";
export default {
name: "home",
setup() {
const usersToggle = ref(false);
const showUsers = () => {
usersToggle.value = !usersToggle.value;
};
return { showUsers, usersToggle };
},
};
</script>
- Now if you check your browser, whenever you click on the button it will open a drop-down list with the testing links and if you click it again it will close.
12- Vue JS 3 click outside:
- Head to the following LINKand install npm click outside package for Vue3.
PS F:\Projects\dropdown-component> npm install --save click-outside-vue3
- Head to
app.js
and import itimport vClickOutside from "click-outside-vue3";
and don't forget to addvClickOutside
just next to use router.use(router, vClickOutside)
- Head to
DropdownComponent.vue
and import it within the script tagsimport vClickOutside from 'click-outside-vue3'
- Add the directive as is says in the DOCs
directives: {
clickOutside: vClickOutside.directive,
},
- Then in the setup make sure to create your function that will make the usersToggle false again by clicking outside and return it.
setup() {
const usersToggle = ref(false);
const showUsers = () => {
usersToggle.value = !usersToggle.value;
};
const onClickOutside = (event) => {
usersToggle.value = false;
};
return { showUsers, usersToggle, onClickOutside };
},
- Within the template, add
v-click-outside="onClickOutside"
to the container div. - Now if you test it on browser it works like a charm.
13- Loop over users in Database:
- Create a new route to receive your Json data from database.
Route::get('list', function () {
return response()->json([
'users' => \App\Models\User::all()
], Response::HTTP_OK);
});
- Head back to your component and adjust the anchor tag to loop over users array.
<a
href="#"
class="block mt-1 w-full rounded-xl bg-blue-100
py-2"
v-for="user in users"
:key="user.id"
>
{{ user.name }}
</a>
- In the setup, create empty array for users.
const users = ref([]);
- Then write the below code to say:
Hey! Get my Json data as a response from this path, and change the users array value to whatever data in the response.
Not only this, I want this data as soon as my component is mounted and return it to me.
const getUsers = () => {
axios.get("/list").then((response) => {
users.value = response.data.users;
});
};
onMounted(() => {
getUsers();
});
return {
showUsers,
usersToggle,
onClickOutside,
getUsers,
users,
};
- Now, If you check your browser you will see your users names in a dynamic functional dropdown menu.
This is a final screen for my code in case you want to compare it to yours:
Also you can find full code on Github: https://github.com/MooseSaeed/dropdown-component
14- Finishing:
Congratulations you've created a complex Vue component with the latest release of everything ππ₯³
Thank you so much for reading my article and I hope it was helpful for everyone.
If you have any questions, comments or feedback please leave them below or find me on Twitter and DMs are open.
Top comments (1)
This is a nice post. The most interested plugin is vue-3-click-outside. Have fun!!! :)