vue场景 无分页列表条件过滤,子组件多选来自父组件的列表

日常开发中,经常会遇到下面场景:

  1. 页面加载一个无分页列表,同时工具栏设置多个条件可对列表过滤的场景(典型的就是关键字模糊查询)
  2. 父组件传给子组件列表,子组件中需要多选列表多选,选择结果返回父组件

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>

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2023-12-25 06:44:06       94 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2023-12-25 06:44:06       100 阅读
  3. 在Django里面运行非项目文件

    2023-12-25 06:44:06       82 阅读
  4. Python语言-面向对象

    2023-12-25 06:44:06       91 阅读

热门阅读

  1. 边缘服务器

    2023-12-25 06:44:06       41 阅读
  2. 微机原理2答案

    2023-12-25 06:44:06       55 阅读
  3. 爱与愁的心痛

    2023-12-25 06:44:06       62 阅读
  4. linux 内核长延时方法

    2023-12-25 06:44:06       48 阅读
  5. UDP Ping程序实现--第3关:服务端模拟丢包事件

    2023-12-25 06:44:06       62 阅读
  6. Go map如何排序

    2023-12-25 06:44:06       60 阅读
  7. Leetcode 2977. Minimum Cost to Convert String II

    2023-12-25 06:44:06       65 阅读