Laravel integration
How to use Vue with Laravel - free starter
This guide will provide you with a free template for a Laravel application, with MySQL database and Vue + Bootstrap 5 front-end.
Prerequisites
Before starting the project make sure to install the following utilities:
Creating a new Laravel application
Step 1
Creating MySQL database.
In order to create a new database you need to run the following command:
mdb database init -db mysql8
- Create a new user
- Provide username, password, database name and description.
CLI will display your username, password, database name and connections string. Now you can go to phpMyAdmin where you will be able to handle the administration of the MySQL database.
Note: the password must contain at least one uppercase letter, one lowercase letter, one number, one special symbol and have minimum length of 8.
Important: Do not close your terminal window until you save your credentials somewhere. This is the only time we will show you your database password. If you won't save it you'll loose it.
Step 2
Create a table.
Go to phpMyAdmin, log in, and add a table, which name will be a plural form of created model. For example on purpose of this tutorial: tasks. Then create a three columns: id (type: int), name (type: text) and description (type: text).
Step 3
Creating Laravel project.
You can initialize a MDB GO starter. Simply run the following command:
mdb backend init
and choose Laravel starter
from the list that shows up.
After initialization just go to the newly created project directory and open the .env
file. After that edit the config values that start with DB_
. You should make use of credentials that's been shown to you in the previous step. In my case the updated values look like this:
DB_CONNECTION=mysql
DB_HOST=mysql.db.mdbgo.com
DB_PORT=3306
DB_DATABASE=your_database_name
DB_USERNAME=your_username
DB_PASSWORD=your_password
Step 4
Navigate to you project direction and install Laravel dependencies using Composer. php-free-laravel
is the name from MDB GO starter (you can change whatever you like).
composer install
Note: If after this process you got an error bound installation - add to previously used command flag --ignore-platform-req=ext-fileinfo
.
Step 5
Create a model. You can use built in Laravel pre-made function: php artisan make:model Task
, where Task
is your custom name (you can change it whatever you like). Nevertheless this model should being inserted in app/Models
directory and looks like this:
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Task extends Model
{
use HasFactory;
public $timestamps=false;
}
Step 6
Now create a controller for handling an endpoints. You can use built in Laravel pre-made function: php artisan make:controller TaskController
, where TaskController
is your custom name (you can change it whatever you like). Nevertheless this controller should being inserted in app/Http/Controllers
directory and looks like this:
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Models\Task;
class TaskController extends Controller
{
function getTasks() {
return Task::all();
}
function addTask(Request $req) {
$task=new Task;
$task->id=$req->id;
$task->name=$req->name;
$task->description=$req->description;
$result=$task->save();
return ["Result"=>"Data has been saved"];
}
function editTask(Request $req) {
$task= Task::find($req->id);
$task->name=$req->name;
$task->description=$req->description;
$result=$task->save();
return ["Result"=>"Edit successfully"];
}
function deleteTask($id) {
$task=Task::find($id);
$result=$task->delete();
return ["Result"=>"Record has beend deleted"];
}
}
Step 7
Add routes for newly created controller in api.php
file (found in routes
folder in root directory).
Route::get('tasks', [TaskController::class, 'getTasks']);
Route::post('task', [TaskController::class, 'addTask']);
Route::put('edit', [TaskController::class, 'editTask']);
Route::delete('delete/{id}', [TaskController::class, 'deleteTask']);
Step 8
The starter project is ready to use. You don't have to change anything to run the example app for the sake of this tutorial. Simply publish it using the following command:
mdb publish -p php-laravel
Note Since we need to install dependencies and run your app, it may take a few moments until it will be available under the provided URL.
Creating MDB Vue application
Note: Don't forget to go back to your root folder before next step. Folders php-free-laravel
and mdb5-free-vue
should be in the same directory.
Step 1
Create a new vite project with our MDB starter. Run the command below and select MDB5 Free Vue
starter.
mdb init
Your folder structure should look like this
Step 2
Let's make some changes to the created vue app. First we need to install axios
inside our mdb5-free-vue
directory.
npm install axios
Remove style.css
file (don't forget to delete it from main.ts
file) and remove HelloWorld
file from components directory.
Step 3
Let's create a .env
file inside a mdb5-free-vue directory. We have to add VITE_
before the name of your variable, because it's the only way to expose them to Vite-processed code. Don't forget to change URL to the one you created earlier.
VITE_API = "LINK_TO_YOUR_BACKEND_APP"
Step 4
Add new content to Home.vue
file inside the views
directory.
Since our starter database contains some sample models and routes, let's use them. We will create an application that will show a list of tasks. We also intend to create a functonality for adding new tasks, changing their content and removing them.
We have already prepared the code for you, so go ahead and copy and paste it into App.vue
.
Ok, so what's actually going on there. We use MDB components, MDBBtn, MDBModal, MDBListGroup, MDBInputs
and few other. The modal will be responsible to show inputs that will allow you to add, edit and send tasks to the database. The Manage tasks
button, gives possibilty to modify or remove tasks. At the end, the list group will display our data.
<template>
<MDBContainer class="mt-5">
<MDBRow class="pt-5">
<MDBCol class="text-center">
<MDBBtn color="primary" @click="taskModal = true">Add task</MDBBtn>
</MDBCol>
</MDBRow>
<MDBRow class="mt-3 p-5" style="min-height: 40vh">
<MDBCol class="d-flex justify-content-center align-items-center">
<div v-if="taskList.length === 0">
Nothing to display. Add a few tasks.
</div>
<MDBListGroup v-else class="list-group-light" style="min-width: 22rem">
<MDBListGroupItem
class="d-flex justify-content-between align-items-center gap-5"
v-for="task in taskList"
:key="task.id"
>
<div>
<div class="fw-bold">
{{ task.name }}
</div>
<div class="text-muted">{{ task.description }}</div>
</div>
<div>
<MDBIcon
class="text-primary me-3"
title="edit"
icon="pen"
style="cursor: pointer"
@click="() => editModal(task)"
/>
<MDBIcon
class="text-danger"
title="delete"
icon="trash"
style="cursor: pointer"
@click="() => deleteTask(task.id)"
/>
</div>
</MDBListGroupItem>
</MDBListGroup>
</MDBCol>
</MDBRow>
</MDBContainer>
<MDBModal
id="addNewTaskModal"
tabindex="-1"
labelledby="addNewTaskModalLabel"
v-model="taskModal"
>
<MDBModalHeader>
<MDBModalTitle id="exampleModalLabel">{{
isEdited.edited ? "Edit task" : "Add task"
}}</MDBModalTitle>
</MDBModalHeader>
<MDBModalBody>
<form>
<div class="my-4">
<MDBInput
label="Name"
type="text"
v-model="newTaskName"
counter
:maxlength="60"
/>
</div>
<div class="my-4">
<MDBInput
label="Description"
type="text"
v-model="newTaskDesc"
counter
:maxlength="255"
/>
</div>
</form>
</MDBModalBody>
<MDBModalFooter>
<MDBBtn
color="secondary"
@click="
{
resetInputs();
taskModal = false;
}
"
>Close</MDBBtn
>
<MDBBtn
color="primary"
@click="handleSaveChanges"
:disabled="!canSendData"
>{{ isEdited.edited ? "Save changes" : "Add task" }}</MDBBtn
>
</MDBModalFooter>
</MDBModal>
</template>
<script setup lang="ts">
import { ref, onMounted, computed } from "vue";
import {
MDBContainer,
MDBRow,
MDBCol,
MDBListGroup,
MDBListGroupItem,
MDBBtn,
MDBModal,
MDBModalTitle,
MDBModalHeader,
MDBModalBody,
MDBModalFooter,
MDBInput,
MDBIcon,
} from "mdb-vue-ui-kit";
import axios from "axios";
interface SingleTask {
id: number;
name: string;
description: string;
}
const taskList = ref<SingleTask[]>([]);
const taskModal = ref(false);
const newTaskName = ref("");
const newTaskDesc = ref("");
const isEdited = ref({ edited: false, value: -1 });
const API_URL = ref("");
const canSendData = computed(() => {
if (newTaskName.value.trim() === "" || newTaskDesc.value.trim() === "") {
return false;
}
return true;
});
const resetInputs = () => {
newTaskName.value = "";
newTaskDesc.value = "";
isEdited.value = { edited: false, value: -1 };
};
const handleSaveChanges = async () => {
if (!canSendData.value) {
return;
}
isEdited.value.edited
? updateTask(isEdited.value.value, newTaskName.value, newTaskDesc.value)
: createTask(
newTaskName.value,
newTaskDesc.value,
Math.ceil(Math.random() * 1000000)
);
resetInputs();
taskModal.value = false;
};
const editModal = (task: SingleTask) => {
newTaskName.value = task.name;
newTaskDesc.value = task.description;
isEdited.value = { edited: true, value: task.id };
taskModal.value = true;
};
const getTaskList = () => {
axios
.get(`${API_URL.value}tasks`)
.then((res) => (taskList.value = res.data));
};
const createTask = (name: string, description: string, id: number) => {
const data = { name, description, id };
axios.post(`${API_URL.value}task`, data).then(() => {
getTaskList();
});
};
const deleteTask = (id: number) => {
axios.delete(`${API_URL.value}delete/${id}`).then(() => {
getTaskList();
});
};
const updateTask = (id: number, name: string, description: string) => {
const data = { name, description };
axios.put(`${API_URL.value}edit`, data).then(() => {
getTaskList();
});
};
onMounted(() => {
API_URL.value = import.meta.env.VITE_API;
getTaskList();
});
</script>
If you haven't done it already, run npm start
in your terminal. The app should be fully functional and should work correctly with backend.
Step 5
Now you can publish your project on MDB GO
mdb publish
Optimization
If you want to further optimize your application please visit: