Composant API de composition vue 3 avec un tableau de cases à cocher et tout basculer
P粉670838735
P粉670838735 2023-08-30 20:55:11
0
1
648
<p>Nous avons décidé de passer progressivement de KO à l'API de composition vue 3 en utilisant TypeScript, et j'essaie de comprendre l'anti-modèle des accessoires en mutation. J'ai un composant fonctionnel qui fait le travail prévu, mais fondamentalement, je veux confirmer que la façon dont il est écrit est l'approche recommandée. </p> <p>Un exemple assez simple est un composant de liste de cases à cocher avec une bascule : </p> <p>Ma plus grande question est de savoir si ce que je fais dans AppList.vue est correct, je fais <code>const internalModel = toRef(props.selected ?? []);</code> les variables indisponibles dans les composants et <code>selectedHandler</code> - événements et <code>toggleAll</code> - évaluent pour émettre OUT mais ici, je garde manuellement <code>selected</code> ;Modèle interne</Code> Utiliser deux variables pour la même chose semble fastidieux, mais en même temps, cela a du sens puisque le modèle interne n'a pas besoin d'interférer avec la vue. </p> <p>Je sais qu'il existe un exemple sur vuejs.org où vous pouvez utiliser un tableau sur <code>v-model</code> pour représenter plusieurs cases à cocher, mais ce n'est pas à l'intérieur d'un composant ou comme accessoire, donc Ce n’est pas exactement la même chose, cela semble plus compliqué. J'ai passé la majeure partie de la journée à essayer de bien faire les choses, mais il n'y a pas beaucoup de résultats de recherche vue 3 et je n'ai trouvé aucun résultat pour ce problème particulier. </p> <p>HomeView.vue :</p> <p> <pre class="brush:html;toolbar:false;"><ensemble de scripts lang="ts"> importer { ref } depuis 'vue' ; importez AppList, { tapez Item } depuis '@/components/AppList.vue' ; const fooItems = ref<Item[]>([ { identifiant : 1, nom : 'foo 1' }, { identifiant : 2, nom : 'foo 2' }, { identifiant : 3, nom : 'foo 3' }, { identifiant : 4, nom : 'foo 4' }, { identifiant : 5, nom : 'foo 5' }, ]); const fooSelected = ref<numéro[]>([]); </script> <modèle> <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;"><configuration du script lang="ts"> importer { calculé, toRef } depuis 'vue' ; interface d'exportation Article { identifiant : numéro ; nom : chaîne ; } const props = définirProps<{ éléments : élément [] ; sélectionné?: numéro[]; }>(); const internalModel = toRef(props.selected ?? []); const émet = définirEmits<{ 'mise à jour : sélectionné ' : [sélectionné : numéro []] ; }>(); const selectedHandler = (e: Événement) => { const target = <HTMLInputElement>e.target; if (props.selected && target) { si (target.checked) { submit('update:selected', [...props.selected, Number(target.value)]); } autre { émettre( 'mise à jour : sélectionnée', props.selected.filter((i: number) => i !== Number(target.value)) ); } } } ; const toggleAll = calculé ({ obtenir : () => internalModel.value.length === props.items.length && internalModel.value.every((s) => props.items.map((item) => item.id).includes(s)), définir : (valeur) => { si (valeur) { émettre( 'mise à jour : sélectionnée', props.items.map((i) => i.id) ); internalModel.value = props.items.map((i) => i.id); } autre { émettre('mise à jour:sélectionné', []); internalModel.value = []; } }, }); </script> <modèle> <étiquette> <input type="checkbox" v-model="toggleAll" /> tout basculer </étiquette> <ul> <li v-for="élément dans les éléments" :key="item.id"> <étiquette> <input type="checkbox" :value="item.id" v-model="internalModel" @change="selectedHandler" /> <span>id {{ item.name }}</span> </étiquette> ≪/li> </ul> Modèle interne : {{ Modèle interne }} </template></pre> </p>
P粉670838735
P粉670838735

répondre à tous(1)
P粉203792468

Il me semble que cela peut être fait d'une manière plus simple.
fooItems Il devrait probablement y avoir un état initial de « vérifié ».
Cliquez simplement selectedHandler中,只需调用emit().
toggleAll 最终将创建一个与 internalModel Fonctions utilisées ensemble.
Voici un exemple Vue SFC Playground.


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>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal