How To Create User Profile Using Vuejs And Laravel

admin_img Posted By Bajarangi soft , Posted On 27-11-2020

We create and update user profile using vuejs and laravel

How To Create User Profile Using Vuejs And Laravel

Let's learn

1.Install new laravel project to implement code. https://laravel.com/docs/5.8/installation

composer create-project --prefer-dist laravel/laravel blog

run above command in command prompt.

2.Install node.js package for blog project . click here to download it.
3.Install npm package for blog project.
click here to see the documentation.Install the dependencies in the local node_modules folder.

npm install

run above command in terminal.
4.Connect between database and blog project.

DB_DATABASE=VUEjs
DB_USERNAME=root
DB_PASSWORD=

5.Create header.vue file in blog/resource/js/components/ folder and implement as below.

<template>

    <nav id="sidebar" class="sidebar-wrapper">
        <div class="sidebar-content">
            <div class="sidebar-brand">
                <a href="#">Vuejs demo</a>
                <div id="close-sidebar" @click="closemenu">
                    <i class="fa fa-list"></i>
                </div>
            </div>
            <div class="sidebar-header">
                <div class="user-pic">
                    <img class="img-responsive img-rounded" src="https://raw.githubusercontent.com/azouaoui-med/pro-sidebar-template/gh-pages/src/img/user.jpg" alt="User picture">
                </div>
                <div class="user-info">
          <span class="user-name">admin
          </span>
                    <span class="user-role">Administrator</span>
                    <span class="user-status">
            <i class="fa fa-circle"></i>
            <span>Online</span>
          </span>
                </div>
            </div>
            <!-- sidebar-header  -->

            <!-- sidebar-search  -->
            <div class="sidebar-menu">
                <ul>
                    <li>
                        <router-link to="/example"><i class="fa fa-book"></i>
                            <span>example</span></router-link>
                    </li>
                    <li>
                        <router-link to="/profile"><i class="fa fa-book"></i>
                            <span>profile</span></router-link>
                    </li>
                </ul>
            </div>
            <!-- sidebar-menu  -->
        </div>
        <!-- sidebar-content  -->

    </nav>
</template>

<script>
    export default {
        methods:{
            closemenu(){
                $(".page-wrapper").removeClass("toggled");
            }
        },

    }
</script>

6.Create footer.vue file in blog/resource/js/components/ folder and implement as below.
<template>
    <footer class="text-center bg-dark">
        <div class="mb-2">
            <small class="text-white">
                © 2020 made with <i class="fa fa-heart" style="color:red"></i>
            </small>
        </div>


    </footer>
</template>
<style scoped>
    footer{
        position: fixed;
        bottom: 0;
        width: 100%;
    }
</style>

7.Create welcome.vue file in blog/resource/js/components/ folder and implement as below to include header and footer vue files in it.
<template>
    <div class="page-wrapper chiller-theme toggled">
        <a id="show-sidebar" class="btn btn-sm btn-dark" href="#" @click="openmenu">
            <i class="fa fa-close"></i>
        </a>
        <addheader></addheader>

        <main class="page-content">

            <router-view/>
        </main>
        <addfooter></addfooter>
        <!-- page-content" -->
    </div>
    <!-- page-wrapper -->
</template>

<script>

    Vue.component('addheader',require('./header.vue').default);
    Vue.component('addfooter',require('./footer.vue').default);
    export default {
        mounted() {
            console.log('Component mounted.')
        },
        methods:{
            openmenu(){
                $(".page-wrapper").addClass("toggled");
            }
        }
    }
</script>

8.Create profile.vue file in blog/resource/js/components/ folder and implement as below .
<template>
    <div class="container">
        <div class="row justify-content-center" @editdata="refreshRecord">
            <div class="col-md-12 text-center ">
                <div class="panel panel-default">
                    <div class="userprofile social " >
                        <div class="userpic">
                            <label v-if="!image" class="btn btn-default display-inline">
                                <img :src="getPhoto"  alt=""  class="userpicimg"/>
                            </label>
                            <div class="hidden display-inline align-center" v-else v-bind:class="{ 'image': true }">

                                <img :src="image"  alt="" class="userpicimg">
                            </div>

                        </div>
                        <h3 class="username">{{record.name}}</h3>
                        <p>Banglore, India</p>
                        <div class="socials text-center"><a href="" class="btn btn-circle btn-primary ">
                            <i class="fa fa-facebook"></i></a> <a href="" class="btn btn-circle btn-danger ">
                            <i class="fa fa-google-plus"></i></a> <a href="" class="btn btn-circle btn-info ">
                            <i class="fa fa-twitter"></i></a> <a href="" class="btn btn-circle btn-warning "><i class="fa fa-envelope"></i></a>
                        </div>
                    </div>
                    <div class="col-md-12 border-top border-bottom" >
                        <ul class="nav nav-pills pull-left countlist" role="tablist">
                            <li role="presentation">
                                <h3>1452<br>
                                    <small>Follower</small> </h3>
                            </li>
                            <li role="presentation">
                                <h3>245<br>
                                    <small>Following</small> </h3>
                            </li>
                            <li role="presentation">
                                <h3>5000<br>
                                    <small>Activity</small> </h3>
                            </li>
                        </ul>
                    </div>
                    <button class="btn btn-primary followbtn " >Follow</button>
                    <div class="clearfix"></div>
                </div>
            </div>



            <div class="col-md-12 ">
                <div class="card">
                    <div class="card-header p-2">
                        <h3>Edit Profile</h3>
                    </div><!-- /.card-header -->
                    <div class="card-body" >
                        <form class="form-horizontal">
                            <div class="form-group row">
                                <label for="inputName" class="col-sm-2 col-form-label">Name</label>
                                <div class="col-sm-10">
                                    <input type="name" class="form-control" id="inputName" placeholder="Name" v-model="record.name">
                                </div>
                            </div>
                            <div class="form-group row">
                                <label for="inputEmail" class="col-sm-2 col-form-label">Email</label>
                                <div class="col-sm-10">
                                    <input type="email" class="form-control" id="inputEmail" placeholder="Email" v-model="record.email">
                                </div>
                            </div>
                            <div class="form-group row">
                                <label for="inputEmail" class="col-sm-2 col-form-label">Experience</label>
                                <div class="col-sm-10">
                                    <textarea type="email" class="form-control"  placeholder="Experience" v-model="record.experience"></textarea>
                                </div>
                            </div>
                            <div class="form-group row">
                                <label  class="col-sm-2 col-form-label" >Profile</label>
                                <div class="col-sm-10">
                                    <input type="file"  placeholder="Name" v-on:change="onImageChange">
                                </div>
                            </div>
                            <div class="form-group row">
                                <div class="offset-sm-2 col-sm-10">
                                    <button type="submit" class="btn btn-success" @click="uploadImage">Update</button>
                                </div>
                            </div>
                        </form>
                    </div>
                </div>
            </div>

        </div>
    </div>

</template>

<script>
    import Vue from 'vue';
    import VueToast from 'vue-toast-notification';
    // Import one of available themes
    import 'vue-toast-notification/dist/theme-default.css';
    //import 'vue-toast-notification/dist/theme-sugar.css';

    Vue.use(VueToast);
    Vue.$toast.open('You did it!');
    Vue.$toast.open({/* options */});

    // Close all opened toast immediately
    Vue.$toast.clear();
    export default {
        data(){
            return{
                record:[],//objects
                image: ''
            }
        },
        computed: {
            getPhoto() {
                return 'http://localhost/Forumvuejs/public/users/image/' + this.record.profile;
            },
        },
        methods:{
            onImageChange(e) {
                let files = e.target.files || e.dataTransfer.files;
                if (!files.length)
                    return;
                this.createImage(files[0]);
            },
            createImage(file) {
                let reader = new FileReader();
                let vm = this;
                reader.onload = (e) => {
                    vm.image = e.target.result;
                };
                reader.readAsDataURL(file);
            },
            refreshRecord(record){
                this.record=record.data
            },
            uploadImage(){
                axios.post('http://localhost/blog/public/Profileupdate/'+this.record.id,{
                    'name':this.record.name,
                    'email':this.record.email,
                    'profile':this.image,
                    '_method':'PUT',
                })
                    .then(data =>{
                        this.$emit('insertdata',data);
                        this.$emit('editdata',data);
                        this.success= "Profile Updated  Successfully!!";
                    })
                    .catch(error =>{
                        this.error = error.response.data.errors.name;
                    });
                this.error=[];
                Vue.$toast.open('Profile Updated  Successfully!!');
            },

        },
        created() {
            axios.get('http://localhost/Forumvuejs/public/Profile')
                .then((response)=>this.record=response.data)
                .catch((error)=>console.log(error));
            console.log('Profile Component loaded.');
        }
    }
</script>
<style scoped>
    .userpicimg{
        border-radius: 50%;
        width:200px
    }
    .countlist h3 {
        margin: 0;
        font-weight: 400;
        line-height: 28px;
    }
    .countlist {
        text-transform: uppercase
    }
    .countlist li {
        padding: 15px 30px 15px 0;
        font-size: 14px;
        text-align: left;
    }
    .countlist li small {
        font-size: 12px;
        margin: 0
    }
    .followbtn {
        float: right;
        margin: 22px;
    }
    .userprofile.social {
        background: url(http://www.bootdey.com/img/Content/flores-amarillas-wallpaper.jpeg) no-repeat top center;
        background-size: 100%;
        padding: 50px 0;
        margin: 0
    }
    .userprofile.social .username {
        color: #ffffff
    }
    .userprofile.social .username+p {
        color: #ffffff;
        opacity: 0.8
    }

    .member img {
        width: 100%;
        transition: 0.5s ease all;
    }
    .member:hover img {
        opacity: 0.8;
        transform: scale(1.2)
    }

    .panel-default>.panel-heading {
        color: #607D8B;
        background-color: #ffffff;
        font-weight: 400;
        font-size: 15px;
        border-radius: 0;
        border-color: #e1eaef;
    }

    .btn-circle {
        width: 30px;
        height: 30px;
        padding: 6px 0;
        border-radius: 15px;
        text-align: center;
        font-size: 12px;
        line-height: 1.428571429;
    }

</style>

9.Now Create function to update profile image in home controller.
<?php

namespace App\Http\Controllers;

use App\User;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Facades\Input;
use Intervention\Image\ImageManagerStatic as Image;
class HomeController extends Controller
{
    /**
     * Create a new controller instance.
     *
     * @return void
     */
    public function __construct()
    {
        $this->middleware('auth');
    }

    /**
     * Show the application dashboard.
     *
     * @return \Illuminate\Contracts\Support\Renderable
     */
    public function index()
    {
        return view('home');
    }

    public function Profile()
    {
        $user=User::whereId(auth()->id())->first();
        return request()->json(200,$user);

    }

    public function Profileupdate($id ,Request $request)
    {
        $exploded=explode(',',$request->profile);
        $decoded=base64_decode($exploded[1]);
        if(str_contains($exploded[0],'jpeg')){
            $extension='jpg';
        }else{
            $extension='png';
        }
        $filename=time().'.'.$extension;
        $path =public_path('users/image').'/'.$filename;
        file_put_contents($path,$decoded);
        $Input = [];

        $Input['profile'] = $filename;

        $user= User::where('id',$id)->update(['name' => $request->name, 'email' => $request->email,'profile'=>$Input['profile']]);

        return request()->json(200,$user);
    }
   
}

10.create route in web.php

Route::get('/Profile', 'HomeController@Profile')->name('Profile');
Route::put('/Profileupdate/{id}', 'HomeController@Profileupdate')->name('Profileupdate');

11.Now include welcome.vue and profile.vue file in resource/js/app.js file
/**
 * 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');

window.Vue = require('vue');

import VueRouter from 'vue-router'
Vue.use(VueRouter)
import Vue from 'vue';
import VueToast from 'vue-toast-notification';
// Import one of available themes
import 'vue-toast-notification/dist/theme-default.css';
//import 'vue-toast-notification/dist/theme-sugar.css';

Vue.use(VueToast);
Vue.$toast.open('You did it!');
Vue.$toast.open({/* options */});

// Close all opened toast immediately
Vue.$toast.clear();
/**
 * The following block of code may be used to automatically register your
 * Vue components. It will recursively scan this directory for the Vue
 * components and automatically register them with their "basename".
 *
 * Eg. ./components/ExampleComponent.vue -> <example-component></example-component>
 */

// const files = require.context('./', true, /\.vue$/i);
// files.keys().map(key => Vue.component(key.split('/').pop().split('.')[0], files(key).default));

// Vue.component('example-component', require('./components/ExampleComponent.vue').default);


const example = require('./components/ExampleComponent.vue').default;
const welcome = require('./components/welcome.vue').default;
const profile = require('./components/profile.vue').default;




const routes=[
    {
        path: '/',
        component: welcome,
        children: [
            // UserHome will be rendered inside User's <router-view>
            // when /user/:id is matched
            {
                path: '/example',
                component: example
            },
            {
                path: '/profile',
                component: profile
            },


        ]
    },



];
const router=new VueRouter({
    routes
});
const app = new Vue({
    el: '#app',
    router,
    data:{

    }
});

12.Now to display vue file implament code in home.blade.php and welcome.blade.php
home.blade.php
<!DOCTYPE html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
    <head>
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width, initial-scale=1">

        <title>Laravel</title>

        <!-- Fonts -->
        <link href="https://fonts.googleapis.com/css?family=Nunito:200,600" rel="stylesheet">

        <!-- Styles -->
        <style>
            html, body {
                background-color: #fff;
                color: #636b6f;
                font-family: 'Nunito', sans-serif;
                font-weight: 200;
                height: 100vh;
                margin: 0;
            }

            .full-height {
                height: 100vh;
            }

            .flex-center {
                align-items: center;
                display: flex;
                justify-content: center;
            }

            .position-ref {
                position: relative;
            }

            .top-right {
                position: absolute;
                right: 10px;
                top: 18px;
            }

            .content {
                text-align: center;
            }

            .title {
                font-size: 84px;
            }

            .links > a {
                color: #636b6f;
                padding: 0 25px;
                font-size: 13px;
                font-weight: 600;
                letter-spacing: .1rem;
                text-decoration: none;
                text-transform: uppercase;
            }

            .m-b-md {
                margin-bottom: 30px;
            }
        </style>
    </head>
    <body>
        <div class="flex-center position-ref full-height">
            @if (Route::has('login'))
                <div class="top-right links">
                    @auth
                        <a href="{{ url('/home') }}">Home</a>
                    @else
                        <a href="{{ route('login') }}">Login</a>

                        @if (Route::has('register'))
                            <a href="{{ route('register') }}">Register</a>
                        @endif
                    @endauth
                </div>
            @endif
    </body>
</html>

welcome.blade.php

@extends('layouts.app')

@section('content')
    <router-view></router-view>
@endsection
 

13.Run command npm run watch.

npm run dev  active and  updates only when you run command.
npm run watch does the same, but then it stays active and "watches" for updates.vue and .js files. If it detects a change so you can just refresh the page.



14.Now run below url in google chrome.

http://localhost/blog/public/

Related Post