vue 3 komposisi api komponen dengan pelbagai kotak pilihan dan togol semua
P粉670838735
2023-08-30 20:55:11
<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>
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.
HomeView.vue:
AppList.view: