<脚本设置lang="ts"> 从“vue”导入{计算,toRef}; 导出接口项{ 身份证号; 名称:字符串; } const 道具 = DefineProps<{ 项目:项目[]; 已选择?:编号[]; }>(); const internalModel = toRef(props.selected ?? []); const 发出 = DefineEmits<{ '更新:选定':[选定:数字[]]; }>(); const selectedHandler = (e: 事件) => { const target =e.target; if (props.selected && target) { if (目标.检查) { 发出('更新:选定',[...props.selected,Number(目标.值)]); } 别的 { 发射( '更新:已选择', props.selected.filter((i: number) => i !== Number(target.value)) ); } } }; consttoggleAll = 计算({ 得到:() => InternalModel.value.length === props.items.length && InternalModel.value.every((s) => props.items.map((item) => item.id).includes(s)), 设置:(值)=> { 如果(值){ 发射( '更新:已选择', props.items.map((i) => i.id) ); InternalModel.value = props.items.map((i) => i.id); } 别的 { 发出('更新:所选',[]); 内部模型.value = []; } }, }); </脚本> <模板> <标签> <输入类型=“复选框”v-model=“toggleAll”/> 全部切换 </标签>
- <标签> > id {{ item.name }}; </标签> </li> </ul> 内部模型:{{内部模型}} </模板></pre> </p>
P粉2037924682023-08-31 15:28:23
在我看来,这可以以某种更简单的方式完成。
fooItems
可能应该有一个初始状态“已检查”。
在selectedHandler
中,只需调用emit()
即可。
toggleAll
最终将创建一个与 internalModel
配合使用的函数。
这是一个示例 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>