cari

Rumah  >  Soal Jawab  >  teks badan

vue 3 komposisi api komponen dengan pelbagai kotak pilihan dan togol semua

<p>Kami telah memutuskan untuk beralih secara beransur-ansur dari kalah mati ke api gubahan vue 3 menggunakan skrip taip, dan saya cuba memahami anti-corak prop yang bermutasi. Saya mempunyai komponen berfungsi yang melakukan tugas yang dimaksudkan, tetapi pada asasnya saya ingin mengesahkan bahawa cara ia ditulis adalah pendekatan yang disyorkan. </p> <p>Contoh yang agak mudah ialah komponen senarai kotak semak dengan togol padanya: </p> <p>Soalan terbesar saya ialah jika apa yang saya lakukan dalam AppList.vue adalah betul, saya sedang melakukan <code>const internalModel = toRef(props.selected ?? []);</code> Pembolehubah yang tidak tersedia dalam komponen dan <kod>selectedHandler</code> - peristiwa dan <kod>toggleSemua</kod> ;Model Dalaman</Kod> Menggunakan dua pembolehubah untuk perkara yang sama terasa menyusahkan, tetapi pada masa yang sama ia masuk akal kerana model dalaman tidak perlu mengganggu pandangan. </p> <p>Saya tahu terdapat contoh di vuejs.org di mana anda boleh menggunakan tatasusunan pada <kod>v-model</code> untuk mewakili berbilang kotak pilihan, tetapi ia tidak berada di dalam komponen atau sebagai prop, jadi ia Tidak betul-betul sama, ini terasa lebih rumit. Saya menghabiskan sebahagian besar hari cuba untuk membetulkannya tetapi tidak banyak hasil carian vue 3 dan saya tidak menemui sebarang hasil sama sekali untuk masalah khusus ini. </p> <p>HomeView.vue:</p> <p> <pre class="brush:html;toolbar:false;"><script set lang="ts"> import { ref } daripada 'vue'; import AppList, { type Item } daripada '@/components/AppList.vue'; const fooItems = ref<Item[]>([ { id: 1, nama: 'foo 1' }, { id: 2, nama: 'foo 2' }, { id: 3, nama: 'foo 3' }, { id: 4, nama: 'foo 4' }, { id: 5, nama: 'foo 5' }, ]); const fooSelected = ref<nombor[]>([]); </skrip> <template> <AppList :items="fooItems" v-model:selected="fooSelected"></AppList> <div>fooselected: {{ fooSelected }}</div> </template></pre> </p> <p>组件/Applist.vue:</p> <p> <pre class="brush:html;toolbar:false;"><script setup lang="ts"> import { dikira, toRef } daripada 'vue'; antara muka eksport Item { nombor ID; nama: rentetan; } const props = defineProps<{ item: Item[]; dipilih?: nombor[]; }>(); const internalModel = toRef(props.selected ?? []); const emit = defineEmits<{ 'kemas kini:dipilih': [dipilih: nombor[]]; }>(); const selectedHandler = (e: Acara) => { const target = <HTMLInputElement>e.target; jika (props.dipilih && sasaran) { if (target.checked) { emit('kemas kini:dipilih', [...props.selected, Number(target.value)]); } lain { memancarkan ( 'kemas kini:dipilih', props.selected.filter((i: number) => i !== Number(target.value)) ); } } }; const toggleSemua = dikira({ dapatkan: () => internalModel.value.length === props.items.length && internalModel.value.every((s) => props.items.map((item) => item.id).includes(s)), set: (nilai) => { jika (nilai) { memancarkan ( 'kemas kini:dipilih', props.items.map((i) => i.id) ); internalModel.value = props.items.map((i) => i.id); } lain { emit('kemas kini:dipilih', []); internalModel.value = []; } }, }); </skrip> <template> <label> <input type="checkbox" v-model="toggleAll" /> togol semua </label> <ul> <li v-for="item in items" :key="item.id"> <label> <input type="checkbox" :value="item.id" v-model="internalModel" @change="selectedHandler" /> <span>id {{ item.name }}</span> </label> </li> </ul> internalModel: {{ internalModel }} </template></pre> </p>
P粉670838735P粉670838735452 hari yang lalu633

membalas semua(1)saya akan balas

  • P粉203792468

    P粉2037924682023-08-31 15:28:23

    Nampaknya ini boleh dilakukan dengan cara yang lebih mudah.
    fooItems Mungkin perlu ada keadaan awal "disemak".
    Hanya klik selectedHandler中,只需调用emit().
    toggleAll 最终将创建一个与 internalModel Fungsi digunakan bersama.
    Berikut ialah contoh Vue SFC Playground. < /p>


    HomeView.vue:

    <script setup lang="ts">
    import { ref } from 'vue';
    import AppList, { type Item } from './AppList.vue';
    
    const fooItems = ref<Item[]>([
      { id: 1, name: 'foo 1', checked: false },
      { id: 2, name: 'foo 2', checked: false },
      { id: 3, name: 'foo 3', checked: false },
      { id: 4, name: 'foo 4', checked: false },
      { id: 5, name: 'foo 5', checked: true },
    ]);
    const fooSelected = ref<number[]>([]);
    fooItems.value.map(item => item.checked && fooSelected.value.push(item.id))
    </script>
    
    <template>
      <AppList :items="fooItems" v-model:selected="fooSelected"></AppList>
      <div>fooselected: {{ fooSelected }}</div>
    </template>

    AppList.view:

    <script setup lang="ts">
    import { ref } from 'vue';
    
    export interface Item {
      id: number;
      name: string;
      checked: boolean
    }
    
    const props = defineProps<{
      items: Item[];
      selected: number[]
    }>();
    
    const emit = defineEmits(['update:selected']);
    
    const internalModel = ref(props.selected);
      
    const selectedHandler = () => emit('update:selected', internalModel.value);
    
    const toggleAll = ($event) => {
      internalModel.value = [];
      if ( ($event.target as HTMLInputElement).checked ) {
        props.items.map(item => internalModel.value.push(item.id));
      }
      emit('update:selected', internalModel.value);
    };
    </script>
    
    <template>
      <label>
        <input type="checkbox" @change="toggleAll($event)" :checked="internalModel.length === items.length" />
        toggle all
      </label>
      <ul>
        <li v-for="item in items" :key="item.id">
          <label>
            <input type="checkbox" :value="item.id" v-model="internalModel" @change="selectedHandler(item.id)" :checked="item.checked"/>
            <span>{{ item.name }}</span>
          </label>
        </li>
      </ul>
      internalModel: {{ internalModel }}
    </template>

    balas
    0
  • Batalbalas