0% found this document useful (0 votes)
87 views26 pages

Student Register with Laravel & Vue.js

Uploaded by

Tshepo
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
87 views26 pages

Student Register with Laravel & Vue.js

Uploaded by

Tshepo
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd

Creating a Student Register Using Laravel and Vue.

js: An
8-Page Comprehensive Guide
Table of Contents
1. Introduction
2. Prerequisites
3. Setting Up the Laravel Backend
4. Designing the Database Schema
5. Creating API Endpoints with Laravel
6. Setting Up the [Link] Frontend
7. Building Vue Components and Integrating with Laravel
8. Implementing CRUD Operations
9. Authentication and Security
10. Testing and Deployment
11. Conclusion

Introduction
Building a student register system is a common requirement for educational institutions and
related applications. Combining Laravel for the backend and [Link] for the frontend
leverages the strengths of both frameworks, providing a robust, scalable, and dynamic
application. Laravel offers a powerful API-building capability, while [Link] ensures a
responsive and interactive user interface. This guide walks you through creating a
comprehensive student registration system using Laravel and [Link], covering everything
from initial setup to deployment.

Prerequisites
Before embarking on this project, ensure you have the following tools and knowledge:

• Basic Knowledge of PHP and Laravel: Understanding Laravel's MVC architecture.


• Basic Knowledge of JavaScript and [Link]: Familiarity with Vue components, directives, and
lifecycle hooks.
• Composer Installed: Laravel utilizes Composer for dependency management.
• [Link] and NPM: Required for managing [Link] dependencies.
• Database Server: MySQL, PostgreSQL, or any other supported database.
• Code Editors: VS Code, PHPStorm, or your preferred IDE.
• Git: For version control.
• Postman: For API testing (optional but recommended).

Optional but beneficial: Familiarity with RESTful APIs, Axios for HTTP requests in [Link],
and basic understanding of authentication mechanisms.
Setting Up the Laravel Backend
1. Install Laravel

Use Composer to create a new Laravel project:

composer create-project --prefer-dist laravel/laravel student-register-


backend

Navigate to the project directory:

cd student-register-backend

2. Configure Environment

Duplicate the .[Link] file to .env:

cp .[Link] .env

Generate an application key:

php artisan key:generate

3. Set Up Development Server

Start the Laravel development server:

php artisan serve

Visit [Link] to verify the setup.

4. Install Laravel Sanctum (For API Authentication)

Laravel Sanctum provides a lightweight authentication system for SPAs (Single Page
Applications):

composer require laravel/sanctum

Publish the Sanctum configuration and migration files:

php artisan vendor:publish --


provider="Laravel\Sanctum\SanctumServiceProvider"

Run migrations:

php artisan migrate


5. Configure CORS

To allow your [Link] frontend to communicate with the Laravel backend, configure CORS.

Open config/[Link] and adjust settings:

return [

'paths' => ['api/*', 'sanctum/csrf-cookie'],

'allowed_methods' => ['*'],

'allowed_origins' => ['[Link] // Vue's default port

'allowed_origins_patterns' => [],

'allowed_headers' => ['*'],

'exposed_headers' => [],

'max_age' => 0,

'supports_credentials' => true,

];

Designing the Database Schema


1. Database Selection

Choose a relational database system like MySQL. Ensure it's installed and running.

2. Create Database

Create a new database for the project, e.g., student_register.

3. Configure .env

Update the .env file with your database credentials:

DB_CONNECTION=mysql
DB_HOST=[Link]
DB_PORT=3306
DB_DATABASE=student_register
DB_USERNAME=your_username
DB_PASSWORD=your_password

4. Plan Database Schema

For a student register, a basic schema might include:

• Students Table:
o id (primary key)
o first_name
o last_name
o email
o phone
o address
o date_of_birth
o created_at
o updated_at

5. Create Migration

Generate the migration for the students table:

php artisan make:migration create_students_table --create=students

Edit the migration file


(database/migrations/xxxx_xx_xx_create_students_table.php):

public function up()


{
Schema::create('students', function (Blueprint $table) {
$table->id();
$table->string('first_name');
$table->string('last_name');
$table->string('email')->unique();
$table->string('phone')->nullable();
$table->text('address')->nullable();
$table->date('date_of_birth')->nullable();
$table->timestamps();
});
}

Run the migration:

php artisan migrate

Creating API Endpoints with Laravel


1. Create Student Model and Controller

Generate a model with a migration and a resource controller:

php artisan make:model Student -m


php artisan make:controller API/StudentController --api

2. Define Model Fillable Properties

Open app/Models/[Link] and add the $fillable property:

<?php

namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;

class Student extends Model


{
use HasFactory;

protected $fillable = [
'first_name',
'last_name',
'email',
'phone',
'address',
'date_of_birth',
];
}

3. Define API Routes

Open routes/[Link] and add resource routes:

use App\Http\Controllers\API\StudentController;

Route::middleware('auth:sanctum')->group(function () {
Route::apiResource('students', StudentController::class);
});

4. Implement Controller Methods

Open app/Http/Controllers/API/[Link] and implement CRUD


methods:

<?php

namespace App\Http\Controllers\API;

use App\Http\Controllers\Controller;
use App\Models\Student;
use Illuminate\Http\Request;

class StudentController extends Controller


{
// Display a listing of students
public function index()
{
return Student::paginate(10);
}

// Store a newly created student


public function store(Request $request)
{
$request->validate([
'first_name' => 'required|string|max:255',
'last_name' => 'required|string|max:255',
'email' => 'required|email|unique:students,email',
'phone' => 'nullable|string|max:20',
'address' => 'nullable|string',
'date_of_birth' => 'nullable|date',
]);
$student = Student::create($request->all());

return response()->json($student, 201);


}

// Display the specified student


public function show(Student $student)
{
return $student;
}

// Update the specified student


public function update(Request $request, Student $student)
{
$request->validate([
'first_name' => 'sometimes|required|string|max:255',
'last_name' => 'sometimes|required|string|max:255',
'email' =>
'sometimes|required|email|unique:students,email,' . $student->id,
'phone' => 'nullable|string|max:20',
'address' => 'nullable|string',
'date_of_birth' => 'nullable|date',
]);

$student->update($request->all());

return response()->json($student, 200);


}

// Remove the specified student


public function destroy(Student $student)
{
$student->delete();

return response()->json(null, 204);


}
}

5. Implement Authentication Routes

To manage user authentication, you can use Laravel Sanctum.

a. Create Authentication Controller

Generate an authentication controller:

php artisan make:controller API/AuthController


b. Define Authentication Methods

Open app/Http/Controllers/API/[Link] and implement registration and


login:

<?php

namespace App\Http\Controllers\API;

use App\Http\Controllers\Controller;
use App\Models\User;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Hash;
use Illuminate\Validation\ValidationException;

class AuthController extends Controller


{
// User Registration
public function register(Request $request)
{
$request->validate([
'name' => 'required|string|max:255',
'email' => 'required|email|unique:users,email',
'password' => 'required|string|min:6|confirmed',
]);

$user = User::create([
'name' => $request->name,
'email' => $request->email,
'password' => Hash::make($request->password),
]);

$token = $user->createToken('student-register-token')-
>plainTextToken;

return response()->json([
'user' => $user,
'token' => $token,
], 201);
}

// User Login
public function login(Request $request)
{
$request->validate([
'email' => 'required|email',
'password' => 'required|string',
]);

$user = User::where('email', $request->email)->first();

if (! $user || ! Hash::check($request->password, $user->password))


{
throw ValidationException::withMessages([
'email' => ['The provided credentials are incorrect.'],
]);
}

// Revoke previous tokens...


$user->tokens()->delete();

$token = $user->createToken('student-register-token')-
>plainTextToken;

return response()->json([
'user' => $user,
'token' => $token,
], 200);
}

// User Logout
public function logout(Request $request)
{
$request->user()->currentAccessToken()->delete();

return response()->json([
'message' => 'Logged out successfully.'
], 200);
}
}
c. Define Authentication Routes

Add the following to routes/[Link]:

use App\Http\Controllers\API\AuthController;

Route::post('/register', [AuthController::class, 'register']);


Route::post('/login', [AuthController::class, 'login']);

Route::middleware('auth:sanctum')->post('/logout', [AuthController::class,
'logout']);

6. Test Backend API

Use Postman or cURL to test the API endpoints.

• Register: POST [Link]


• Login: POST [Link]
• CRUD Operations: Use the token received upon login to access protected routes.

Setting Up the [Link] Frontend


1. Initialize Vue Project

Use Vue CLI to bootstrap the frontend project. If you don't have Vue CLI installed, install it
globally:

npm install -g @vue/cli

Create a new Vue project:

vue create student-register-frontend

Navigate to the project directory:

cd student-register-frontend

Choose the default preset or customize it as per your requirements.

2. Install Necessary Dependencies

Install Axios for HTTP requests and Vue Router for routing:
npm install axios vue-router

Optionally, install BootstrapVue for styling:

npm install bootstrap bootstrap-vue

Import BootstrapVue in src/[Link]:

// src/[Link]

import Vue from 'vue';


import App from './[Link]';
import router from './router';
import axios from 'axios';

import { BootstrapVue, IconsPlugin } from 'bootstrap-vue';


import 'bootstrap/dist/css/[Link]';
import 'bootstrap-vue/dist/[Link]';

[Link](BootstrapVue);
[Link](IconsPlugin);

[Link] = false;

// Set up Axios
[Link] = '[Link]
[Link] = true;

// Add a request interceptor to include the token


[Link]((config) => {
const token = [Link]('token');
if (token) {
[Link] = `Bearer ${token}`;
}
return config;
}, (error) => {
return [Link](error);
});

new Vue({
router,
render: h => h(App),
}).$mount('#app');

3. Set Up Project Structure

Organize your project with the following structure:

src/

├── components/
│ ├── Auth/
│ │ ├── [Link]
│ │ └── [Link]
│ ├── Students/
│ │ ├── [Link]
│ │ ├── [Link]
│ │ └── [Link]
│ └── Layout/
│ └── [Link]

├── router/
│ └── [Link]

├── services/
│ └── [Link]

├── [Link]
├── [Link]
└── ...

Building Vue Components and Integrating with Laravel


1. Create Navigation Bar

Create src/components/Layout/[Link]:

<!-- src/components/Layout/[Link] -->

<template>
<b-navbar toggleable="lg" type="light" variant="light">
<b-navbar-brand href="#">Student Register</b-navbar-brand>

<b-navbar-toggle target="nav-collapse"></b-navbar-toggle>

<b-collapse id="nav-collapse" is-nav>


<b-navbar-nav>
<b-nav-item v-if="isLoggedIn" to="/students">Students</b-nav-item>
</b-navbar-nav>

<b-navbar-nav class="ml-auto">
<b-nav-item v-if="!isLoggedIn" to="/login">Login</b-nav-item>
<b-nav-item v-if="!isLoggedIn" to="/register">Register</b-nav-item>
<b-nav-item-dropdown v-if="isLoggedIn" right>
<template v-slot:button-content>
{{ [Link] }}
</template>
<b-dropdown-item @click="logout">Logout</b-dropdown-item>
</b-nav-item-dropdown>
</b-navbar-nav>
</b-collapse>
</b-navbar>
</template>

<script>
import axios from 'axios';

export default {
name: 'Navbar',
data() {
return {
user: {},
};
},
computed: {
isLoggedIn() {
return !![Link]('token');
},
},
methods: {
logout() {
[Link]('/logout')
.then(() => {
[Link]('token');
this.$[Link]('/login');
})
.catch(error => {
[Link]('Logout failed:', error);
});
},
fetchUser() {
[Link]('/user')
.then(response => {
[Link] = [Link];
})
.catch(error => {
[Link]('Error fetching user:', error);
});
},
},
created() {
if ([Link]) {
[Link]();
}
},
};
</script>

<style scoped>
/* Add any custom styles here */
</style>

2. Configure Routing

Create src/router/[Link]:

// src/router/[Link]

import Vue from 'vue';


import Router from 'vue-router';

import Register from '../components/Auth/[Link]';


import Login from '../components/Auth/[Link]';
import StudentList from '../components/Students/[Link]';
import StudentForm from '../components/Students/[Link]';
import StudentDetail from '../components/Students/[Link]';

[Link](Router);

const router = new Router({


mode: 'history',
routes: [
{
path: '/',
redirect: '/students',
},
{
path: '/register',
name: 'Register',
component: Register,
meta: { requiresGuest: true },
},
{
path: '/login',
name: 'Login',
component: Login,
meta: { requiresGuest: true },
},
{
path: '/students',
name: 'StudentList',
component: StudentList,
meta: { requiresAuth: true },
},
{
path: '/students/create',
name: 'StudentCreate',
component: StudentForm,
meta: { requiresAuth: true },
},
{
path: '/students/edit/:id',
name: 'StudentEdit',
component: StudentForm,
meta: { requiresAuth: true },
},
{
path: '/students/:id',
name: 'StudentDetail',
component: StudentDetail,
meta: { requiresAuth: true },
},
{
path: '*',
redirect: '/students',
},
],
});

// Navigation Guards
[Link]((to, from, next) => {
const isLoggedIn = !![Link]('token');
if ([Link](record => [Link])) {
if (!isLoggedIn) {
next('/login');
} else {
next();
}
} else if ([Link](record => [Link])) {
if (isLoggedIn) {
next('/students');
} else {
next();
}
} else {
next();
}
});
export default router;

3. Create Authentication Components


a. Register Component

Create src/components/Auth/[Link]:

<!-- src/components/Auth/[Link] -->

<template>
<div class="container mt-5">
<h2>Register</h2>
<b-alert variant="danger" show v-if="[Link]">
<ul>
<li v-for="(error, index) in errors" :key="index">{{ error }}</li>
</ul>
</b-alert>
<b-form @[Link]="handleRegister">
<b-form-group label="Name" label-for="name">
<b-form-input
id="name"
v-model="[Link]"
required
placeholder="Enter your name"
></b-form-input>
</b-form-group>

<b-form-group label="Email" label-for="email">


<b-form-input
id="email"
type="email"
v-model="[Link]"
required
placeholder="Enter your email"
></b-form-input>
</b-form-group>

<b-form-group label="Password" label-for="password">


<b-form-input
id="password"
type="password"
v-model="[Link]"
required
placeholder="Enter your password"
></b-form-input>
</b-form-group>

<b-form-group label="Confirm Password" label-


for="password_confirmation">
<b-form-input
id="password_confirmation"
type="password"
v-model="form.password_confirmation"
required
placeholder="Confirm your password"
></b-form-input>
</b-form-group>
<b-button type="submit" variant="primary">Register</b-button>
</b-form>
</div>
</template>

<script>
import axios from 'axios';

export default {
name: 'Register',
data() {
return {
form: {
name: '',
email: '',
password: '',
password_confirmation: '',
},
errors: [],
};
},
methods: {
handleRegister() {
[Link]('/register', [Link])
.then(response => {
[Link]('token', [Link]);
this.$[Link]('/students');
})
.catch(error => {
if ([Link] && [Link]) {
[Link] = [Link]([Link]).flat();
}
});
},
},
};
</script>

<style scoped>
/* Add any custom styles here */
</style>
b. Login Component

Create src/components/Auth/[Link]:

<!-- src/components/Auth/[Link] -->

<template>
<div class="container mt-5">
<h2>Login</h2>
<b-alert variant="danger" show v-if="[Link]">
<ul>
<li v-for="(error, index) in errors" :key="index">{{ error }}</li>
</ul>
</b-alert>
<b-form @[Link]="handleLogin">
<b-form-group label="Email" label-for="email">
<b-form-input
id="email"
type="email"
v-model="[Link]"
required
placeholder="Enter your email"
></b-form-input>
</b-form-group>

<b-form-group label="Password" label-for="password">


<b-form-input
id="password"
type="password"
v-model="[Link]"
required
placeholder="Enter your password"
></b-form-input>
</b-form-group>

<b-button type="submit" variant="primary">Login</b-button>


</b-form>
</div>
</template>

<script>
import axios from 'axios';

export default {
name: 'Login',
data() {
return {
form: {
email: '',
password: '',
},
errors: [],
};
},
methods: {
handleLogin() {
[Link]('/login', [Link])
.then(response => {
[Link]('token', [Link]);
this.$[Link]('/students');
})
.catch(error => {
if ([Link] && [Link]) {
[Link] = [Link]([Link]).flat();
}
});
},
},
};
</script>

<style scoped>
/* Add any custom styles here */
</style>

4. Create Student Components


a. Student List Component

Create src/components/Students/[Link]:
<!-- src/components/Students/[Link] -->

<template>
<div class="container mt-5">
<h2>Students</h2>
<b-button variant="primary" class="mb-3"
@click="$[Link]('/students/create')">Add New Student</b-button>
<b-table striped hover :items="students" :fields="fields">
<template #cell(actions)="row">
<b-button size="sm" variant="info"
@click="viewStudent([Link])">View</b-button>
<b-button size="sm" variant="warning" class="ml-2"
@click="editStudent([Link])">Edit</b-button>
<b-button size="sm" variant="danger" class="ml-2"
@click="deleteStudent([Link])">Delete</b-button>
</template>
</b-table>
<b-pagination
v-if="pagination.last_page > 1"
v-model="pagination.current_page"
:total-rows="[Link]"
:per-page="pagination.per_page"
@change="fetchStudents"
align="center"
class="my-0"
></b-pagination>
</div>
</template>

<script>
import axios from 'axios';

export default {
name: 'StudentList',
data() {
return {
students: [],
fields: [
{ key: 'id', label: 'ID' },
{ key: 'first_name', label: 'First Name' },
{ key: 'last_name', label: 'Last Name' },
{ key: 'email', label: 'Email' },
{ key: 'phone', label: 'Phone' },
{ key: 'actions', label: 'Actions' },
],
pagination: {
current_page: 1,
last_page: 1,
total: 0,
per_page: 10,
},
};
},
methods: {
fetchStudents(page = 1) {
[Link](`/students?page=${page}`)
.then(response => {
[Link] = [Link];
[Link] = {
current_page: [Link].current_page,
last_page: [Link].last_page,
total: [Link],
per_page: [Link].per_page,
};
})
.catch(error => {
[Link]('Error fetching students:', error);
});
},
viewStudent(id) {
this.$[Link](`/students/${id}`);
},
editStudent(id) {
this.$[Link](`/students/edit/${id}`);
},
deleteStudent(id) {
if (confirm('Are you sure you want to delete this student?')) {
[Link](`/students/${id}`)
.then(() => {
[Link]([Link].current_page);
})
.catch(error => {
[Link]('Error deleting student:', error);
});
}
},
},
created() {
[Link]();
},
};
</script>

<style scoped>
/* Add any custom styles here */
</style>
b. Student Form Component

Create src/components/Students/[Link]:

<!-- src/components/Students/[Link] -->

<template>
<div class="container mt-5">
<h2>{{ isEdit ? 'Edit' : 'Add' }} Student</h2>
<b-alert variant="danger" show v-if="[Link]">
<ul>
<li v-for="(error, index) in errors" :key="index">{{ error }}</li>
</ul>
</b-alert>
<b-form @[Link]="handleSubmit">
<b-form-group label="First Name" label-for="first_name">
<b-form-input
id="first_name"
v-model="form.first_name"
required
placeholder="Enter first name"
></b-form-input>
</b-form-group>

<b-form-group label="Last Name" label-for="last_name">


<b-form-input
id="last_name"
v-model="form.last_name"
required
placeholder="Enter last name"
></b-form-input>
</b-form-group>

<b-form-group label="Email" label-for="email">


<b-form-input
id="email"
type="email"
v-model="[Link]"
required
placeholder="Enter email"
></b-form-input>
</b-form-group>

<b-form-group label="Phone" label-for="phone">


<b-form-input
id="phone"
v-model="[Link]"
placeholder="Enter phone number"
></b-form-input>
</b-form-group>

<b-form-group label="Address" label-for="address">


<b-form-textarea
id="address"
v-model="[Link]"
placeholder="Enter address"
rows="3"
></b-form-textarea>
</b-form-group>

<b-form-group label="Date of Birth" label-for="date_of_birth">


<b-form-input
id="date_of_birth"
type="date"
v-model="form.date_of_birth"
></b-form-input>
</b-form-group>

<b-button type="submit" variant="success">{{ isEdit ? 'Update' :


'Save' }}</b-button>
</b-form>
</div>
</template>

<script>
import axios from 'axios';

export default {
name: 'StudentForm',
data() {
return {
form: {
first_name: '',
last_name: '',
email: '',
phone: '',
address: '',
date_of_birth: '',
},
errors: [],
};
},
computed: {
isEdit() {
return !!this.$[Link];
},
},
methods: {
fetchStudent() {
[Link](`/students/${this.$[Link]}`)
.then(response => {
[Link] = [Link];
})
.catch(error => {
[Link]('Error fetching student:', error);
});
},
handleSubmit() {
if ([Link]) {
[Link](`/students/${this.$[Link]}`, [Link])
.then(() => {
this.$[Link]('/students');
})
.catch(error => {
if ([Link] && [Link]) {
[Link] =
[Link]([Link]).flat();
}
});
} else {
[Link]('/students', [Link])
.then(() => {
this.$[Link]('/students');
})
.catch(error => {
if ([Link] && [Link]) {
[Link] =
[Link]([Link]).flat();
}
});
}
},
},
created() {
if ([Link]) {
[Link]();
}
},
};
</script>

<style scoped>
/* Add any custom styles here */
</style>
c. Student Detail Component

Create src/components/Students/[Link]:

<!-- src/components/Students/[Link] -->

<template>
<div class="container mt-5" v-if="student">
<h2>Student Details</h2>
<b-card>
<b-card-text><strong>Name:</strong> {{ student.first_name }} {{
student.last_name }}</b-card-text>
<b-card-text><strong>Email:</strong> {{ [Link] }}</b-card-
text>
<b-card-text><strong>Phone:</strong> {{ [Link] || 'N/A' }}</b-
card-text>
<b-card-text><strong>Address:</strong> {{ [Link] || 'N/A'
}}</b-card-text>
<b-card-text><strong>Date of Birth:</strong> {{ student.date_of_birth
|| 'N/A' }}</b-card-text>
<b-button variant="primary" @click="$[Link]('/students')">Back
to List</b-button>
</b-card>
</div>
<div class="container mt-5" v-else>
<p>Loading...</p>
</div>
</template>

<script>
import axios from 'axios';

export default {
name: 'StudentDetail',
data() {
return {
student: null,
};
},
methods: {
fetchStudent() {
[Link](`/students/${this.$[Link]}`)
.then(response => {
[Link] = [Link];
})
.catch(error => {
[Link]('Error fetching student:', error);
});
},
},
created() {
[Link]();
},
};
</script>

<style scoped>
/* Add any custom styles here */
</style>
5. Configure Routing in [Link]

Edit src/[Link]:

<!-- src/[Link] -->

<template>
<div id="app">
<Navbar />
<router-view></router-view>
</div>
</template>

<script>
import Navbar from './components/Layout/[Link]';

export default {
name: 'App',
components: {
Navbar,
},
};
</script>

<style>
/* Add any global styles here */
</style>

Implementing CRUD Operations


With the components in place, you can perform the following operations:

1. Create (Add a New Student)

• Navigate to /students/create.
• Fill out the form and submit.
• The student will be added to the database and appear in the student list.

2. Read (View Students)

• Navigate to /students.
• View the list of students with pagination.
• Click on a student's "View" button to see detailed information.

3. Update (Edit a Student)

• Navigate to /students/edit/{id}.
• Modify the desired fields and submit.
• The changes will reflect in the student list and detail view.
4. Delete (Remove a Student)

• Click the "Delete" button next to a student in the list.


• Confirm the deletion.
• The student will be removed from the database and the list.

5. Authentication

• Register a new user via /register.


• Login via /login to obtain an authentication token.
• Only authenticated users can access the student management features.
• Logout to invalidate the token and restrict access.

Authentication and Security


1. Protecting Routes

Ensure that only authenticated users can access certain routes. This is handled both in the
frontend ([Link]) and backend (Laravel).

• Frontend: Use Vue Router navigation guards to redirect unauthenticated users to the login
page.
• Backend: Use Laravel Sanctum's auth:sanctum middleware to protect API routes.

2. Handling Tokens Securely

• Store the authentication token in localStorage.


• For enhanced security, consider using HTTP-only cookies to prevent XSS attacks.

3. Validating Inputs

Both frontend and backend should validate user inputs to prevent malicious data from being
processed.

• Frontend: Provide immediate feedback to users for incorrect inputs.


• Backend: Enforce validation rules to ensure data integrity.

4. Error Handling

Gracefully handle errors both on the frontend and backend.

• Frontend: Display user-friendly error messages.


• Backend: Return meaningful HTTP status codes and error messages.
5. Implementing HTTPS

Ensure that your application uses HTTPS to encrypt data transmitted between the client and
server.

Testing and Deployment


1. Testing the Application
a. Backend Testing

Use PHPUnit to write tests for your Laravel API.

Example test for creating a student:

// tests/Feature/[Link]

namespace Tests\Feature;

use App\Models\User;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Tests\TestCase;

class StudentTest extends TestCase


{
use RefreshDatabase;

public function test_create_student()


{
$user = User::factory()->create();
$token = $user->createToken('test-token')->plainTextToken;

$response = $this->withHeaders([
'Authorization' => 'Bearer ' . $token,
])->postJson('/api/students', [
'first_name' => 'Jane',
'last_name' => 'Doe',
'email' => '[Link]@[Link]',
]);

$response->assertStatus(201)
->assertJson([
'first_name' => 'Jane',
'last_name' => 'Doe',
'email' => '[Link]@[Link]',
]);

$this->assertDatabaseHas('students', [
'email' => '[Link]@[Link]',
]);
}
}

Run tests:
php artisan test
b. Frontend Testing

Use Jest and Vue Test Utils to write tests for your [Link] components.

Example test for the Login component:

// tests/unit/[Link]

import { shallowMount } from '@vue/test-utils';


import Login from '@/components/Auth/[Link]';
import axios from 'axios';
import flushPromises from 'flush-promises';

[Link]('axios');

describe('[Link]', () => {
it('renders login form', () => {
const wrapper = shallowMount(Login);
expect([Link]('h2').text()).toBe('Login');
expect([Link]('input[type="email"]').exists()).toBe(true);
expect([Link]('input[type="password"]').exists()).toBe(true);
});

it('handles successful login', async () => {


const mockToken = 'test-token';
[Link]({
data: { token: mockToken },
});

const wrapper = shallowMount(Login, {


mocks: {
$router: {
push: [Link](),
},
},
});

[Link]('input[type="email"]').setValue('test@[Link]');
[Link]('input[type="password"]').setValue('password');
[Link]('form').trigger('[Link]');

await flushPromises();

expect([Link]('token')).toBe(mockToken);
expect([Link].$[Link]).toHaveBeenCalledWith('/students');
});

it('displays errors on failed login', async () => {


[Link]({
response: {
data: {
errors: {
email: ['The provided credentials are incorrect.'],
},
},
},
});
const wrapper = shallowMount(Login);
[Link]('input[type="email"]').setValue('wrong@[Link]');
[Link]('input[type="password"]').setValue('wrongpassword');
[Link]('form').trigger('[Link]');

await flushPromises();

expect([Link]).toContain('The provided credentials are


incorrect.');
expect([Link]('.alert').isVisible()).toBe(true);
});
});

Run tests:

npm run test:unit

2. Deployment
a. Deploy Laravel Backend

1. Choose a Hosting Provider: Options include DigitalOcean, AWS, Heroku, Laravel


Forge, etc.
2. Server Setup:
o Install necessary software: PHP, Composer, Nginx/Apache, MySQL, etc.
3. Clone Repository:
o Use Git to clone your project to the server.
4. Install Dependencies:
5. composer install
6. Configure Environment:
o Set up the .env file with production credentials.
7. Run Migrations and Seeders:
8. php artisan migrate --force
9. php artisan db:seed --force
10. Set Permissions:
11. sudo chown -R www-data:www-data /path-to-your-project
12. sudo chmod -R 775 storage
13. sudo chmod -R 775 bootstrap/cache
14. Configure Web Server:
o Set up Nginx or Apache to serve the Laravel application.
15. Set Up SSL:
o Use Let's Encrypt or another provider to secure your application with HTTPS.

b. Deploy [Link] Frontend

1. Choose a Hosting Provider: Options include Netlify, Vercel, AWS Amplify, GitHub
Pages, etc.
2. Build the Vue App:
3. npm run build
4. Deploy the dist Folder:
o Upload the dist folder to your chosen hosting provider.
5. Configure Environment Variables:
o Ensure the Vue app points to the correct backend API URL. You can set this in
environment variables during the build process.
6. Set Up Routing:
o Configure the hosting provider to handle client-side routing (e.g., redirect all routes
to [Link]).

3. Configure CORS for Production

Update config/[Link] in Laravel to allow the production frontend domain:

'allowed_origins' => ['[Link]

Run php artisan config:cache to apply changes.

Conclusion
Creating a student register application using [Link] for the frontend and Laravel for the
backend combines the strengths of both technologies, resulting in a robust, scalable, and user-
friendly system. Laravel handles the server-side logic, API creation, and database
interactions, while [Link] provides a dynamic and responsive user interface. By following
this comprehensive guide, you can develop a full-stack application that efficiently manages
student data with secure authentication, seamless CRUD operations, and a polished user
experience.

Additional Resources:

• Laravel Documentation
• [Link] Documentation
• Laravel Sanctum Documentation
• Axios Documentation
• Vue Router Documentation
• BootstrapVue Documentation

Feel free to explore these resources to deepen your understanding and enhance your
application further.

You might also like