日常开发中,经常会遇到下面场景:
思路:无分页列表是最简单的情况,列表直接绑定计算属性即可:
<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>
思路:来自父组件的列表可以认为是无分页列表,先在子组件中复制一份,追加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>