Laravel blade template changing to vue component

12,173

Solution 1

there are many different ways to have vue components in our laravel application. Basic idea is to execute SPA (Single Page Application), I'll tell you how I do it.

Laravel provides basic entry point for our vuejs application. You can see in your webpack.mix.js file. For the routes I use vue-router and rest api for CRUD operation. So you need to do following setup:

npm install
npm install vue-router --save

npm run dev // To compile app.js and store into public folder

In your case I would make a single blade file which will act as entry point for Vue application. I would define in route web.php

Route::get('/{view?}', 'HomeController@landing')->where('view', '(.*)')->name('landing');

In HomeController I'll simply return the blade view

return view('landing')

Now in will make landing.blade.php:

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="utf-8">
        <title>welcome.</title>
        <meta name="description" content="Login Page">
        <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">

        <meta name="csrf-token" content="{{ csrf_token() }}">

    </head>
    <body>

        <div id="website">
        </div>

        <script src="{{ mix('js/app.js') }}"></script>

    </body>
</html>

You have to mention csrf_token() in the meta tag and a div with id so that it can render vue-components over there.

Now I'll create a router file for vuejs will create router.js in resources folder:

import Vue from 'vue';
import VueRouter from 'vue-router';

Vue.use(VueRouter);

export const router = new VueRouter({
    mode: 'history',
    routes:
        [
            {
                path: '/',
                component: Vue.component('welcome', () => import('./components/Welcome.vue')),
                name: 'welcome',
            },
            {
                path: '/roadmap',
                component: Vue.component('roadmap-index', () => import('./components/Roadmap/index.vue')),
                name: 'roadmap.index',
            },

        ],
    base: '/',
});

Rest you can do for Create, Update forms. Now we will configure our app.js file present inside resource folder:

/**
 * First we will load all of this project's JavaScript dependencies which
 * includes Vue and other libraries. It is a great starting point when
 * building robust, powerful web applications using Vue and Laravel.
 */

require('./bootstrap');

import VueRouter from 'vue-router';
import {router} from "./routes";
import welcome from './components/Welcome';

window.Vue = require('vue');

Vue.use(VueRouter);

const layoutOne = new Vue({
    el: '#website',
    router: router,
    render:h=>h(welcome)
});

Then I'll create welcome component which will act as entry point for vue-router, will create a welcome.vue file:

<template>
    <div>
        <router-view></router-view>
    </div>
</template>

<script>
    export default {
        name: "welcome",
    }
</script>

<style lang="scss">


</style>

Now I'll make API's for CRUD operation:

<?php

namespace App\Http\Controllers;
use DB;
use Illuminate\Http\Request;
use App\Roadmap;
use Validator;
use Illuminate\Foundation\Validation\ValidatesRequests;

class RoadmapController extends Controller
{
    /**
     * Display a listing of the resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function index()
    {
        //
        $roadmap = DB::table('roadmaps')->get();

        return response()->json(['roadmap' => $roadmap], 200);

    }

    /**
     * Store a newly created resource in storage.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return \Illuminate\Http\Response
     */
    public function store(Request $request)
    {
        //
        request()->validate([
            'year' =>['required', 'string', 'max:255', 'unique:roadmaps'],
            'body' => ['required', 'string', 'max:255'],
          ]);

          Roadmap::create($request->all());
          return response()->json(['message' => 'Created successfully'], 200);
    }

    /**
     * Display the specified resource.
     *
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function show($id)
    {
        //
        $roadmap = Roadmap::find($id);
        return response()->json(['roadmap` => $roadmap],200);
    }


    /**
     * Update the specified resource in storage.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function update(Request $request, $id)
    {
        //
        request()->validate([
            'year' => 'required',
            'body' => 'required',
          ]);
          Roadmap::find($id)->update($request->all());
          return response()->json(['message' => 'Updated successfully'], 200;;
    }

    /**
     * Remove the specified resource from storage.
     *
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function destroy($id)
    {
        //
        Roadmap::find($id)->delete();
        return response()->json(['message' => 'Deleted'], 200;;
    }

}

I would then make api in api.php

Route::resource('roadmap', 'RoadmapController');

Now only thing left out is calling these api in our component file and executing as per our requirement.

<template>
    <table class="table table-hover">
        <thead class="demo">
        <tr>
            <th>Roadmap</th> //Whatever you have headers
            <th>Update</th>
            <th>Delete</th>
        </tr>
        </thead>
        <tbody>
        <tr v-for="(item, index) in roadmaps">
            <td>{{ item.name }}</td>  // Whatever your data field is
            <td @click="update(item)">Update</td>
            <td @click="delete(item)"> Delete</td>
        </tr>
    </table>
</template>

<script>
    export default {
        data() {
            return: {
                roadmaps: [],
                errors: ''
            }
        },
        methods: {
            fetchData() {
                axios.get('api/roadmap).then(response => {
                    if(response.status === 200)
                    {
                        this.roadmaps = response.data
                    }
                }).catch((error) => {
                    this.errors = error.response.data
                })
            },
            update(item) {
                this.$router.push({ name: update, params: { id: item.id}})
            },
            delete(item) {
                axios.delete('api/roadmap/'+item.id).then(response => {
                    if(response.status === 200)
                    {
                        this.fetchData()  // to refresh table..
                    }
                }).catch((error) => {
                    this.errors = error.response.data
                })
            }
        }
        created() {
            this.fetchData()
        }
    }
</script>

I hope you get a basic idea to execute things on your own. There are lot of tutorials which can be found:

https://laravel-news.com/using-vue-router-laravel

Hope this helps. Cheers.

PS: You have to keep compiling via npm run dev or npm run watch after you finish coding vue-component. Code may not work or might have bugs. This is only to give you direction to start through.

Solution 2

Don't know if its help you or not , but i am sharing my thoughts.

  1. add js file in laravel webpack
  2. in js file add your component
  3. in component add your code for @foreach you can use v-for="data in roadmap"

    <tr v-for="data in roadmap">
       <td> {{ data.id }}</td>
       <td> {{ data.year }}</td>
    <td>
    <a :href="'/roadmap/'+ data.id +'/edit'" class="btn btn-warning">
     <span class="glyphicon glyphicon-pencil"></span>
    </a>
    </td>
    </tr>
    
  4. for controller index function:

        if($request->ajax()){
            $roadmap = DB::table('roadmaps')->get();
            return response()->json($roadmap, 200);
        }
    
        return view('roadmap.index');
    
  5. to submit form you can add methods on click buttons.

let me know if their any lack of understanding. i will update my answer

Share:
12,173

Related videos on Youtube

draw134
Author by

draw134

Noob web developer..

Updated on June 04, 2022

Comments

  • draw134
    draw134 almost 2 years

    So I just recently finished my project using only laravel framework. Now that I've finished working on it, I want to add vue.js into my project by making the content refresh without refreshing the layout page. And also I want to convert my blade files into vue components. And I don't know how to do it because in every section in my project, I have 4 blade files like index,edit,create,show and I don't know how to do make that in the component and it is difficult to me because I'm using laravel collective form that's why it refreshes every-time I add some entry into the database. Im also new to vuejs. Can someone help me out of this? Thanks a lot.

    My folder directory is like this.

    -roadmap
    ---index.blade.php
    ---show.blade.php
    ---edit.blade.php
    ---create.blade.php
    

    Here are some of my codes.

    roadmap/index.blade.php

    @extends('layouts.admin')
    
    
    
    
    @section('content')
    
    <meta name="csrf-token" content="{{ csrf_token() }}">
    <!-- DATA TABLES -->
    <script src="//code.jquery.com/jquery-1.12.3.js"></script>
    <script src="//cdn.datatables.net/1.10.12/js/jquery.dataTables.min.js"></script>
    <script src="https://cdn.datatables.net/1.10.12/js/dataTables.bootstrap.min.js"></script>
    <link rel="stylesheet"href="https://cdn.datatables.net/1.10.12/css/dataTables.bootstrap.min.css">
    
    
    <div><a class="btn btn-success" style="float:right" href="{{ route('roadmap.create') }}">Add Roadmap</a></div>
    
    <table id="myTable" class="table table-hover">
        <thead>
          <tr>
            <th scope="col">ID</th>
            <th scope="col">Year Covered </th>
            <th scope="col">Description</th>
            <th scope="col">Date entered</th>
    
    
    
            <th width="280px">Action</th>
          </tr>
        </thead>
        <tbody>
            @foreach ($roadmap as $data)
            <tr>
               <td>{{ $data->id }}</td>
               <td>{{ $data->year}}</td>
               <td>{{ $data->body}}</td>
               <td>{{ $data->created_at}}</td>
    
    
            <td>
    
            <a href="/roadmap/{{$data->id}}/edit" class="btn btn-warning"><span class="glyphicon glyphicon-pencil"></span></a>
    
            <a href="/roadmap/{{$data->id}}" class="btn btn-primary"><span class="glyphicon glyphicon-search"></span></a>
    
            {!! Form::open(['method' => 'DELETE', 'route'=>['roadmap.destroy', $data->id], 'style'=> 'display:inline', 'onsubmit' => 'return confirm("Are you sure you want to delete?")']) !!}
            {!! Form::button('<i class="fa fa-trash"></i>',['type'=>'submit', 'class'=> 'btn btn-danger']) !!}
            {!! Form::close() !!}</td>
    
    
            </tr>
            @endforeach
        </tbody>
      </table>
    
      <script>
        $(document).ready(function() {
          $('#myTable').DataTable();
    
      } );
       </script>
    
    
    
    
    @endsection
    
    

    RoadmapController.php

    <?php
    
    namespace App\Http\Controllers;
    use DB;
    use Illuminate\Http\Request;
    use App\Roadmap;
    use Validator;
    use Illuminate\Foundation\Validation\ValidatesRequests;
    
    class RoadmapController extends Controller
    {
        /**
         * Display a listing of the resource.
         *
         * @return \Illuminate\Http\Response
         */
        public function index()
        {
            //
            $roadmap = DB::table('roadmaps')->get();
    
            return view('roadmap.index', ['roadmap' => $roadmap]);
    
        }
    
        /**
         * Show the form for creating a new resource.
         *
         * @return \Illuminate\Http\Response
         */
        public function create()
        {
            //
            return view('roadmap.create');
        }
    
        /**
         * Store a newly created resource in storage.
         *
         * @param  \Illuminate\Http\Request  $request
         * @return \Illuminate\Http\Response
         */
        public function store(Request $request)
        {
            //
            request()->validate([
                'year' =>['required', 'string', 'max:255', 'unique:roadmaps'],
                'body' => ['required', 'string', 'max:255'],
              ]);
    
              Roadmap::create($request->all());
              return redirect()->route('roadmap.index')->with('success','Created successfully');
        }
    
        /**
         * Display the specified resource.
         *
         * @param  int  $id
         * @return \Illuminate\Http\Response
         */
        public function show($id)
        {
            //
            $roadmap = Roadmap::find($id);
            return view('roadmap.show', compact('roadmap'));
        }
    
        /**
         * Show the form for editing the specified resource.
         *
         * @param  int  $id
         * @return \Illuminate\Http\Response
         */
        public function edit($id)
        {
            //
            $roadmap = Roadmap::find($id);
            return view('roadmap.edit', compact('roadmap'));
        }
    
        /**
         * Update the specified resource in storage.
         *
         * @param  \Illuminate\Http\Request  $request
         * @param  int  $id
         * @return \Illuminate\Http\Response
         */
        public function update(Request $request, $id)
        {
            //
            request()->validate([
                'year' => 'required',
                'body' => 'required',
              ]);
              Roadmap::find($id)->update($request->all());
              return redirect()->route('roadmap.index')->with('success',' Updated successfully');
        }
    
        /**
         * Remove the specified resource from storage.
         *
         * @param  int  $id
         * @return \Illuminate\Http\Response
         */
        public function destroy($id)
        {
            //
            Roadmap::find($id)->delete();
            return redirect()->route('roadmap.index')->with('success','News deleted successfully');
        }
    
    }
    
    

    web.php

    //CRUD COLLECTIVE ROADMAP
        Route::resource('roadmap', 'RoadmapController');
    
    • Emtiaz Zahid
      Emtiaz Zahid over 4 years
      do you know how to use components in blade ?
    • draw134
      draw134 over 4 years
      I do know a little sir but im confused if I should create 4 components in vue like create,index ect.. I only know how to render my component in the blade file by creating a <component-name> and some little CRUD axios. Also im confused if @foreach will work in my component since im passing the data to my views using the compact function in my controller
  • draw134
    draw134 over 4 years
    thanks a lot for the answer sir. i will try to understand it first then i will apply it to my codes.
  • draw134
    draw134 over 4 years
    thanks a los for the answer sir. I will try to understand it and then i will try it to my project. <3
  • draw134
    draw134 over 4 years
    Sir i have a question, why do i need to use api.php route? I cant use my route for the resource in my web.php
  • Nitish Kumar
    Nitish Kumar over 4 years
    Yes you can, but if you check your app\http\kernel.php there are lot of middlewares which are helpful for REST API which are not mentioned in our web.php middleware.
  • draw134
    draw134 over 4 years
    Okay sir. But i have this one thing bothers me, where should i create the views for create,show ect..? do i have to make another component for this like show.blade.vue? or maybe ill make a modal and insert the code in my vue component?
  • Nitish Kumar
    Nitish Kumar over 4 years
    As you can see I have router.js file which has URL configuration, ie when I call URL that particular component will be called. It is same like having a blade file and displaying via routes. Here you have update.vue component and routes are defined as I have mentioned over there.
  • draw134
    draw134 over 4 years
    hmmm. i find it hard to understand a bit sir but let me tell you my understanding about it. So do you mean I will create multiple components for edit, show and create? then I will use the vue router to call that evety component? my problem is how could i extend it in the @section('content')? can extend it directly in the component or should i put the <component-name> in my section content ?
  • Nitish Kumar
    Nitish Kumar over 4 years
    I know its bit difficult to understand for first time. That is why I told you there are lot of tutoarial available. Just search for Single page Application (SPA) with Laravel and Vuejs. You will get plenty of stuff which will clear all your doubts.