删除按钮在 vue-bootstrap> 中生成多个确认模式

Delete button spawning multiple confirm modals in vue-bootstrap>

希望通过在此循环中对模态进行唯一引用来解决此问题,尝试在末尾给引用一个 grade.id,但不适用于带有 b 模态引用的字符串插值,也试过 :ref.

这是 vue 文件中的代码,下面是它的截图,当我按下删除成绩时,它会显示所有模态,因为模态在一个循环中。

 <template>
  <div>
    <b-form @submit="onSubmit" @reset="onReset">
      <b-row>
        <b-col class="underline">Add Grades</b-col>
      </b-row>
      <br />
      <b-row>
        <b-col>
          <b-form-group
            inline
            label-cols-sm="4"
            label-cols-lg="3"
            id="input-group-1"
            label="Select Farm:"
          >
            <b-form-select v-model="form.farm" :options="farms" required />
          </b-form-group>
        </b-col>
      </b-row>
      <b-row class="my-1">
        <b-col>
          <b-form-group label-cols-sm="4" label-cols-lg="3" label="name:">
            <b-form-input
              v-model="form.gradeName"
              size="sm"
              placeholder="name"
            ></b-form-input>
          </b-form-group>
        </b-col>
      </b-row>
      <b-row class="my-1">
        <b-col>
          <b-form-group
            label-cols-sm="4"
            label-cols-lg="3"
            label="min weight(gms):"
          >
            <b-form-input
              v-model="form.gradeMinWeight"
              size="sm"
              placeholder="minimum"
            ></b-form-input>
          </b-form-group>
        </b-col>
      </b-row>
      <b-row class="my-1">
        <b-col>
          <b-form-group
            label-cols-sm="4"
            label-cols-lg="3"
            label="max weight(gms):"
          >
            <b-form-input
              v-model="form.gradeMaxWeight"
              size="sm"
              placeholder="maximum"
            ></b-form-input>
          </b-form-group>
        </b-col>
      </b-row>
      <b-row class="my-1">
        <b-col>
          <b-form-group label-cols-sm="4" label-cols-lg="3" label="shape:">
            <b-form-select v-model="form.gradeShape">
              <option value="rounded">rounded</option>
              <option value="flat">flat</option>
              <option value="curve">curve</option>
            </b-form-select>
          </b-form-group>
        </b-col>
        <b-col>
          <b-form-group label-cols-sm="4" label-cols-lg="3" label="dimension:">
            <b-form-select v-model="form.gradeDimension">
              <option value="rounded">seeds</option>
              <option value="rounded">small</option>
              <option value="flat">medium</option>
              <option value="curve">large</option>
              <option value="curve">extra large</option>
              <option value="curve">jumbo</option>
            </b-form-select>
          </b-form-group>
        </b-col>
      </b-row>
      <b-row>
        <b-col>
          <b-button type="submit" variant="primary" block>Add</b-button>
        </b-col>
        <b-col>
          <b-button type="reset" variant="secondary" block>Cancel</b-button>
        </b-col>
      </b-row>
    </b-form>

    <br />
    <b-row>
      <b-col class="underline">My Grades</b-col>
    </b-row>
    <br />
    <div v-if="grades.length > 0">
      <b-card-group class="mb-4" v-for="grade in grades" :key="grade.id">
        <b-card :title="getTitle(grade)">
          <b-card-text class="list-card">
            {{ getProperties(grade) }}

            <span style="float: right">
              <b-button
                class="mr-1"
                type="reset"
                variant="danger"
                @click="showModal"
                size="sm"
              >
                <!-- Fix css to icon middle -->
                <b-icon icon="trash-fill" size="is-small"></b-icon>
              </b-button>

              <b-modal
                scrollable
                id="modal-delete-grade"
                ref=' `modal-delete-grade'
                centered
                @ok="actionDelete(grade.id)"
                class="d-block text-center"
                title="Confirm Delete Grade"
              >
                <p>
                  Confirm that you are about to delete grade
                  {{ getTitle(grade) }}
                </p>
              </b-modal>
            </span>
          </b-card-text>
        </b-card>
      </b-card-group>
    </div>
  </div>
</template>

<script>
import makeToast from "../../helper/toast";
import farmService from "../../service/FarmService";
import { getUser } from "@/helper/storage";
import userService from "@/service/UserService";
import DashEdit from "@/views/DashEdit";
import { contentMixin } from "@/mixins/contentMixin";
import { setupMixin } from "@/mixins/setupMixin";

export default {
  name: "AddSetupGrade",
  mixins: [contentMixin, setupMixin],
  data() {
    return {
      farms: [],
      grades: [],
      form: {
        farm: null,
        gradeName: null,
        gradeMinWeight: null,
        gradeMaxWeight: null,
        gradeShape: null,
        gradeDimension: null,
      },
    };
  },
  mounted() {
    this.getUserFarm();
    this.getGrades();
  },
  created() {
    this.getGrades();
  },
  methods: {
    async onSubmit(evt) {
      try {
        evt.preventDefault();
        let response = await farmService.addGrades({
          name: this.form.gradeName,
          farmId: this.form.farm.id,
          properties: {
            minWeight: this.form.gradeMinWeight,
            maxWeight: this.form.gradeMaxWeight,
            units: "gms",
            shape: this.form.gradeShape,
            dimension: this.form.gradeDimension,
          },
        });

        if (response.status === 200) {
          makeToast.call(
            this,
            "Success",
            "Successfully created grade",
            "success"
          );

          this.onReset();
          this.getGrades();
        }
      } catch (e) {
        console.log(`Error in creating grade. ${e}`);
        makeToast.call(this, "Error", "Error adding grade", "danger");
      }
    },
    onReset() {
      this.form.gradeName = null;
      this.form.gradeMinWeight = null;
      this.form.gradeMaxWeight = null;
      this.form.gradeShape = null;
      this.form.gradeDimension = null;
    },

    async getUserFarm() {
      try {
        let { id: userId } = getUser();
        let response = await userService.getFarmsOfUser(userId);
        let farmList = response.data.data;
        this.farms = farmList.map((each) => {
          return {
            value: { id: each.id, name: each.name },
            text: each.name,
          };
        });
        this.farms.push({ value: null, text: "Select Farm" });
      } catch (e) {
        console.log(`Error: ${e}`);
      }
    },

    getTitle(grade) {
      if (grade) {
        return grade.name + " - " + grade.alias;
      }
    },
    showModal(gradeId) {
      this.$bvModal.show("modal-delete-grade");
    },
    keyValString(obj) {
      return Object.entries(obj).reduce((str, [key, value], index) => {
        if (value) {
          if (str) str += ", ";
          str += `${key}: ${value}`;
        }
        return str;
      }, "");
    },

    getProperties(grade) {
      return (
        (grade && grade.properties && this.keyValString(grade.properties)) ||
        "No properties on grade."
      );
    },

    async getGrades() {
      try {
        let response = await farmService.getGrades();
        this.grades = response.data.data;
      } catch (e) {
        console.log(e);
      }
    },

    async actionDelete(id) {
      try {
        let response = await farmService.deleteGrade(id);
        this.$bvModal.hide("modal-delete-grade");
        this.getGrades();
      } catch (e) {
        console.log(e.response.data);
      }
    },
  },
};
</script>

<style scoped>
.underline {
  border-bottom: 2px solid currentColor;
  border-bottom-color: #d3d3d3;
  font-weight: bold;
  font-size: 16px;
}
.list-card {
  font-family: Open Sans;
  font-size: 14px;
  line-height: (48 / 24);
  letter-spacing: -0.046em;
  color: black;
}
.card-title {
  font-size: 1em;
  font-family: Open Sans;
}
</style>

您可以将模式移出循环。要传递点击成绩的数据,只需将其保存到您的数据中,例如作为“activeGrade”。在您的模式中,您显示“activeGrade”的数据。现在您可以使用点击的成绩特定数据打开(相同的)模式。

我稍微简化了您的代码以仅显示提出的问题:

<template>
  <div class="hello">
    <b-card-group class="mb-4" v-for="grade in grades" :key="grade.id">
      <b-card :title="grade.title">
        <b-card-text class="list-card">
          Some Text (grade properties)

          <span style="float: right">
            <b-button
              class="mr-1"
              type="reset"
              variant="danger"
              @click="showModal(grade)"
              size="sm">
              <!-- Fix css to icon middle -->
              <b-icon icon="trash-fill" size="is-small"></b-icon>
            </b-button>
          </span>
        </b-card-text>
      </b-card>
    </b-card-group>

    <b-modal v-if="activeGrade"
            scrollable
            id="modal-delete-grade"
            centered
            @ok="actionDelete(activeGrade.id)"
            class="d-block text-center"
            title="Confirm Delete Grade">
      <p>
        Confirm that you are about to delete grade
        {{ activeGrade.title }}
      </p>
    </b-modal>
  </div>
</template>

<script>
export default {
  data() {
    return {
      grades: [
        { id: 1, title: 'Grate 1' },
        { id: 2, title: 'Grate 2' },
        { id: 3, title: 'Grate 3' },
      ],
      activeGrade: null
    }
  },
  methods: {
    actionDelete(gradeId) {
      console.log('delete ' + gradeId)
    },
    showModal(grade) {
      this.activeGrade = grade

      this.$nextTick(() => {
        this.$bvModal.show("modal-delete-grade");
      })
    }
  }
}
</script>