Bilal Ünal

Laravel ve Vue.js

Merhaba. Şu yazımda belirttiğim gibi bu aralar laravel kullanarak bir proje geliştiriyorum. Projenin bir yönetim paneli bulunuyor ve bu panel üzerinden veri tabanındaki veriler listelenebiliyor, düzenlenebiliyor, silinebiliyor. Bu işlemlerin her biri ayrı sayfalarda gerçekleştiriliyor. Bu işlemleri tek bir sayfada nasıl toplayabilirim diye araştırırken karşıma Vue.js çıktı. Vue.js frontend tarafında kullanılan bir Javascript librarysi. Son zamanlarda baya popüler olan bu kütüphane, githubda en çok “star”lanan repo listesinde 6. sırada bulunuyor. Yaklaşık 3-4 haftadır ben de vue.js kullanarak yerelimde bir şeyler yapıyorum. Bu yazıda da laravel ve vue.js kullanarak tek bir sayfa üzerinde nasıl CRUD işlemleri yapabileceğimizden bahsedeceğim.

Geliştirme Ortamının Hazırlanması

Örnek üzerinden ilerlemenin daha yararlı olduğunu düşünüyorum. Örnek olarak bir yapılacaklar sayfası oluşturalım. Sayfa üzerinde bir tabloda yapılacak işleri görüntüleyelim. Tablonun yanında bir form olsun. Form ile de yapılacak işleri ekleyelim.

Hızlı bir şekilde laravel geliştirme ortamı oluşturmak için aşağıdaki komutları sırası ile çalıştıralım.

laravel new laravue
cd laravue
composer install
yarn install
cp .env.example .env
php artisan key:generate
php artisan config:clear  
php artisan config:cache

Laravel installer ve yarn paktleri yüklü değilse npm kullanabilirsiniz.

Yapılacaklar sayfası için öncelikle veritabanında bir tabloya ihtiyacımız var. Bunun için bir öncelikle yeni bir veri tabanı oluşturalım.

$ mysql -u root -p
mysql> CREATE DATABASE laravue CHARACTER SET utf8 COLLATE utf8_general_ci;

Veritabanımızı oluşturduktan sonra .env dosyamızda bağlantı için gerekli düzenlemeleri yapalım.

DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=laravue
DB_USERNAME=root
DB_PASSWORD=

Düzenlemeleri yaptıktan sonra “php artisan migrate:status” ile bağlantınızı test edebilirsiniz.

Geliştirme

Tablomuz için migrationu, modeli ve controlleri oluşturualım. Bunun için tek bir komut yeterli.

php artisan make:model Task -mr

Oluşturulan migrationu aşağıdaki şekilde düzenleyelim;

<?php

public function up()
{
    Schema::create('tasks', function (Blueprint $table) {
        $table->increments('id');
        $table->string('title');
        $table->timestamps();
    });
}

Mass asignment hatasından kaçmak için Task modelimize şu satırı ekleyelim;

app/Task.php

protected $guarded = [];

Tabloları oluşturalım.

php artisan migrate

SQLSTATE[42000]: Syntax error or access violation: 1071 Specified key was too long; max key length is 767 bytes

şeklinde bir hata ile karşılaşırsanız şu şekilde çözebilirsiniz.

app/Providers/AppServiceProvider.php içerisindeki boot fonksiyonunu şu şekilde değiştirelim.

<?php
namespace App\Providers;
use Illuminate\Support\ServiceProvider;
use Illuminate\Support\Facades\Schema;
class AppServiceProvider extends ServiceProvider
{
    /**
    * Bootstrap any application services.
    *
    * @return void
    */
    public function boot()
    {
        Schema::defaultStringLength(191);
    }
    /**
    * Register any application services.
    *
    * @return void
    */
    public function register()
    {
        //
    }
}

Eğer hatayı aldıysanız düzgün bir şekilde migrate işlemini yapamadınız demektir. Veri tabanı içerisinde oluşturulan tüm tabloları silip yukarıdaki değişiklikleri yaptıktan sonra tekrar migrate yapmayı deneyin.

Migrate yaptıktan sonra route tanımı yapmamız gerekiyor.

routes/web.php dosyasına aşağıdaki satırları ekleyelim.

<?php
Route::resource('tasks', 'TaskController');
Route::get('/', function () {
    return view('welcome');
});

Route tanımını da yaptıktan sonra daha önce oluşturduğumuz TaskController sınıfındaki metodlarımızın içlerini dolduralım.

<?php

namespace App\Http\Controllers;

use App\Task;
use Illuminate\Http\Request;

class TaskController extends Controller
{
    /**
    * Display a listing of the resource.
    *
    * @return \Illuminate\Http\Response
    */
    public function index()
    {
        return Task::all();
    }

    /**
    * Show the form for creating a new resource.
    *
    * @return \Illuminate\Http\Response
    */
    public function create()
    {
        //
    }

    /**
    * Store a newly created resource in storage.
    *
    * @param  \Illuminate\Http\Request  $request
    * @return \Illuminate\Http\Response
    */
    public function store(Request $request)
    {
        $request->validate([
            'title' => 'required|max:500'
        ]);
        return Task::create([ 'title' => request('title') ]);
    }

    /**
    * Display the specified resource.
    *
    * @param  \App\Task  $task
    * @return \Illuminate\Http\Response
    */
    public function show(Task $task)
    {
        //
    }

    /**
    * Show the form for editing the specified resource.
    *
    * @param  \App\Task  $task
    * @return \Illuminate\Http\Response
    */
    public function edit(Task $task)
    {
        //
    }

    /**
    * Update the specified resource in storage.
    *
    * @param  \Illuminate\Http\Request  $request
    * @param  \App\Task  $task
    * @return \Illuminate\Http\Response
    */
    public function update(Request $request, Task $task)
    {
        //
    }

    /**
    * Remove the specified resource from storage.
    *
    * @param  \App\Task  $task
    * @return \Illuminate\Http\Response
    */
    public function destroy(Task $task)
    {
        $task->delete();
        return 200;
    }
}

Backend tarafında her şey hazır. Şimdi Vue.js ve tasarım kısımlarını tamamlayalım. Öncelikle yeni bir terminal penceresi açıp projenin içerisinde “yarn watch” komutunu çalıştırıyoruz. Ardından giriş sayfamız olan welcome blade templateini düzenliyoruz.

resources/views/welcome.blade.php

<!doctype html>
<html lang="{{ app()->getLocale() }}">
    <head>
        <meta charset="utf-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <title>Laravel Vue Task App</title>
        <!-- CSRF Stuff -->
        <meta name="csrf-token" content="{{ csrf_token() }}">
        <script>window.Laravel = { csrfToken: '{{ csrf_token() }}' }</script>
        <!-- Fonts -->
        <link href="https://fonts.googleapis.com/css?family=Raleway:100,600" rel="stylesheet" type="text/css">
        <!-- Styles -->
        <link rel="stylesheet" href="{{ asset('css/app.css') }}">
</head>
<body>
        <div class="container" id='app'>
            <h2>Yapılacaklar Listesi</h2>
            <tasks></tasks>
        </div>
        <!-- Scripts -->
        <script src="{{ asset('js/app.js') }}"></script>
    </body>
</html>

app idsi ile bir div oluşturduk. bu selector app.js dosyası içerisinden değiştirilebilir. app.js dosyamızı componentimizi ekleyelim.

resources/js/app.js

Vue.component('tasks', require('./components/TaskComponent.vue'));

Şimdi blade dosyamız içerisinde çağırdığımız vue componentini oluşturalım.

resources/assets/js/components/TasksComponent.vue

<template>
    <div class="row">
        <div class="col-md-6">
            <table class="table">
                <thead>
                    <tr>
                    <th scope="col">#</th>
                    <th scope="col">Başlık</th>
                    <th scope="col">İşlem</th>
                    </tr>
                </thead>
                <tbody>
                    <tr v-for="task in taskList">
                        <th scope="row">{{ task.id }}</th>
                        <td>{{ task.title }}</td>
                        <td><button @click="deleteTask(task.id)" type="button" class="btn btn-danger">Sil</button></td>
                    </tr>
                </tbody>
            </table>
        </div>
        <div class="col-md-6">
            <form action="#" @submit.prevent="createTask()">
                <div class="form-group">
                    <label for="taskTitle">Yapılacak işin başlığı</label>
                    <input v-model="newTask.title" type="text" class="form-control" id="taskTitle" placeholder="Başlık">
                </div>
                <button type="submit" class="btn btn-primary">Ekle</button>
            </form>
        </div>
    </div>
</template>
<script>
    export default {
        data() {
            return {
                newTask: {
                    title: ''
                },
                taskList: []
            };
        },

        created() {
            this.getTasks();
        },

        methods: {
            getTasks() {
                axios.get('/tasks').then((res) => {
                    this.taskList = res.data;
                });
            },
            createTask() {
                axios.post('/tasks', this.newTask).then((res) => {
                    this.newTask.title = '';
                    this.getTasks();
                });
                    
            },
            deleteTask(id) {
                axios.delete('/tasks/' + id).then((res) => {
                    this.getTasks();
                });
            }
        },
    }
</script>

Sonuç

Frontend kısmını da bitirdikten sonra yeni bir terminal penceresinde “php artisan serve” yazarak uygulamamızı 8000 portunda ayağa kaldırıyoruz.

Eğer her şeyi doğru yaptıysanız “localhost:8000” adresine girdiğinizde uygulamayı görüntüleyip kullanabilmeniz gerekiyor.

Projenin benzerine https://github.com/bilalunalnet/task-list adresinden ulaşabilirsiniz. İyi günler.