У меня нет ошибок, и он компилируется, поэтому я не уверен, что делаю не так. Я искал по этой теме безуспешно.
У меня есть BulkExpenses.vue, который извлекает и показывает некоторые записи о расходах, тогда BulkExpense.vue - это вложенный компонент, который отображает каждую запись. Я хочу щелкнуть значок корзины, и он вернет идентификатор расхода родительскому компоненту для запуска сценария удаления. Я делаю это в другом проекте, и он отлично работает, поэтому я не уверен, что делаю здесь не так.
Также есть компонент 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.info(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>
Что именно означает «не работает»? Что вы ожидаете, и что происходит вместо этого? Удалите ненужные вещи.






Хотя он может не дать прямого ответа на ваш вопрос, это наверняка сработает. Кроме того, это решает вашу фундаментальную проблему, которая является примером антипаттерна.
Вместо того, чтобы создавать другой метод внутри вашего компонента, который передает родительскому элементу, просто выполните его из обработчика щелчка в дочернем элементе. Кроме того, просто отправляйте расходы туда и обратно, чтобы вы не жонглировали собственностью:
Не нужно объявлять $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))
Это здорово, и это приближает меня ... но я думаю, что все еще существует проблема, связанная с визуализированной DOM. Если я заменю его вашим упрощенным компонентом, он действительно сработает. Однако, когда я добавляю больше сложности, кажется, что значок корзины больше не доступен. Что-то не так с любыми вложенными данными - например, у меня есть связанная запись «оплачено», если я помещаю ссылку на удаление после этого, по какой-то причине она не активируется - почти как ошибки там, но я не регистрирую никаких ошибок.
@DylanGlockler Может быть CSS, искаженный HTML, множество вещей. Поскольку это решает вашу проблему, вы можете принять этот ответ и задать новый вопрос.
alert(this.expense.id)работает? MCVE было бы здорово