2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

laravel backend vue frontend

Posted at

laravelをbackend、vueをfrontendにしたつぶやきwebアプリを作って自分の確認のために書いておきます。

まず、vueは画面表示だけ、laravelの方でつぶやきもユーザーも管理する方向で作っていきました。

laravelのAuthControllerもこんな感じ

<?php

namespace App\Http\Controllers;
use App\Http\Requests\UserLoginRequest;
use App\Http\Requests\UserRegisterRequest;
use App\Http\Resources\User as UserResource;
use App\User;
use Illuminate\Http\Request;

class AuthController extends Controller {
	public function register(UserRegisterRequest $request) {
		$user = User::create([
			'email' => $request->email,
			'name' => $request->name,
			'password' => bcrypt($request->password),
		]);

		if (!$token = auth()->attempt($request->only(['email', 'password']))) {
			return abort(401);
		};

		return (new UserResource($request->user()))->additional([
			'meta' => [
				'token' => $token,
			],
		]);
	}

	public function login(UserLoginRequest $request) {
		if (!$token = auth()->attempt($request->only(['email', 'password']))) {
			return response()->json([
				'errors' => [
					'email' => ['Sorry we cant find you with those details.'],
				],
			], 422);
		};

		return (new UserResource($request->user()))->additional([
			'meta' => [
				'token' => $token,
			],
		]);
	}

	public function user(Request $request) {
		return new UserResource($request->user());
	}

	public function logout() {
		auth()->logout();
	}
}

backend/app/Http/Controllers/PostController.phpも

<?php

namespace App\Http\Controllers;

use App\Http\Requests\StorePostRequest;
use App\Http\Requests\UpdatePostRequest;
use App\Http\Resources\Post as PostResource;
use App\Post;
use App\Topic;
use Illuminate\Http\Request;

class PostController extends Controller {
	public function store(StorePostRequest $request, Topic $topic) {
		$post = new Post;
		$post->body = $request->body;
		$post->user()->associate($request->user());

		$topic->posts()->save($post);
		return new PostResource($post);
	}

	public function show(Request $request, Topic $topic, Post $post) {
		return new PostResource($post);
	}

	public function update(UpdatePostRequest $request, Topic $topic, Post $post) {
		$this->authorize('update', $post);
		$post->body = $request->get('body', $post->body);
		$post->save();
		return new PostResource($post);
	}

	public function destroy(Topic $topic, Post $post) {
		$this->authorize('destroy', $post);
		$post->delete();
		return response(null, 204);
	}
}

backend/app/Http/Controllers/TopicsController.php

<?php

namespace App\Http\Controllers;

use App\Http\Requests\TopicCreateRequest;
use App\Http\Requests\UpdateTopicRequest;
use App\Http\Resources\Topic as TopicResource;
use App\Post;
// use Illuminate\Http\Request;
use App\Topic;

class TopicController extends Controller {
	public function index() {
		$topics = Topic::latestFirst()->paginate(5);
		return TopicResource::collection($topics);
	}

	public function store(TopicCreateRequest $request) {
		$topic = new Topic;
		$topic->title = $request->title;
		$topic->user()->associate($request->user());

		$post = new Post;
		$post->body = $request->body;
		$post->user()->associate($request->user());

		$topic->save();
		$topic->posts()->save($post);

		return new TopicResource($topic);
	}

	public function show(Topic $topic) {
		return new TopicResource($topic);
	}

	public function update(UpdateTopicRequest $request, Topic $topic) {
		$this->authorize('update', $topic);
		$topic->title = $request->get('title', $topic->title);
		$topic->save();
		return new TopicResource($topic);
	}

	public function destroy(Topic $topic) {
		$this->authorize('destroy', $topic);
		$topic->delete();
		return response(null, 204);
	}
}

vue側で送られてきたデータを登録、消去、変更するだけ。
resources/viewsには何も記述しない、vueで表示するから。
ちなみにpostはトピックに対するコメント、topicはつぶやき本体。

おまちかねvueの処理の紹介

frontend/pages/topics/posts/index.vue
```
<template>
	<div class="container">
		<h2>Latest Topics</h2>
    <div v-for="(topic, index) in topics" :key="index" class="bg-light mt-5 mb-5" style="padding:20px;">
      <h2><nuxt-link :to="{name: 'topics-id', params: {id: topic.id}}">{{topic.title}}</nuxt-link></h2>

      <div v-if="authenticated">
        <div v-if="user.id === topic.user.id">
          <button @click="deleteTopic(topic.id)" class="btn btn-outline-danger fa fa-trash fa-2x pull-right"></button>
          
          <nuxt-link :to="{name: 'topics-edit', params: {id: topic.id}}">
            <button class="btn btn-outline-success fa fa-edit fa-2x pull-right"></button>
          </nuxt-link>
        </div>
      </div>

      <p class="text-muted">{{topic.created_at}} by {{topic.user.name}}</p>

      <div v-for="(content, index) in topic.posts" :key="index" class="ml-5 content">
        {{content.body}}
        <p class="text-muted">{{content.created_at}} by {{content.user.name}}</p>
        <!-- add likes button -->
        <div class="btn btn-outline-primary fa fa-thumbs-up ml-5 mb-2" @click="likePost(topic.id, content)">
          <span class="badge">{{content.like_count}}</span>
        </div>
      </div>
    </div>

    <nav>
      <ul class="pagination justify-content-center">
        <li v-for="(key, value) in links" class="page-item">
          <a @click="loadMore(key)" href="#" class="page-link">{{value}}</a>
        </li>
      </ul>
    </nav>
	</div>
</template>

<script>
	export default {
		data() {
			return {
				topics: [],
        links: []
			}
		},
		async asyncData({$axios}) {
			let {data, links} = await $axios.$get('/topics')
      console.log(links)
			return {
				topics: data,
        links
			}
		},
    methods: {
       async loadMore(key) {
        let {data} =  await this.$axios.$get(key)
        return this.topics = {...this.topics, ...data}
      },
      async deleteTopic(id) {
        await this.$axios.$delete(`/topics/${id}`)
        this.$router.push('/')
      },
      async likePost(topicId, content) {
        const userFromVuex = this.$store.getters["auth/user"];
        if (userFromVuex) {
          // cant like your own post
          if (userFromVuex.id === content.user.id) {
            alert('You cant like your own post')
          }
          // if user have already liked
          if (content.users) {
            if (content.users.some(user => user.id === userFromVuex.id)) {
              alert('You have already liked this post')
            } else {
              await this.$axios.$post(`/topics/${topicId}/posts/${content.id}/likes`)
              let {data, links} = await this.$axios.$get(`/topics`)
              this.topics = data
              this.links = links
            }
          }
        } else {
          alert('Please log in')
          this.$router.push('/login')
        }
      }
    }
	}
</script>

<style scoped>
  .content {
    border-left: 10px solid white;
    padding: 0 10px 0 10px;
  }
  .btn-outline-success, .btn-outline-danger {
    border: none;
  }
</style>

```
2
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?