Hello artisan, in this tutorial, i will show you how we can create a simple twitter application using laravel 8 and vue js. In this tutorial i will also show you how to create follow-unfollow system in laravel using vue js.
I am using Axios to send a http request. We simply build an application in which, the user can post the tweet and appears in his timeline. Also, one user can follow or unfollow each other.
If currently signed in user follow any other registered user then he can also see the following user’s tweet in his timeline. The very basic app, but the very powerful web app to understand laravel and vue.js fundamental concepts.
In this laravel vue tutorial we will create simple Twitter app with follow unfollow system. A user can follow another user and after logged in he can post a tweet.
I am putting this Laravel and vue example project on github so you can check it out there. Git repository for this project
Preview :
Preview after hitting follow button :
Preview of timelineComponent :
Step 1: Install Laravel.
Type the following command in the terminal.
composer create-project --prefer-dist laravel/laravel TwitterApp
now type bellow command to go to this directory
cd twitterApp
Step 2: Install npm
Install the front-end dependencies using the following command.
npm install
Create an authentication using the following command.
composer require laravel/ui --dev
php artisan ui vue --auth
Now when user logged in then he can see the home.blade,php page. So we need to thing in this page.
resources/views/home.blade.php
Now go to this URL:
localhost:8000/home
and you can see the changes.
Step 3: Create tweet form
Write the following code inside FormComponent.vue file.
resources/js/components/FormComponent.vue
Import this component inside app.js file.
resources/js/app.js
require('./bootstrap');
window.Vue = require('vue');
Vue.component('example-component', require('./components/ExampleComponent.vue').default);
//Twitter Component
Vue.component('form-component', require('./components/FormComponent.vue').default);
const app = new Vue({
el: '#app',
});
Also, we need to add this component inside a home.blade.php file.
resources/views/home.blade.php
Step 4: Create Post Model
Okay, now create a model and migration.
php artisan make:model Post -m
Write the following schema inside a create_posts_table.php file.
public function up()
{
Schema::create('posts', function (Blueprint $table) {
$table->bigIncrements('id');
$table->unsignedBigInteger('user_id');
$table->string('body', 130);
$table->timestamps();
$table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
});
}
Migrate the posts table.
php artisan migrate
Step 5: Create PostController
Also, we need to create a PostController. So create a controller by the following command.
php artisan make:controller PostController
Step 6: Define the relationships.
Inside User.php model, we need to define a function that is a relationship between Post model and User model.
// User.php
public function posts()
{
return $this->hasMany(Post::class);
}
Also, the Post belongs to User. So we can define the inverse relationship inside Post.php model.
// Post.php
public function user()
{
return $this->belongsTo(User::class);
}
Step 7: Save Tweet in the database.
When we have used the command npm install, it has already install axios library. So we can use the axios to send a POST request to a Laravel backend web server and store the tweet in the database.
routes/web.php
Route::post('tweet/save', 'PostController@store');
Also, we need to define the $fillable property inside Post.php model to prevent the Mass Assignment Exception.
app/Post.php
protected $guarded = [];
The final thing is to define the store function inside PostController.php file.
app/Http/Controllers/PostController.php
namespace App\Http\Controllers;
use App\Post;
use Illuminate\Http\Request;
class PostController extends Controller
{
public function store(Request $request, Post $post)
{
$newPost = $request->user()->posts()->create([
'body' => $request->body
]);
return response()->json($post->with('user')->find($newPost->id));
}
}
Read also : User Roles and Permissions Tutorial in Laravel without Packages
Also, we need to use axios library to send a POST request, so write the code inside FormComponent.vue file.
resources/js/components/FormComponent.vue
Step 8: Create a vue event.
To display all the tweets on the frontend, we need to first show the tweets to the Timeline, and for that, we need to create an event. Remember, we are not refreshing the page to fetch all the tweets. When we add a new tweet, we need to display that tweet in the user’s timeline without refresh the page.
We can also use Vuex for this, but right now, we are not diving into Stores and actions, let us keep it simple.
resources/js/app.js
//Events
let Event = new Vue()
window.Event = Event;
Now make an Event in FormComponet.vue
resources/js/components/FormComponent.vue
So, when the new post is saved, we can emit an event that has the saved tweet with the user.
Step 9: Create a Timeline Component.
resources/js/components/TimelineComponent.vue
So, we are listening for that event, and when the event is listened by this component, we add the new data to the posts array and iterate the component to display the tweet and user as well. Now, register this component inside an app.js file.
resources/js/app.js
Vue.component('timeline-component', require('./components/TimelineComponent.vue').default);
Also, add this component inside a home.blade.php file.
Add a new tweet, and you can see the name and tweet.
Step 10: Show time in the timeline.
Add this below code inside post.php to get date. So, we can use the append attribute to add the time data and then fetch it in the response. Very simple.
app/Post.php
protected $appends = ['createdDate'];
public function getCreatedDateAttribute(){
return $this->created_at->diffForHumans();
}
Now, we can access the createdDate property inside TimelineComponent.vue file.
resources/js/components/TimelineComponent.vue
Step 11: Create a user profile.
Now, we need to create one controller called UserController. Type the following command.
php artisan make:controller UserController
Now, add the following function inside UserController.php file.
app/Http/Controllers/UserController.php
namespace App\Http\Controllers;
use App\User;
use Illuminate\Http\Request;
class UserController extends Controller
{
public function show(User $user)
{
return view('user', compact('user'));
}
}
Here, I am using Route Model Binding, but we will use my name on the route. So, we can access it through user’s name key. So we need to define the routing key inside User.php file.
app/User.php
// User.php
public function getRouteKeyName()
{
return 'name';
}
Create a view file called user.blade.php inside views folder.
resources/views/user.blade.php
Also, we need to define the route inside a web.php file.
routes/web.php
Route::get('users/{user}', 'UserController@show')->name('user.show');
Let us say; I have registered the user with a name: abc. We can access its profile using this URL
localhost:8000/users/abc
Step 12: Display URL inside TimelineComponent.
Create an accessor for a profileLink inside User.php model file.
app/User.php
namespace App;
use Illuminate\Notifications\Notifiable;
use Illuminate\Foundation\Auth\User as Authenticatable;
class User extends Authenticatable
{
protected $appends = ['profileLink'];
public function getProfileLinkAttribute()
{
return route('user.show', $this);
}
}
Now, we can display this URL inside TimelineComponent.vue file.
resources/js/components/TimelineComponent.vue
Step 13: Create Follow or Unfollow link.
Create a migration file for Followers table.Type the following command to generate model and migrations.
php artisan make:model Follower -m
Now, write the following schema inside create_followers_table.
Schema::create('followers', function (Blueprint $table) {
$table->bigIncrements('id');
$table->unsignedBigInteger('user_id');
$table->unsignedBigInteger('follower_id');
$table->nullableTimestamps();
$table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
$table->foreign('follower_id')->references('id')->on('users')->onDelete('cascade');
});
Migrate the table.
php artisan migrate
Now, we need to set up the relationship with the User model.
app/User.php
public function following()
{
return $this->belongsToMany(User::class, 'followers', 'user_id', 'follower_id');
}
Next step is, we need to put some condition that is following.
app/User.php
namespace App;
use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
class User extends Authenticatable
{
public function isNot($user)
{
return $this->id !== $user->id;
}
public function isFollowing($user)
{
return (bool) $this->following->where('id', $user->id)->count();
}
public function canFollow($user)
{
if(!$this->isNot($user)) {
return false;
}
return !$this->isFollowing($user);
}
}
Okay, now we have written all the conditions regarding function, we can head over to the user.blade.php file and implement the follow or unfollow link.
resources/views/user.blade.php
Step 14: Follow the User.
routes/web.php
Route::get('users/{user}/follow', 'UserController@follow')->name('user.follow');
Now, we can write the follow() function inside UserController.php file.
app/Http/Controllers/UserController.php
public function follow(Request $request, User $user)
{
if($request->user()->canFollow($user)) {
$request->user()->following()->attach($user);
}
return redirect()->back();
}
Also, we need to update the user.blade.php file.
resources/views/user.blade.php
Step 15: Unfollow the User
We can unfollow the user, which is currently following. So we can write the following function inside User.php file.
app/User.php
public function canUnFollow($user)
{
return $this->isFollowing($user);
}
Also, we need to define the unfollow route inside a web.php file.
routes/web.php
Route::get('users/{user}/unfollow', 'UserController@unfollow')->name('user.unfollow');
Now, write the unFollow() function inside UserController.php file.
app/Http/Controllers/UserController.php
public function unFollow(Request $request, User $user)
{
if($request->user()->canUnFollow($user)) {
$request->user()->following()->detach($user);
}
return redirect()->back();
}
Also, we need to update the user.blade.php file.
resources/views/user.blade.php
Now, finally, the follow and unfollow functionality is over. you can check it now
Step 16: Fetch tweets
So, we can define the index() function inside PostController.php file.
app/Http/Controllers/PostController.php
namespace App\Http\Controllers;
use App\Post;
use Illuminate\Http\Request;
class PostController extends Controller
{
public function store(Request $request, Post $post)
{
$newPost = $request->user()->posts()->create([
'body' => $request->body
]);
return response()->json($post->with('user')->find($newPost->id));
}
public function index(Request $request, Post $post)
{
$posts = $post->whereIn('user_id', $request->user()->following()
->pluck('users.id')
->push($request->user()->id))
->with('user')
->orderBy('created_at', 'desc')
->take($request->get('limit', 10))
->get();
return response()->json($posts);
}
}
Define the route for this index() function.
routes/web.php
Route::get('posts', 'PostController@index')->name('posts.index');
Okay, now finally, we need to send a network request using axios library. We need to define the axios get request inside our TimelineComponent.vue file.
resources/js/components/TimelineComponent.vue
Finally, our laravel vue tutorial is over. In this Laravel and vue example, we have covered lots of things and concepts.I hope it can help you with your real-time projects.
#laravel-6 #vue-js #follow-unfollow #laravel