使用element封装搜索分页组件

264 阅读5分钟

使用element封装搜索分页组件

动态组件说明文档

本文档描述了两个动态组件的实现:搜索组件表格组件。这两个组件是基于 Vue2 和 Element UI 实现的,支持灵活配置字段、按钮和操作。


1. 搜索组件(SearchComponent)

1.1 组件功能

搜索组件允许用户动态配置搜索字段和操作按钮。支持 inputselectdate-pickerinput-number 等字段类型,同时支持按钮的动态渲染。

1.2 组件配置项

searchFields
  • 类型:Array
  • 说明:搜索字段的配置数组。每个元素表示一个搜索框。
    • label:字段的标签
    • prop:字段对应的数据属性
    • type:字段类型,支持 inputselectdatenumber
    • placeholder:字段的提示文字
    • props:其他配置项(仅 select 类型需要)
buttons
  • 类型:Array
  • 说明:操作按钮的配置数组。每个元素表示一个按钮。
    • label:按钮的文本
    • type:按钮的类型,如 'primary''default''danger'
    • action:按钮点击时执行的操作方法
searchData
  • 类型:Object
  • 说明:存储当前的搜索条件

1.3 组件方法

  • handleSearch(): 搜索按钮点击时触发的方法,抛出搜索条件。
  • resetSearch(): 重置按钮点击时触发的方法,清空所有字段。

1.4 组件代码

1.4.1 子组件代码
<!-- 子组件 -->
<template>
  <el-row :gutter="20">
    <!-- 动态渲染搜索字段 -->
    <el-col :span="6" v-for="(item, index) in searchFields" :key="index">
      <component
        :is="getComponentType(item.type)"
        v-model="searchData[item.prop]"
        v-bind="item.props"
        :placeholder="item.placeholder"
        :clearable="true"
      />
    </el-col>

    <!-- 渲染功能按钮 -->
    <el-col :span="4" v-for="(button, index) in buttons" :key="index">
      <el-button :type="button.type" @click="handleButtonClick(button)">{{ button.label }}</el-button>
    </el-col>
  </el-row>
</template>

<script>
export default {
  props: {
    searchFields: {
      type: Array,
      required: true, // 接收父组件传入的动态字段配置
    },
    buttons: {
      type: Array,
      required: true, // 接收父组件传入的按钮配置
    },
  },
  data() {
    return {
      searchData: {}, // 存储搜索条件
    };
  },
  watch: {
    // 监听 searchFields 的变化,更新 searchData 对象
    searchFields: {
      handler(newFields) {
        newFields.forEach(field => {
          if (!this.searchData[field.prop]) {
            this.$set(this.searchData, field.prop, ''); // 初始化 searchData 的值
          }
        });
      },
      immediate: true,
    },
  },
  methods: {
    getComponentType(type) {
      // 根据字段类型返回对应的 Element UI 组件
      const componentMap = {
        input: 'el-input',
        select: 'el-select',
        date: 'el-date-picker',
        number: 'el-input-number',
      };
      return componentMap[type] || 'el-input'; // 默认使用 el-input
    },
    handleButtonClick(button) {
      // 根据按钮的配置调用对应的方法
      if (button.action && typeof button.action === 'function') {
        button.action(this.searchData); // 调用按钮对应的action方法,并传递当前的searchData
      }
    },
  },
};
</script>

<style scoped>
/* 根据需要自定义样式 */
</style>

1.4.2 父组件代码
<template>
  <div>
    <!-- 动态字段配置 -->
    <search-component 
      :searchFields="dynamicSearchFields"
      :buttons="buttons"
      @search="handleSearch"
    />
  </div>
</template>

<script>
import SearchComponent from './SearchComponent.vue';

export default {
  components: {
    SearchComponent,
  },
  data() {
    return {
      // 动态控制搜索字段
      dynamicSearchFields: [
        { label: '名称', prop: 'name', type: 'input', placeholder: '请输入名称' },
        { label: '类型', prop: 'type', type: 'select', placeholder: '请选择类型', props: { options: ['类型A', '类型B', '类型C'] } },
        { label: '开始时间', prop: 'startTime', type: 'date', placeholder: '请选择开始时间' },
        { label: '金额', prop: 'amount', type: 'number', placeholder: '请输入金额' },
        // 可以根据需求添加、删除字段
      ],
      // 动态控制按钮
      buttons: [
        { label: '搜索', type: 'primary', action: this.handleSearch },
        { label: '重置', type: 'default', action: this.resetSearch },
        { label: '新增', type: 'success', action: this.handleAdd },
        // 可以根据需求添加更多按钮
      ],
    };
  },
  methods: {
    handleSearch(searchData) {
      console.log('搜索条件:', searchData);
      // 处理搜索请求
    },
    resetSearch() {
      console.log('重置搜索');
      // 处理重置请求
    },
    handleAdd(searchData) {
      console.log('新增操作,当前搜索条件:', searchData);
      // 执行新增操作
    },
  },
};
</script>

1.5 解释说明

  • 动态渲染按钮:通过 buttons 配置传递每个按钮的 label、type 和 action。action 是按钮点击时执行的方法。
  • 动态按钮 action 方法:action 可以是任何一个方法(如 handleSearch、resetSearch、handleAdd 等),每个按钮对应一个操作。
  • 按钮点击处理:在 SearchComponent 中,通过 handleButtonClick 方法来处理按钮点击事件,并根据 button.action 来执行不同的操作方法。

2. 表格组件(TableComponent)

2.1 组件功能

表格组件支持动态渲染不同类型的操作按钮。每个操作按钮对应一个方法,支持对每一行数据执行操作(如删除、编辑、发布等)。

2.2 组件配置项

tableData
  • 类型:Array
  • 说明:表格的数据源。
columns
  • 类型:Array
  • 说明:表格列的配置。
    • label:列的标签
    • prop:列的数据字段
actions
  • 类型:Array
  • 说明:操作按钮的配置。
    • label:按钮的文本
    • type:按钮类型,如 'primary''danger'
    • action:按钮点击时执行的操作方法

2.3 组件方法

  • handleAction(action, row): 动态处理按钮点击事件,根据按钮配置执行不同的操作。

2.4 组件代码

2.4.1 子组件代码
<template>
  <el-table :data="tableData" style="width: 100%">
    <!-- 渲染表格的其他列 -->
    <el-table-column
      v-for="(column, index) in columns"
      :key="index"
      :label="column.label"
      :prop="column.prop"
    >
    </el-table-column>

    <!-- 渲染操作列 -->
    <el-table-column label="操作">
      <template slot-scope="scope">
        <el-button 
          v-for="(action, index) in actions"
          :key="index"
          :type="action.type || 'text'" 
          @click="handleAction(action, scope.row)"
        >
          {{ action.label }}
        </el-button>
      </template>
    </el-table-column>
  </el-table>
</template>

<script>
export default {
  props: {
    // 表格数据
    tableData: {
      type: Array,
      required: true,
    },
    // 表格列配置
    columns: {
      type: Array,
      required: true,
    },
    // 操作按钮配置
    actions: {
      type: Array,
      required: true,
    },
  },
  methods: {
    handleAction(action, row) {
      // 动态处理按钮点击事件
      if (action && typeof action.action === 'function') {
        action.action(row); // 将当前行数据作为参数传递给操作方法
      } else {
        console.warn(`操作方法未定义:${action.label}`);
      }
    },
  },
};
</script>

<style scoped>
/* 根据需要自定义样式 */
</style>

2.4.2 父组件代码
<template>
  <div>
    <!-- 表格组件 -->
    <table-component 
      :tableData="tableData"
      :columns="columns"
      :actions="actions"
    />
  </div>
</template>

<script>
import TableComponent from './TableComponent.vue';

export default {
  components: {
    TableComponent,
  },
  data() {
    return {
      // 表格数据
      tableData: [
        { id: 1, name: '张三', age: 28, status: 'active' },
        { id: 2, name: '李四', age: 34, status: 'inactive' },
        { id: 3, name: '王五', age: 23, status: 'active' },
      ],

      // 表格列配置
      columns: [
        { label: '姓名', prop: 'name' },
        { label: '年龄', prop: 'age' },
        { label: '状态', prop: 'status' },
      ],

      // 动态操作按钮配置
      actions: [
        { label: '编辑', type: 'primary', action: this.handleEdit },
        { label: '删除', type: 'danger', action: this.handleDelete },
        { label: '发布', type: 'success', action: this.handlePublish },
        // 其他操作
      ],
    };
  },
  methods: {
    // 编辑操作方法
    handleEdit(row) {
      console.log('编辑操作,当前行数据:', row);
      // 执行编辑操作
    },
    
    // 删除操作方法
    handleDelete(row) {
      console.log('删除操作,当前行数据:', row);
      // 执行删除操作
    },

    // 发布操作方法
    handlePublish(row) {
      console.log('发布操作,当前行数据:', row);
      // 执行发布操作
    },
  },
};
</script>

2.5 解释说明

  • 动态渲染操作按钮:通过传递 actions 配置数组,每个按钮会动态渲染并绑定相应的 action 方法。当点击按钮时,handleAction 方法会根据按钮的 action 执行不同的操作,并且将当前行的数据(scope.row)作为参数传递给对应的操作方法。
  • actions 配置项:每个操作按钮配置包含以下字段:
    • label:按钮的名称,显示在按钮上。
    • type:按钮类型(如 'primary'、'danger'、'success' 等)。
    • action:按钮对应的操作方法(是一个函数)。
  • 动态操作方法:每个操作(如编辑、删除、发布等)对应一个方法,在父组件中定义。通过 this.handleEdit、this.handleDelete 等方法来处理不同的操作。

3. 总结

  • 动态搜索组件:支持多种类型的搜索字段,并且可以灵活配置操作按钮(如“搜索”、“重置”)。
  • 动态表格组件:支持动态渲染表格的操作按钮,并根据每个按钮的配置执行相应的操作(如“编辑”、“删除”)。

4.模拟电力交易申报策略分页表格设计

4.1 搜索功能

在电力交易的申报策略表格中,我们需要提供一系列的搜索字段,常见的搜索项可能包括:

  • 申报策略名称(输入框)
  • 申报时间范围(日期选择器)
  • 策略状态(下拉框:待审核、已通过、已驳回等)
  • 所属电厂(选择框)
4.2 表格功能

表格展示内容为:

  • 申报策略名称
  • 所属电厂
  • 申报时间
  • 状态
  • 操作按钮(如编辑、删除、发布等)
4.3 表格功能

搜索组件配置

  • 申报策略名称:用户可以输入策略名称进行搜索。
  • 申报时间:用户可以选择时间范围进行搜索。
  • 策略状态:提供待审核、已通过、已驳回等状态供选择。
  • 所属电厂:提供电厂A、电厂B等供选择。

表格组件配置

  • 列配置:包括申报策略名称、所属电厂、申报时间和状态。
  • 操作按钮:包括编辑、删除和发布操作按钮。

方法

  • handleSearch:根据搜索条件获取数据,并展示到表格中。
  • handleReset:重置搜索条件。
  • handleEdit、handleDelete、handlePublish:对应的操作方法,分别是编辑、删除和发布。

分页功能

  • 需要根据数据量,分页表格的功能可以进一步扩展。您可以使用 el-pagination 组件来实现分页。
<template>
  <div>
    <!-- 搜索区域 -->
    <search-component
      :searchFields="searchFields"
      :buttons="searchButtons"
      @search="handleSearch"
    />
    
    <!-- 表格区域 -->
    <table-component
      :tableData="tableData"
      :columns="columns"
      :actions="actions"
    />
  </div>
</template>

<script>
import SearchComponent from './SearchComponent';
import TableComponent from './TableComponent';

export default {
  components: {
    SearchComponent,
    TableComponent,
  },
  data() {
    return {
      // 搜索字段配置
      searchFields: [
        {
          label: '申报策略名称',
          prop: 'name',
          type: 'input',
          placeholder: '请输入策略名称',
        },
        {
          label: '申报时间',
          prop: 'date',
          type: 'date',
          placeholder: '请选择时间范围',
        },
        {
          label: '策略状态',
          prop: 'status',
          type: 'select',
          placeholder: '请选择状态',
          props: {
            options: [
              { label: '待审核', value: 'pending' },
              { label: '已通过', value: 'approved' },
              { label: '已驳回', value: 'rejected' },
            ],
          },
        },
        {
          label: '所属电厂',
          prop: 'plant',
          type: 'select',
          placeholder: '选择电厂',
          props: {
            options: [
              { label: '电厂A', value: 'plantA' },
              { label: '电厂B', value: 'plantB' },
            ],
          },
        },
      ],
      
      // 搜索按钮
      searchButtons: [
        {
          label: '搜索',
          type: 'primary',
          action: this.handleSearch,
        },
        {
          label: '重置',
          type: 'default',
          action: this.handleReset,
        },
      ],
      
      // 表格数据
      tableData: [],
      
      // 表格列配置
      columns: [
        { label: '申报策略名称', prop: 'name' },
        { label: '所属电厂', prop: 'plant' },
        { label: '申报时间', prop: 'date' },
        { label: '状态', prop: 'status' },
      ],
      
      // 表格操作按钮配置
      actions: [
        {
          label: '编辑',
          type: 'primary',
          action: this.handleEdit,
        },
        {
          label: '删除',
          type: 'danger',
          action: this.handleDelete,
        },
        {
          label: '发布',
          type: 'success',
          action: this.handlePublish,
        },
      ],
    };
  },
  methods: {
    // 搜索操作
    handleSearch(searchData) {
      console.log('搜索数据:', searchData);
      // 调用 API 获取数据(这里假设是静态数据)
      this.tableData = this.fetchData(searchData);
    },
    
    // 重置搜索框
    handleReset() {
      this.searchFields.forEach(field => {
        this.$set(this.searchData, field.prop, '');
      });
      this.handleSearch(this.searchData);
    },

    // 编辑操作
    handleEdit(row) {
      console.log('编辑策略:', row);
      // 编辑策略的逻辑
    },

    // 删除操作
    handleDelete(row) {
      console.log('删除策略:', row);
      // 删除策略的逻辑
    },

    // 发布操作
    handlePublish(row) {
      console.log('发布策略:', row);
      // 发布策略的逻辑
    },

    // 模拟获取数据的方法
    fetchData(searchData) {
      // 模拟返回的表格数据,实际中可以从 API 获取数据
      return [
        {
          name: '策略1',
          plant: '电厂A',
          date: '2023-01-01',
          status: 'pending',
        },
        {
          name: '策略2',
          plant: '电厂B',
          date: '2023-02-01',
          status: 'approved',
        },
      ];
    },
  },
};
</script>