Rumah  >  Soal Jawab  >  teks badan

Komponen kotak pilihan tersuai Vue 3 terikat pada tatasusunan nilai yang dipilih

Saya telah cuba mencipta komponen ringkas dengan kotak pilihan gaya dan label yang sepadan. Nilai (rentetan) semua kotak pilihan yang dipilih hendaklah disimpan dalam tatasusunan. Ini berfungsi untuk kotak semak html biasa:

<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>

Ia membawa kepada situasi yang diingini berikut:

Sekarang, jika saya menggantikan kotak pilihan ini dengan komponen kotak pilihan tersuai, saya tidak dapat membuatnya berfungsi. Jika saya menandai kotak, nilai yang dipancarkannya seolah-olah menggantikan tatasusunan status dan bukannya ditambah atau dialih keluar daripadanya, mengakibatkan perkara berikut:

Jadi atas sebab tertentu semua kotak semak ditandakan secara lalai dan apabila saya mengklik pada salah satu daripadanya, semuanya tidak ditanda dan nilai status 值会转到 false ,再次单击任何一个复选框将选中所有复选框并使 status true pergi ke salah, Mengklik mana-mana kotak semak sekali lagi akan memilih semua kotak pilihan dan menjadikan < kod >status true.

Sekarang, saya tahu bahawa mengembalikan sama ada kotak ditandakan dalam pelepasan mengembalikan nilai benar atau palsu, tetapi saya tidak faham cara Vue melakukan ini dengan kotak pilihan asli dan cara melaksanakan gelagat ini dengan komponen saya.

Ini ialah kod untuk komponen kotak semak saya:

<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>

Dan komponen induk hanya menggunakan templat yang berbeza:

<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>

Saya cuba melihat jawapan ini oleh StevenSiebert tetapi ia menggunakan objek dan saya mahu meniru kelakuan Vue asal menggunakan kotak semak asli.

Saya juga merujuk kepada dokumentasi rasmi Vue pada v-model tetapi tidak faham mengapa ini berfungsi secara berbeza untuk kotak pilihan asli berbanding untuk komponen.

P粉561749334P粉561749334302 hari yang lalu604

membalas semua(1)saya akan balas

  • P粉893457026

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

    Model v untuk setiap kotak pilihan adalah sama, mungkin serupa dengan coretan kod berikut:

    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>

    balas
    0
  • Batalbalas