返回

一劳永逸:Vue 中的列表条件过滤组件封装指南

前端

在前端开发中,我们经常会遇到需要对列表进行条件过滤的需求。无论是商品列表、用户列表还是订单列表,都少不了搜索和筛选功能。如果每次都需要从头开始编写过滤逻辑,不仅耗时耗力,而且容易出错。

为了解决这个问题,我们可以封装一个通用的列表条件过滤组件。这样,无论遇到什么样的列表过滤需求,都可以直接使用这个组件,快速搭建出所需的功能。

组件设计

在设计组件之前,我们需要先明确组件的功能需求。我们希望组件能够具备以下功能:

  • 支持多种过滤条件,包括文本过滤、数值过滤、日期过滤等。
  • 支持多条件组合过滤,即可以同时指定多个过滤条件。
  • 支持过滤条件的动态添加和删除。
  • 支持过滤结果的实时更新。

组件实现

组件的实现分为两部分:模板和脚本。

模板

模板负责组件的界面展示。我们可以使用 Vue 的内置组件来实现模板,例如<input><select><button>等。

<template>
  <div class="filter-component">
    <div class="filter-item">
      <label for="name">名称:</label>
      <input type="text" id="name" v-model="filters.name">
    </div>
    <div class="filter-item">
      <label for="age">年龄:</label>
      <input type="number" id="age" v-model="filters.age">
    </div>
    <div class="filter-item">
      <label for="gender">性别:</label>
      <select id="gender" v-model="filters.gender">
        <option value="male"></option>
        <option value="female"></option>
      </select>
    </div>
    <div class="filter-button">
      <button @click="filter">筛选</button>
    </div>
  </div>
</template>

脚本

脚本负责组件的逻辑实现。我们可以使用 Vue 的内置方法和属性来实现脚本,例如data()methods()computed()等。

<script>
export default {
  data() {
    return {
      filters: {
        name: '',
        age: '',
        gender: ''
      }
    }
  },
  methods: {
    filter() {
      // 触发父组件的过滤事件
      this.$emit('filter', this.filters)
    }
  }
}
</script>

组件使用

组件的使用非常简单。我们只需要在父组件中导入组件,然后在模板中使用组件即可。

<template>
  <div class="parent-component">
    <filter-component @filter="handleFilter"></filter-component>
    <ul>
      <li v-for="item in filteredItems" :key="item.id">{{ item.name }}</li>
    </ul>
  </div>
</template>

<script>
import FilterComponent from './FilterComponent.vue'

export default {
  components: {
    FilterComponent
  },
  data() {
    return {
      items: [
        { id: 1, name: 'John Doe', age: 20, gender: 'male' },
        { id: 2, name: 'Jane Doe', age: 25, gender: 'female' },
        { id: 3, name: 'Peter Smith', age: 30, gender: 'male' },
        { id: 4, name: 'Mary Johnson', age: 35, gender: 'female' }
      ],
      filteredItems: []
    }
  },
  methods: {
    handleFilter(filters) {
      // 根据过滤条件过滤数据
      this.filteredItems = this.items.filter(item => {
        let flag = true
        if (filters.name) {
          flag = flag && item.name.includes(filters.name)
        }
        if (filters.age) {
          flag = flag && item.age === Number(filters.age)