Laravel を利用した CRUD の SPA 作成 5 編集画面編

俺の編集画面は13km や

フロントエンドの実装

トップ画面の修正

まずはトップ画面に編集ボタンを追加します。

<template>
  <div>
    <div v-if="message" class="alert alert-success">
      {{ message }}
    </div>
    <router-link to="/add" tag="button" class="btn btn-success" style="margin-bottom:10px">新規作成</router-link>
    <div class="input-group mb-3">
      <div class="input-group-prepend">
        <span class="input-group-text">検索</span>
      </div>
      <input type="text" class="form-control" v-on:blur="fetchItems" v-model="searchText">
    </div>
    <table class="table table-bordered table-dark">
      <thead>
        <tr>
          <th scope="col">Id</th>
          <th scope="col">名前</th>
          <th scope="col">編集</th>
        </tr>
      </thead>
      <tbody>
        <tr v-for="item in items">
          <th scope="row">{{ item.id }}</th>
          <td>{{ item.item_name }}</td>
          <td style="width:10%"><router-link :to="{ name:'edit', params: { itmeId:item.id }}" tag="button" class="btn btn-primary" style="margin-bottom:10px">編集</router-link></td>
        </tr>
      </tbody>
    </table>
  </div>
</template>
<script>
    export default {
        created() {
            this.fetchItems()
            this.message = this.$route.query.message
        },
        data() {
            return {
                items: [],
                searchText: '',
                message: null
            }
        },
        methods: {
            fetchItems() {
                axios.get('/api/items', {params: {item_name:this.searchText}}).then((res)=>{
                    this.items = res.data
                })
            }
        }
    }
</script>

一覧のテーブルに「router-link」で編集ボタンを追加します。

Edit コンポーネントの新規作成

新たに「Edit.vue」に編集用のコンポーネントを作成します。

<template>
  <div>
    <div v-if="error" class="alert alert-danger">
      {{ error }}
    </div>
    <h2>{{itmeId}}</h2>
    <div class="input-group mb-3">
      <input type="text" class="form-control" placeholder="なんか入力してください" v-model="itemNameText">
      <div class="input-group-append">
        <button class="btn btn-outline-secondary" type="button" v-on:click="editItem">編集</button>
      </div>
    </div>
    <router-link to="/" tag="button" class="btn btn-info">一覧へ</router-link>
  </div>
</template>
<script>
    export default {
        created() {
          this.fetchItem()
        },
        data() {
          return {
            itemNameText: '',
            error: null
          }
        },
        props: ['itmeId'],
        methods: {
          fetchItem(){
            axios.get('/api/items/edit/'+this.itmeId).then((res)=>{
              console.log(res)
              this.itemNameText = res.data.item_name
            })
          },
          editItem(event){
            axios.post('/api/items/edit/'+this.itmeId, { item_name:this.itemNameText }).then((res)=>{
              console.log(res)
              if(res.data.stats == 0){
                this.$router.push({ path: '/', query: { message: res.data.message } })
              }else{
                this.error = res.data.message.item_name.join('<br>')
              }
            })
          }
        }
    }
</script>

画面描写時に「fetchItem」関数を呼び出し、itmeId に対応するデータを Rest にて取得し
フォームに取得したデータをセットします。

編集ボタンをクリック時「" v-on:click="editItem"」によりイベント発火させて editItem 関数
を呼び出しデータを更新します。

ルーティングの設定

Vue.js のルーティングを設定します。

import Vue from 'vue'
import VueRouter from 'vue-router'
import itmeIndex from './components/items/Index.vue'
import itmeAdd from './components/items/Add.vue'
import itmeEdit from './components/items/Edit.vue'
require('./bootstrap');
Vue.use(VueRouter)
const router = new VueRouter({
    mode: 'history',
    routes: [
        { path: '/', component: itmeIndex },
        { path: '/add', component: itmeAdd },
        { path: '/edit/:itmeId', name: 'edit', component: itmeEdit, props: true }        
    ]
})
const app = new Vue({
    router,
    el: '#app'
})

Edit.vue をコンポーネントとしてインポートします。「/edit/:itmeId」のアドレスでアクセスした場合にEdit コンポーネントに切り替わります。

バックエンドの実装

編集画面初期表示用 API 作成

編集画面へ遷移した場合の初期表示の Rest Api を作成します。

    public function edit($id)
    {
        $item = \App\Item::find($id);
        return response($item);
    }

テーブル主キー(id)に対応する item を json で返却しているだけです。

更新ロジックの実装

編集(update)ロジックの実装です。

    public function update(Request $request, $id) 
    {
        $validator = Validator::make($request->all(), [
            'item_name' => 'required|max:255',
        ]);
        if ($validator->fails()) {
            return [
                'stats' => 1,
                'message' => $validator->errors(),
            ];
        }
        $item = \App\Item::find($id);
        $item->item_name = $request->input('item_name');
        $item->save();
        return [
            'stats' => 0,
            'message' => "編集に成功しました。",
        ];
    }

登録とほぼ同じ。
バリデーション後に更新を実施します。

ルーティングの設定

Route::get('items/edit/{id}', 'ItemsController@edit');
Route::post('items/edit/{id}', 'ItemsController@update');

以上で完成です。

動作確認

http://homestead.test/

トップ画面のテーブルに「編集」ボタンが追加されました。クリックしてみましょう。

http://homestead.test/edit/1

編集画面が表示されました。わけのわからない日本語が表示されていますが、「こここ更新」というエレガントかつシンプルな日本語に変更します。

しっかり更新されました。

JavaScript, PHP

Posted by admin