iT邦幫忙

2022 iThome 鐵人賽

DAY 14
0
Modern Web

LV的全端開發體驗系列 第 14

Day14 補完題組編輯及刪除 - 引入fontawesome

  • 分享至 

  • xImage
  •  

昨天我們完成了題組的新增及重新整理了題目的CRUD,不過題組應該也要可以修改及刪除,但目前的版面配置空間有限,所以我們使用 icon 來協助完成這兩個功能。

不過這邊有個問題要小心,題目中有題庫和題組的關聯,那麼當題組或題庫被刪除時,題目該怎麼處理?所以如果只是編輯的話沒有什麼問題,但是當要刪除時,應該要先確認一下有沒有關聯的題目存在,並做出對應的提示,目前我會先檔下來,只要題庫或題組有關聯的題目在,就只能編輯不能刪除。

引入fontawesome

參考官網的[Set Up with Vue]

npm i --save @fortawesome/fontawesome-svg-core

安裝免費版的 icon 套件

npm i --save @fortawesome/free-solid-svg-icons
npm i --save @fortawesome/free-regular-svg-icons
npm i --save @fortawesome/free-brands-svg-icons

安裝 vue3 用的 icon component

# for Vue 3.x
npm i --save @fortawesome/vue-fontawesome@latest-3

接著到 [Add Icons with Vue] 來看看如何把icon加入到 vue 中;
resources\js\Pages\Backstage\Subjects.vue

...略
/* 載入fontawesome的專用library */
import { library } from '@fortawesome/fontawesome-svg-core'

/* 引入fontawesome的專用組件 */
import { FontAwesomeIcon } from '@fortawesome/vue-fontawesome'

/* 引入要使用的icon名稱 */
import { faFilePen,faTrashCan } from '@fortawesome/free-solid-svg-icons'

/* 將要使用的icon加入到library中 */
library.add(faFilePen,faTrashCan)

...略

<div v-else>
    <button class="px-4 py-2 border rounded-lg hover:bg-sky-400 
                   hove:text-sky-900 text-sky-700 bg-sky-200"
            v-for="group in groups" 
            :key="group.id">
      {{ group.name }}
    </button>

    <!-- 使用組件來引入icon -->
    <font-awesome-icon icon="fa-solid fa-file-pen" />
    <font-awesome-icon icon="fa-solid fa-trash-can" />
</div>

調整一下icon的位置在題組按鈕的右上和右下,一個設成綠色的,一個設成紅色的,同時我們在題組按鈕上設定滑鼠滑入滑出時icon的顯示隱蔵效果:

resources\js\Pages\Backstage\Subjects.vue

<script setup>
import { ref } from 'vue';

//依據題組的數量來宣告一個陣列,並預設填上false
const hover=ref((new Array(props.groups.length)).fill(false))

</script>
<template>

<div v-else>
    
<!--在按鈕上建立滑鼠移入移出的事件,並切換hover的true及false值-->    
<button class="px-4 py-2 border rounded-lg hover:bg-sky-400 
               hove:text-sky-900 text-sky-700 bg-sky-200 relative"
        v-for="group,idx in groups" 
        :key="group.id"
        @mouseover="hover[idx]=!hover[idx]"
        @mouseout="hover[idx]=!hover[idx]">
      {{ group.name }}
    
    <!-- 使用組件來引入icon -->
    <font-awesome-icon icon="fa-solid fa-file-pen" 
                       class="absolute -top-1 -right-3 text-green-600" 
                       :class="{'block':hover[idx],'hidden':!hover[idx]}" />
    
    <font-awesome-icon icon="fa-solid fa-trash-can" 
                       class="absolute -bottom-1 -right-2 text-red-600" 
                       :class="{'block':hover[idx],'hidden':!hover[idx]}" />
</button>
</div>    
</template>

接著在編輯及刪除的icon上加上刪除的路由:
resources\js\Pages\Backstage\Subjects.vue

.....略
<Link :href="route('bankgroup.edit',group.id)">
    <font-awesome-icon icon="fa-solid fa-file-pen" 
                       class="absolute -top-1 -right-3 text-green-600" 
                       :class="{'block':hover,'hidden':!hover}" />
</Link>
<Link :href="route('bankgroup.destroy',group.id)">
    <font-awesome-icon icon="fa-solid fa-trash-can" 
                       class="absolute -bottom-1 -right-2 text-red-600" 
                       :class="{'block':hover,'hidden':!hover}" />
</Link>

調整一下 BankGroupConroller 中的內容,把需要帶的資料和提示功能也加上去:
app\Http\Controllers\BankGroupController.php

function edit($id)
{
    $group=$this->bankgroup->find($id);
    $bank=$group->bank;
    unset($group->bank); //移除不需要傳到前端的資料,
    return Inertia::render('Backstage/BankGroupForm',[
        'header'=>'編輯題組',
        'button'=>'修改',
        'group'=>$group,
        'bank'=>$bank
    ]);
}

function update(Request $request,$id)
{
    $this->bankgroup->update($request->input(),$id);

    //善用邏輯拆分及資料關聯,可以很方便的取得需要的資料,
    //比如在這邊可以從題組的id去找出題庫再取得題庫的code回傳給路由
    return redirect()->route('bank.subjects',$this->bankgroup->find($id)->bank->code);
}

function destroy($id)
{
    //透過關聯判斷題組是否有關聯的題目存在
    if($this->bankgroup->find($id)->subjects()->exists()){

        //如果有關聯題目存在,則回傳錯誤息
        return redirect()->back()->withErrors(['bankgroup'=>'關聯題目存在,無法刪除題組']);
    }

    //刪除題組
    $this->bankgroup->destroy($id);

    //導回頁面
    return redirect()->back();
}

因為題組的刪除可能會有錯誤訊息回傳,所以我們要在題目列表畫面偵錯誤訊息,這個機制 Inertia 已經幫我們做掉了,laravel回傳的錯誤訊息都會集中在全域的 errors 中,我們只要在組件中把這個屬性接進來就可以了:

resources\js\Pages\Backstage\Subjects.vue

<script setup>
....略
const props = defineProps({ subjects: Array, 
                            groups:Array, 
                            count: Number ,
                            bank:String,
                            errors:Object}); //增加一個errors的屬性
</script>
<template>
    
<!--這個錯誤訊息區塊會依據bankgroup是否有資料來顯示或隱藏-->
<div v-if="errors.bankgroup" 
     class="text-red-100 px-3 py-1.5 rounded-lg bg-red-500 my-2">
         {{ errors.bankgroup }}
</div>
</template>

這樣,整套題庫到題目的後台功能總算是比較完整了,細節的部份可以再自行調整,後面如果有空我會再補上,因為我開始覺得30天講不完這整個系統的設計,我太輕敵了,哈哈哈哈哈.......


上一篇
Day13 完善題組及題目功能
下一篇
Day15 前台測驗功能試做
系列文
LV的全端開發體驗30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言