日常开发中,经常会遇到下面场景:
- 页面加载一个无分页列表,同时工具栏设置多个条件可对列表过滤的场景(典型的就是关键字模糊查询)
- 父组件传给子组件列表,子组件中需要多选列表多选,选择结果返回父组件
1 无分页列表过滤
思路:无分页列表是最简单的情况,列表直接绑定计算属性即可:
<template><div class="page-container"><el-input v-model="keyword" placeholder="请输入关键字"></el-input><div class="list" v-for="item in filteredList" :key="item.id"><span>{{ item.id }}</span><span>{{ item.name }} </span><span>{{ item.status }}</span></div></div>
</template><script lang="ts" setup>
const keyword = ref('');
const list = ref([{id:1,name:'张三',status:'正常',},{id:2,name:'李四',status:'正常',}, {id:3,name:'王五',status:'休假',}, {id:4,name:'林六',status:'休假',}, {id:5,name:'徐七',status:'休假',}
]);
const filteredList = computed(()=>{return list.value.filter(item=>item.name.includes(keyword.value))
})</script>
<style lang="scss" scoped>
.page-container {width: 300px;height: 300px;.list{display: flex;span{+span{margin-left:20px;}}}
}
</style>
同理:多条件时,只是修改计算属性中的逻辑运算即可
<template><div class="page-container"><el-input v-model="keyword" placeholder="请输入关键字"></el-input><el-radio-group v-model="status"><el-radio :label="'全部'">全部</el-radio><el-radio :label="'正常'">正常</el-radio><el-radio :label="'休假'">休假</el-radio></el-radio-group><div class="list" v-for="item in filteredList" :key="item.id"><span>{{ item.id }}</span><span>{{ item.name }} </span><span>{{ item.status }}</span></div></div>
</template><script lang="ts" setup>
const keyword = ref('');
const status=ref('正常')
const list = ref([{id:1,name:'张三',status:'正常',},{id:2,name:'李四',status:'正常',}, {id:3,name:'王五',status:'休假',}, {id:4,name:'林六',status:'休假',}, {id:5,name:'徐七',status:'休假',}, {id:6,name:'徐八',status:'正常',}
]);
const filteredList = computed(()=>{let baseCondition=item=>item.name.includes(keyword.value);let condition=baseCondition;if(status.value!=='全部'){condition=item=>baseCondition(item) && item.status===status.value}return list.value.filter(condition)
})</script>
<style lang="scss" scoped>
.page-container {width: 300px;height: 300px;.list{display: flex;span{+span{margin-left:20px;}}}
}
</style>
2 子组件中多选来自父组件的列表
思路:来自父组件的列表可以认为是无分页列表,先在子组件中复制一份,追加check属性,然后在list中绑定
不正确的处理(修改props):
1 在子组件中给props中的list追加check属性,绑定list
2 在父组件中给list追加check属性,子组件绑定list,这样点击checkbox依然会修改props
<template><div class="page-container"><el-input v-model="keyword" placeholder="请输入关键字"></el-input><el-radio-group v-model="status"><el-radio :label="'全部'">全部</el-radio><el-radio :label="'正常'">正常</el-radio><el-radio :label="'休假'">休假</el-radio></el-radio-group><div class="list" v-for="item in filteredList" :key="item.id"><el-checkbox v-model="item.check"> </el-checkbox><span>{{ item.id }} </span><span>{{ item.name }} </span><span>{{ item.status }} </span></div></div>
</template><script lang="ts" setup>
const keyword = ref("");
const status = ref("全部");
const props = defineProps({list: {type: Array,default: () => [{id: 1,name: "张三",status: "正常",},{id: 2,name: "李四",status: "正常",},{id: 3,name: "王五",status: "休假",},{id: 4,name: "林六",status: "休假",},{id: 5,name: "徐七",status: "休假",},{id: 6,name: "徐八",status: "正常",},],},
});const copyList = ref(props.list.map((item) => ({...item,check: false,}))
);const filteredList = computed(()=>{let baseCondition=item=>item.name.includes(keyword.value);let condition=baseCondition;if(status.value!=='全部'){condition=item=>baseCondition(item) && item.status===status.value}return copyList.value.filter(condition)
})watch(filteredList.value, (val, old) => {console.log("val", val.filter((item) => item.check).map((item) => item.id));emit("selectionChange",val.filter((item) => item.check).map((item) => item.id));
});const emit = defineEmits(["selectionChange"]);
</script>
<style lang="scss" scoped>
.page-container {width: 300px;height: 300px;.list {display: flex;.el-checkbox,span {+ span {margin-left: 20px;}}}
}
</style>