suchen

Heim  >  Fragen und Antworten  >  Hauptteil

Benutzerdefinierte Vue 3-Kontrollkästchenkomponente, die an ein Array ausgewählter Werte gebunden ist

Ich habe versucht, eine einfache Komponente mit einem gestalteten Kontrollkästchen und einer entsprechenden Beschriftung zu erstellen. Die Werte (Strings) aller ausgewählten Kontrollkästchen sollten in einem Array gespeichert werden. Dies funktioniert für einfache HTML-Kontrollkästchen:

<template>
  <div>
    <div class="mt-6">
      <div>
        <input type="checkbox" value="EVO" v-model="status" /> <label for="EVO">EVO</label>
      </div>
      <div>
        <input type="checkbox" value="Solist" v-model="status" /> <label for="Solist">Solist</label>
      </div>
      <div>
        <input type="checkbox" value="SPL" v-model="status" /> <label for="SPL">SPL</label>
      </div>
    </div>
    <div class="mt-3">{{status}}</div>
  </div>
</template>

<script setup>
  import { ref } from 'vue'
  
  let status = ref([]);
</script>

Es führt zu folgender gewünschter Situation:

Wenn ich diese Kontrollkästchen nun durch eine benutzerdefinierte Kontrollkästchenkomponente ersetze, funktioniert es nicht. Wenn ich ein Kästchen ankreuze, scheint der ausgegebene Wert das status-Array zu ersetzen, anstatt ihm hinzugefügt oder daraus entfernt zu werden, was zu Folgendem führt:

Aus irgendeinem Grund sind also alle Kontrollkästchen standardmäßig aktiviert, und wenn ich auf eines davon klicke, werden sie alle deaktiviert und der status 值会转到 false ,再次单击任何一个复选框将选中所有复选框并使 status true-Wert geht auf false. Wenn ich erneut auf ein Kontrollkästchen klicke, werden alle Kontrollkästchen ausgewählt und < Code >Status wahr.

Jetzt weiß ich, dass die Rückgabe in der Ausgabe unabhängig davon, ob das Kontrollkästchen aktiviert ist, einen wahren oder falschen Wert zurückgibt, aber ich verstehe nicht, wie Vue dies mit nativen Kontrollkästchen macht und wie ich dieses Verhalten mit meiner Komponente implementieren kann.

Dies ist der Code für meine Checkbox-Komponente:

<template>
  <div class="mt-1 relative">
    <input
      type="checkbox"
      :id="id ?? null"
      :name="name"
      :value="value"
      :checked="modelValue ?? false"
      class="bg-gray-200 text-gold-500 rounded border-0 w-5 h-5 mr-2 focus:ring-2 focus:ring-gold-500"
      @input="updateValue"
    />
    {{ label }}
  </div>
</template>

<script setup>
  const props = defineProps({
    id: String,
    label: String,
    name: String,
    value: String,
    errors: Object,
    modelValue: Boolean,
  })
  
  const emit = defineEmits(['update:modelValue'])
  
  const updateValue = function(event) {
    emit('update:modelValue', event.target.checked)
  }
</script>

Und die übergeordnete Komponente verwendet einfach eine andere Vorlage:

<template>
  <div>
    <div class="mt-6">
      <Checkbox v-model="status" value="EVO" label="EVO" name="status"  />
      <Checkbox v-model="status" value="Solist" label="Solist" name="status" />
      <Checkbox v-model="status" value="SPL" label="SPL" name="status" />
    </div>
    <div class="mt-3">{{status}}</div>
  </div>
</template>

Ich habe versucht, mir diese Antwort von StevenSiebert anzusehen, aber sie verwendet ein Objekt und ich möchte das ursprüngliche Vue-Verhalten mithilfe nativer Kontrollkästchen reproduzieren.

Ich habe auch auf die offizielle Vue-Dokumentation zu v-model verwiesen, verstehe aber nicht, warum dies bei nativen Kontrollkästchen anders funktioniert als bei Komponenten.

P粉561749334P粉561749334363 Tage vor673

Antworte allen(1)Ich werde antworten

  • P粉893457026

    P粉8934570262023-12-22 15:09:31

    每个复选框的 v-model 都是相同的,可能类似于以下代码片段:

    const { ref } = Vue
    const app = Vue.createApp({
      setup() {
        const status = ref([{label: 'EVO', status: false}, {label: 'Solist', status: false}, {label: 'SPL', status: false}])
        return {
          status
        }
      },
    })
    app.component('Checkbox', {
      template: `
        <div class="mt-1 relative">
          <input
            type="checkbox"
            :id="id ?? null"
            :name="name"
            :value="value"
            :checked="modelValue ?? false"
            class="bg-gray-200 text-gold-500 rounded border-0 w-5 h-5 mr-2 focus:ring-2 focus:ring-gold-500"
            @input="updateValue"
          />
          {{ label }}
        </div>
      `,
      props:{
        id: String,
        label: String,
        name: String,
        value: String,
        errors: Object,
        modelValue: Boolean,
      },
      setup(props, {emit}) {
        const updateValue = function(event) {
          emit('update:modelValue', event.target.checked)
        }
        return {
          updateValue
        }
      }
    })
    app.mount('#demo')
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/tailwindcss/2.2.18/tailwind.min.css" integrity="sha512-JfKMGsgDXi8aKUrNctVLIZO1k1iMC80jsnMBLHIJk8104g/8WTaoYFNXWxFGV859NY6CMshjktRFklrcWJmt3g==" crossorigin="anonymous" referrerpolicy="no-referrer" />
    <script src="https://unpkg.com/vue@3/dist/vue.global.prod.js"></script>
    <div id="demo">
      <div>
        <div class="mt-6" v-for="box in status">
          <Checkbox v-model="box.status" :value="box.label" :label="box.label" name="status"></Checkbox>
        </div>
        <div class="mt-3">{{status}}</div>
      </div>
    </div>

    Antwort
    0
  • StornierenAntwort