簡體   English   中英

Laravel + Vue,最佳實踐

[英]Laravel + Vue, best practices

我正在 Laravel 中構建一個簡單的發票系統。 所以很明顯我需要建立一個視圖,當我能夠編輯它時。 這是一個表,我可以在其中動態添加和刪除行。

所以我的想法是:好的,我可以用 jQuery 很容易地做到這一點,但是添加一個具有多個輸入的行,特別是當我使用順風時,這意味着有很多奇怪的類,會很混亂,所以我會嘗試Vue。 我沒有這方面的經驗,但總的來說它看起來很容易。

然后我制作了一個 Vue 組件,其中包含<table><tr> ,其中包含輸入:

<document-items-table:items='@json($document->items)' />

它不是 SPA,所以我不想在里面進行 AJAX 調用,我已經加載了我的文檔,所以我通過一個 vue 道具將文檔項傳遞為 Json。 它工作正常。

接下來是,在每個文檔行中,我添加了刪除一行的刪除按鈕。 我還有一個添加空行的按鈕。

我的組件如下所示:

<template>
    <div class="w-full">
        <div class="relative flex flex-col min-w-0 break-words w-full rounded bg-white">
            <div class="block w-full overflow-x-auto">
                <table class="items-center w-full bg-transparent border-collapse pb-4">
                    <thead>
                    <tr>
                        <th style="width: 30px" class="pl-6 pr-2 align-middle border-b border-solid py-3 text-xs uppercase border-l-0 border-r-0 whitespace-nowrap font-semibold text-left bg-blueGray-50 text-blueGray-500 border-blueGray-100">
                            No.
                        </th>
                        <th style="min-width: 600px" class=" align-middle border-b border-solid py-3 text-xs uppercase border-l-0 border-r-0 whitespace-nowrap font-semibold text-left bg-blueGray-50 text-blueGray-500 border-blueGray-100">
                            Name
                        </th>
                        <th style="width: 60px" class="align-middle border-b border-solid py-3 text-xs uppercase border-l-0 border-r-0 whitespace-nowrap font-semibold text-left bg-blueGray-50 text-blueGray-500 border-blueGray-100">
                            Quantity
                        </th>
                        <th style="width: 60px"  class="align-middle border-b border-solid py-3 text-xs uppercase border-l-0 border-r-0 whitespace-nowrap font-semibold text-left bg-blueGray-50 text-blueGray-500 border-blueGray-100">
                            Unit
                        </th>
                        <th style="width: 120px"  class="align-middle border-b border-solid py-3 text-xs uppercase border-l-0 border-r-0 whitespace-nowrap font-semibold text-left bg-blueGray-50 text-blueGray-500 border-blueGray-100">
                            Price
                        </th>
                        <th style="width: 60px"  class="align-middle border-b border-solid py-3 text-xs uppercase border-l-0 border-r-0 whitespace-nowrap font-semibold text-left bg-blueGray-50 text-blueGray-500 border-blueGray-100">
                            Tax rate
                        </th>
                        <th style="width: 60px"  class="align-middle border-b border-solid py-3 text-xs uppercase border-l-0 border-r-0 whitespace-nowrap font-semibold text-left bg-blueGray-50 text-blueGray-500 border-blueGray-100">

                        </th>
                    </tr>
                    </thead>
                    <tbody class="border-b-4 border-white">
                    <tr v-for="(item, i) in this.itemsLocal" :key="item.id">
                        <td class="border-t-0 pl-6 align-middle border-l-0 border-r-0 text-xs whitespace-nowrap py-1">
                            {{ i + 1 }}
                        </td>
                        <td class="border-t-0 align-middle border-l-0 border-r-0 text-xs whitespace-nowrap py-1">
                            <item-input name="title" id="title" :value="item.title" />
                        </td>
                        <td class="border-t-0 align-middle border-l-0 border-r-0 text-xs whitespace-nowrap py-1">
                            <item-input class="w-full" name="quantity" id="quantity" :value="item.quantity" />
                        </td>
                        <td class="border-t-0 align-middle border-l-0 border-r-0 text-xs whitespace-nowrap py-1">
                            <item-input class="w-full" name="unit" id="unit" :value="item.unit" />
                        </td>
                        <td class="border-t-0 align-middle border-l-0 border-r-0 text-xs whitespace-nowrap py-1">
                            <item-input class="w-full" name="price" id="price" :value="item.price / 100" />
                        </td>
                        <td class="border-t-0 align-middle border-l-0 border-r-0 text-xs whitespace-nowrap py-1">
                            <item-input class="w-full" name="tax" id="tax" :value="item.tax_rate" />
                        </td>
                        <td class="border-t-0 align-middle border-l-0 border-r-0 text-xs whitespace-nowrap py-1">
                            <button @click="() => deleteRow(item.id)" class="p-2 px-4 bg-rose-500 text-white rounded"><i class="fas fa-times fa-sm"></i> </button>
                        </td>
                    </tr>
                    </tbody>
                </table>
            </div>
        </div>
        <div class="w-full text-center">
            <button @click="addRow" class="bg-lightBlue-600 px-4 py-2 text-white rounded text-sm font-bold">Add row</button>
        </div>
    </div>
</template>

<script>
export default {
    props: {
        items: Array,
    },
    mounted() {
    },

    data () {
        return {
            itemsLocal: [...this.items],
            newRowCount: 1
        }
    },
    methods: {
        deleteRow(itemID) {
            this.itemsLocal = _.reject(this.itemsLocal, ['id', itemID]);
        },
        addRow() {
            this.itemsLocal.push({
                id: -this.newRowCount
            })
            this.newRowCount++;
        }
    }
}
</script>

現在我有一些問題要問那些對 Vue 更有經驗的人

  1. 使用 json 將一組 PHP 對象傳遞給 Vue 組件是一個干凈的解決方案嗎?
  2. 由於不允許修改props ,並且我需要添加和刪除行,我將我的itemsprops克隆到data ,然后添加和刪除它們。 有沒有更好的解決方案?
  3. 在我的桌子旁邊,我將有一些匯總框,其中包含所有元素的一些“總價”。 我想根據我輸入這些輸入的值動態更新這個值。 我可以把它做成一個單獨的組件,但我知道在兩個組件之間傳遞值沒有好的方法,那么我應該如何解決呢? 我是否應該再制作一個包含我的表格和摘要框的父包裝器組件,將數據發送到該包裝器,然后再發送到摘要組件? 或者只是使用一些 jQuery 並且不打擾?
  4. 你看到我在這里使用的任何其他錯誤做法嗎? (我知道 html id 和名稱重復 - 我會處理它)

我盡量讓它干凈。 這不是一個工作項目,而是提高我的技能的事情。

  1. 使用 JSON 將數據作為道具發送可以很好地初始化組件,只需確保在需要的地方進行正確的編碼和解碼。
  2. 您不能直接修改道具,但是一旦您將道具中的值分配給本地數據,您幾乎可以使用該本地數據做您想做的事情。 安裝后,您實際上可以將 JSON 數據的值分配給相同類型的各個組件。 在這些組件中,如果需要,您實際上可以將數據發送回父級。 例如,如果您修改子組件中的值,您可以將其發送回父組件,以便父組件在其本地數據中始終具有更新的值,並且由於 vue 是響應式的,它也會將該值分配回為給孩子的道具。 所以間接地你會修改道具。 我建議為它創建一個組件,因為它可以讓您更輕松地創建和刪除它的實例,並最大限度地減少您需要在父級別上執行的工作量。
  3. 對於計算,vue 有一個計算屬性,您可以使用它來計算一個值並將其分配給可以在組件中顯示的數據。 請注意這一點,因為如果您的計算量很大,它確實會減慢速度。 也有觀察者可以嘗試解決這個問題,但我認為計算總價最容易。 計算文檔與觀看文檔
  1. 您正在嘗試學習最佳實踐真是太好了。 我也在學習中。 到目前為止,我唯一建議的是創建一個新的組件類型並在創建時初始化它們並將新的組件添加到列表中。 操作和刪除也會更容易。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM