我没有收到任何错误并且正在编译,所以我不确定自己在做什么错。我搜索了这个主题,但没有成功。
我有BulkExpenses.vue,它可以拉出并显示一些费用记录,然后BulkExpenses.vue是一个嵌套组件,显示每个记录。我想单击垃圾桶图标,并使其将费用ID传回父组件以运行删除脚本。我正在另一个项目中进行此操作,并且运行良好,因此我不确定在这里做错了什么。
还有一个Lookup组件,它是TypeAhead,用于拉动行程以连接到Expense,但这是可行的。
BulkExpenses.vue
<template>
<div>
<form action="#" @submit.prevent="createBulkExpense()" class="publisher bt-1 border-fade bg-white" autocomplete="off">
<table>
<thead>
<tr>
<td><input v-model="bulk_name" type="text" placeholder="Name"></td>
<td><input id="bulk_expensed_at" type="text" name="bulk_expensed_at" placeholder="Date Expense Incurred"></td>
<td><input id="bulk_type_id" type="text" name="bulk_type" placeholder="Type"></td>
<td>
<lookup
source="/api/lookup/trip"
placeholder="Search your trips"
filter-key="name"
:start-at="3"
v-on:selected-link="onSelectedTrip"
:modellink="modellink">
</lookup>
</td>
<!-- <td><input id="bulk_tags" type="text" name="bulk_tags" placeholder="Tags"></td> -->
<td><input id="bulk_vendor" type="text" name="bulk_vendor" placeholder="Vendor"></td>
<td><input id="bulk_method" type="text" name="bulk_method" placeholder="Payment Method"></td>
<td><input id="bulk_total" type="text" name="bulk_total" placeholder="Total Amount"></td>
<td><input id="bulk_paidby_user_id" type="text" name="bulk_paidby" placeholder="Paid By"></td>
<td><input id="bulk_status" type="text" name="bulk_status" placeholder="Payment Status"></td>
<td><input id="bulk_notes" type="text" name="bulk_notes" placeholder="Notes"></td>
</tr>
</thead>
<tbody>
<expense v-for="expense in expenses"
:key="expense.id"
:expense="expense"
@expense-deleted="deleteExpense($event)">
</expense>
</tbody>
</table>
</form>
</div>
</template>
<script>
// import CommentsManager from './CommentsManager.vue';
var axios = require("axios");
import lookup from './Lookup.vue';
import expense from './BulkExpense.vue';
export default {
components: {
lookup, expense
},
data: function() {
return {
modellink: {
"name": "n/a",
"description": "",
"id": null,
"model": "n/a"
},
bulk_trip: {
"name": "n/a",
"description": "",
"id": null
},
selectName: "",
bulk_name: "",
bulk_expensed_at: "",
bulk_type: "",
bulk_tags: "",
bulk_vendor: "",
bulk_method: "",
bulk_total: "",
bulk_paidby: {
name: "",
id: ""
},
bulk_status: "",
bulk_notes: "",
expense: {
id: 1,
name: "",
expensed_at: "",
type: {
id: "",
name: ""
},
trip: {
id: "",
name: ""
},
tags: [],
vendor: "",
method: "",
total: "",
paidby: {
id: "",
name: ""
},
status: {
id: "",
name: ""
},
notes: ""
},
expenses: [
{
id: 1,
name: "",
expensed_at: "",
type: {
id: "",
name: ""
},
trip: {
id: "",
name: ""
},
tags: [],
vendor: "",
method: "",
total: "",
paidby: {
id: "",
name: ""
},
status: {
id: "",
name: ""
},
notes: ""
}
]
};
},
created() {
this.fetchExpenses();
},
methods: {
// onSelectedLink: function (talink) {
// // alert(JSON.stringify(talink.description, null, 4));
// this.modellink = talink
// },
onSelectedTrip: function (talink) {
// alert(JSON.stringify(talink.description, null, 4));
this.bulk_trip = talink
this.modellink = talink
},
fetchExpenses() {
axios.get('/api/expense').then((res) => {
//alert(JSON.stringify(res.data[0], null, 4));
this.expenses = res.data;
});
},
createExpense() {
axios.post('/api/expense', {name: this.expense.name, vessel_id: Laravel.vesselId, expensed_at: this.expense.expensed_at })
.then((res) => {
this.expense.content = '';
// this.expense.user_id = Laravel.userId;
// this.task.statuscolor = '#ff0000';
this.edit = false;
this.fetchExpenses();
})
.catch((err) => console.error(err));
},
deleteExpense(expense) {
console.log(expense.id);
alert(expense.id);
axios.delete('/api/expense/' + expense.id)
.then((res) => {
this.fetchExpenses()
})
.catch((err) => console.error(err));
},
}
}
</script>
BulkExpense.vue
<template>
<tr>
<td><input v-model="expense.name" type="text" name="name"></td>
<td><input v-model="expense.expensed_at"></td>
<td v-if="expense.type"><input v-model="expense.type.name"></td>
<td>
<trip-select v-bind:tripId="expense.trip_id" selectName="trip_id"></trip-select>
</td>
<td><input v-model="expense.vendor"></td>
<td><input v-model="expense.method"></td>
<td><input v-model="expense.total"></td>
<td v-if="expense.paidby"><input v-model="expense.paidby.name" ></td>
<td v-if="expense.status"><input v-model="expense.status.name" ></td>
<td><input v-model="expense.notes"></td>
<td>
<a class="text-lighter hover-light" v-on:click="deleteExpense" href="#"><i class="fas fa-trash"></i></a>
</td>
</tr>
</template>
<script>
import TripSelect from './TripSelect.vue';
import typeahead from './Typeahead.vue';
export default {
name: 'expense',
components: { TripSelect, typeahead },
props: {
bulk_name: {
type: String,
required: false
},
expense: {
required: true,
type: Object,
default: function () {
return {
id: 1,
name: "",
expensed_at: "",
type: {
id: "",
name: ""
},
trip: {
id: "",
name: ""
},
tags: [],
vendor: "",
method: "",
total: "",
paidby: {
id: "",
name: ""
},
status: {
id: "",
name: ""
},
notes: ""
}
}
}
},
data() {
return {
}
},
methods: {
deleteExpense() {
alert(this.expense.id)
this.$emit('expense-deleted', {
'id': this.expense.id,
});
}
}
}
</script>
答案 0 :(得分:1)
虽然它可能无法直接回答您的问题,但这肯定可以解决。而且,这可以解决您遇到的一个基本问题,它是反模式的一个例子。
与其在组件内部创建另一个向父节点发出的方法,不如从子进程中的单击处理程序发出消息。另外,只需来回发送费用,这样就不会造成财产混乱:
无需声明$event
,因为如果需要,您可以默认使用它。
<expense v-for="expense in expenses" :key="expense.id" :expense="expense" @expense-deleted="deleteExpense"></expense>
然后在您的点击处理程序中,只需emit
进行操作,然后将费用转回即可:
<a class="text-lighter hover-light"
@click="$emit('expense-deleted', expense)"
href="#">
<i class="fas fa-trash"></i>
</a>
这将解决上述基本问题,并可能解决您在此过程中遇到的问题。
我还看到您将v-on:click
和@click
混合使用,但是它们是同一回事,一个只是另一个的简写。我只建议@click
来保持凝聚力。
最后,这是此方法的MCVE。
修改
以防万一,您可以通过以下方式将其从现有集合中删除:
this.expenses.slice(this.expenses.findIndex(o => o.id === expense.id), 1)
由于我们的expense
将始终存在于我们的收藏夹中,因此我们不必担心检查是否存在,因此您可以使用一个衬纸。
或者您可以替换整个阵列,但是您需要为此使用Vue.set
:
Vue.set(this, 'expenses', this.expenses.filter(o => o.id !== expense.id))