【发布时间】:2021-07-03 19:37:40
【问题描述】:
我正在 Laravel 中构建一个简单的发票系统。所以很明显我需要建立一个视图,当我能够编辑它时。这是一个表格,我可以在其中动态添加和删除行。
所以我的想法是:好的,我可以使用 jQuery 轻松做到这一点,但是添加具有多个输入的行,特别是当我使用 tailwind 时,这意味着有很多奇怪的类,会很混乱,所以我'将尝试使用 Vue。我没有这方面的经验,但总的来说它看起来很简单。
然后我做了一个 Vue 组件,其中包含 <table> 和 <tr>s,里面有输入:
<document-items-table :items='@json($document->items)' />
它不是 SPA,所以我不想在里面进行 AJAX 调用,我已经加载了我的文档,所以我通过 vue prop 作为 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 的人
- 使用 json 将 PHP 对象数组传递给 Vue 组件是一个干净的解决方案吗?
- 由于不允许修改
props,并且我需要添加和删除行,我将我的items从props克隆到data,然后添加和删除它们。有没有更好的解决方案? - 在我的表格旁边,我将有一些汇总框,其中包含所有元素的一些“总价”。我想根据我输入这些输入的值动态更新这个值。我可以把它做成一个单独的组件,但是我知道在两个组件之间传递值没有好的方法,那么我应该如何解决呢?我是否应该再制作一个包含我的表格和摘要框的父包装器组件,将数据发送到该包装器,然后再发送到摘要组件?或者只是使用一些 jQuery 而不会打扰?
- 您看到我在这里使用的任何其他错误做法吗? (我知道 html id 和名称重复 - 我会处理它)
我尽量让它干净。这不是一个工作项目,而是一个提高我技能的事情。
【问题讨论】:
标签: javascript php laravel vue.js