#vue.js #vuejs2
Вопрос:
У меня есть таблица, в которой показан список таких стран (также ссылка на полный код и поле ниже).:
При нажатии кнопки «Обзор» появляется модальный режим, и пользователь может просмотреть некоторые данные о стране, а затем выбрать один из следующих вариантов:
[mark as ready] [mark as reject] [mark as pending]
Основываясь на его выборе, мне нужно отправить идентификатор страны обратно родительскому компоненту, чтобы теперь мы могли отображать статус для этой конкретной страны как «Отклонено», «Готово» или «Ожидает».
В чем мне нужна помощь, так это в том, как я могу логически сделать это как можно проще, не усложняясь (в чем я ужасен).
Я могу успешно передавать данные обратно родителю, но где я терплю неудачу, так это в том, как обрабатывать логику на родительской стороне.
Позвольте мне объяснить:
Вот моя таблица с данными по странам и кнопками для просмотра: App.vue
:
<template>
<div id="app" class="container mt-5">
<table class="table">
<thead>
<tr>
<th scope="col">Country</th>
<th scope="col">Status</th>
</tr>
</thead>
<tbody>
<tr v-for="country in countryChanges" :key="country.id">
<td>{{ country.name }}</td>
<td>
<template v-if="ready">
<button :href="`#modal_${country.id}`" data-bs-toggle="modal">
Ready
</button>
</template>
<template v-else-if="rejected">
<button :href="`#modal_${country.id}`" data-bs-toggle="modal">
Rejected
</button>
</template>
<template v-else>
<button :href="`#modal_${country.id}`" data-bs-toggle="modal">
Review
</button>
</template>
</td>
<AppModal :country="country" @set-as-ready="setAsReady"> </AppModal>
</tr>
</tbody>
</table>
</div>
</template>
<script>
import AppModal from "@/components/AppModal.vue";
import changedCountryData from "@/assets/data.json";
export default {
name: "AdminDashboard",
components: {
AppModal,
},
data() {
return {
countryChanges: [],
ready: false,
rejected: false,
};
},
async created() {
this.countryChanges = changedCountryData;
},
methods: {
setAsReady(id) {
},
},
};
</script>
Вот модальный экран для каждого подробного представления страны:
AppModal.vue
:
<template>
<section
class="modal fade"
:id="`modal_${country.id}`"
tabindex="-1"
aria-labelledby="appModal"
aria-hidden="true"
>
<div class="modal-dialog modal-dialog-scrollable modal-fullscreen">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title fw-bold fs-2">
<slot name="heading"></slot>
</h5>
<button
type="button"
class="btn-close"
data-bs-dismiss="modal"
aria-label="Close"
></button>
</div>
<div class="modal-body">
<div class="container-fluid">
<ul class="list-inline fw-bold mb-4">
<li class="list-inline-item me-4">
<span class="badge rounded-pill bg-light text-secondary"
>Baseline Type</span
>
<slot name="baselineType"></slot>
</li>
<li class="list-inline-item me-4">
<span class="badge rounded-pill bg-light text-secondary">
Submitter</span
>
Doe, John
</li>
<li class="list-inline-item me-4">
<span class="badge rounded-pill bg-light text-secondary">
Submitted</span
>
March 2, 2021
</li>
<li class="list-inline-item">
<span class="badge rounded-pill bg-light text-secondary me-2"
>Status</span
>
<span class="badge rounded-pill bg-warning text-dark"
>Review Changes</span
>
</li>
</ul>
<table class="table table-bordered table-striped">
<thead class="table-dark fs-5">
<tr>
<th scope="col" class="text-muted">Field/Entity</th>
<th scope="col">{{ country.name }}</th>
</tr>
</thead>
<tbody>
<tr>
<th scope="row">Full Name</th>
<td>
Original Value
<div class="ps-2 fw-bold text-success">
<svg
xmlns="http://www.w3.org/2000/svg"
width="16"
height="16"
fill="currentColor"
class="bi bi-arrow-return-right"
viewBox="0 0 16 16"
>
<path
fill-rule="evenodd"
d="M1.5 1.5A.5.5 0 0 0 1 2v4.8a2.5 2.5 0 0 0 2.5 2.5h9.793l-3.347 3.346a.5.5 0 0 0 .708.708l4.2-4.2a.5.5 0 0 0 0-.708l-4-4a.5.5 0 0 0-.708.708L13.293 8.3H3.5A1.5 1.5 0 0 1 2 6.8V2a.5.5 0 0 0-.5-.5z"
/>
</svg>
Updated Value
</div>
</td>
</tr>
<tr>
<th scope="row">Local Short Name</th>
<td>
Original Value
<div class="ps-2 text-success fw-bold">
<svg
xmlns="http://www.w3.org/2000/svg"
width="16"
height="16"
fill="currentColor"
class="bi bi-arrow-return-right"
viewBox="0 0 16 16"
>
<path
fill-rule="evenodd"
d="M1.5 1.5A.5.5 0 0 0 1 2v4.8a2.5 2.5 0 0 0 2.5 2.5h9.793l-3.347 3.346a.5.5 0 0 0 .708.708l4.2-4.2a.5.5 0 0 0 0-.708l-4-4a.5.5 0 0 0-.708.708L13.293 8.3H3.5A1.5 1.5 0 0 1 2 6.8V2a.5.5 0 0 0-.5-.5z"
/>
</svg>
Updated Value
</div>
</td>
</tr>
</tbody>
</table>
</div>
</div>
<div class="modal-footer border-top-0">
<button type="button" class="btn btn-link" data-bs-dismiss="modal">
Close
</button>
<button
type="button"
class="btn btn-success"
data-bs-dismiss="modal"
@click="setAsReady(country)"
>
Mark as Ready
</button>
<button type="button" class="btn btn-danger">Mark as Reject</button>
<button type="button" class="btn btn-warning">Mark as Pending</button>
</div>
</div>
</div>
</section>
</template>
<script>
export default {
props: {
country: {
type: Object,
required: true,
},
},
methods: {
setAsReady(country) {
// console.log(country.id);
this.$emit("set-as-ready", country.id);
},
},
};
</script>
Если, например, нажата кнопка «Отметить как готовую», я хочу затем отобразить обновленную кнопку со статусом «Готов» для этой страны (в данном примере, Мексика) примерно так:
У кого-нибудь есть совет, как я могу сделать это логично и эффективно? У меня есть демо-версия codesandbox, доступная здесь: https://codesandbox.io/s/tender-black-zn9nt?file=/src/App.vue
Ответ №1:
Самый простой подход-это управление центральным состоянием данных. Установите новое свойство «статус» для элементов таблицы. Затем переключите это значение в зависимости от события, вызванного из таблицы.
<template v-if="country.status === 1">
<button :href="`#modal_${country.id}`" data-bs-toggle="modal">
Ready
</button>
</template>
methods: {
setAsReady(id) {
let country = this.countryChanges.find((e) => e.id === id);
country.status = 1;
},
},
См. поле Рабочие кодыи: https://codesandbox.io/s/dry-water-gl2q9?file=/src/App.vue
Комментарии:
1. Спасибо, это хорошо работает. Я взял ваш codesandbox и изменил его . Вы видите что-нибудь неправильное в этом подходе? codesandbox.io/s/patient-feather-uoqs9?file=/src/App.vue
2. Я посмотрел на код и коробку. это именно то, что я хотел сказать. выглядит чисто и просто. ваше здоровье!