vue+elementUI 搜索栏公共组件封装,封装多搜索条件通用组件,超实用

发布时间 2023-06-09 11:35:24作者: 前端小菜鸡美哥

1、新建BaseSearch.vue文件

<!--
    *名称:弹窗的搜索条件组件
    *功能:methods
      1.点击搜索的方法:@search
      2.搜索条件 props : formItemList
-->

<template>
  <div class="dialog-search">
    <el-form
      :inline="true"
      ref="ruleForm"
      :model="formInline"
      class="demo-form-inline"
    >
      <el-form-item
        v-for="(item, index) in formItemList"
        :key="index"
        :label="item.label"
      >
        <!-- 下拉选择框 -->
        <el-select
          v-if="item.type == 'select'"
          v-model="formInline[item.param]"
          :multiple="item.multiple"
          placeholder="请选择"
          size="mini"
          clearable
        >
          <el-option
            v-for="(item2, index2) in item.selectOptions"
            :key="index2"
            :label="item2.text"
            :value="item2.value"
          ></el-option>
        </el-select>
        <!-- 下拉选择框end -->
        <!-- 输入框 -->
        <el-input
          v-if="item.type == 'input'"
          v-model="formInline[item.param]"
          size="mini"
          placeholder="请输入"
          clearable
        ></el-input>
        <!-- 输入框 -->
        <!-- 日期范围选择框 -->
        <el-date-picker
          v-if="
            item.type == 'daterange' ||
              item.type == 'datetimerange' ||
              item.type == 'date' ||
              item.type == 'datetime'
          "
          v-model="formInline[item.param]"
          :value-format="item.valueFormat || 'yyyy/MM/dd'"
          :format="item.format || 'yyyy/MM/dd'"
          clearable
          :type="item.type || ''"
          :range-separator="item.rangeSeparator || '至'"
          :start-placeholder="item.startPlaceholder"
          :end-placeholder="item.endPlaceholder"
          placeholder="请选择"
          size="mini"
        >
        </el-date-picker>
        <!-- 日期范围选择框end -->
        <!-- 级联选择器 -->
        <el-cascader
          v-if="item.type == 'cascader'"
          v-model="formInline[item.param]"
          size="mini"
          :options="item.options"
          :props="item.props"
          clearable
        ></el-cascader>
        <!-- 级联选择器end -->
      </el-form-item>
      <slot name="formItem"></slot>

      <el-form-item style="width:10rem">
        <el-button type="primary" size="mini" @click="onSubmit">查询</el-button>
        <el-button type="" size="mini" @click="resetForm('ruleForm')"
          >重置</el-button
        >
      </el-form-item>

      <!-- 可用于显示其他按钮 -->
      <slot name="formButton"></slot>
    </el-form>
  </div>
</template>

<script>
export default {
  name: "BaseSearch",
  props: {
    emitSearch: {
      // 是否立即执行搜索
      type: Boolean,
      default: false
    },
    formItemList: {
      type: Array,
      default() {
        return [
          {
            label: "下拉框",
            type: "select",
            selectOptions: [{ text: 111, value: 111 }],
            param: "company",
            defaultSelect: "222", // 下拉框默认选中项
            multiple: false
          },
          {
            label: "输入框",
            type: "input",
            param: "name"
          },
          {
            label: "日期范围",
            type: "daterange",
            param: "createtime"
          },
          {
            label: "级联选择器",
            type: "cascader",
            param: "cascader",
            options:[],
            props:{ multiple: false }
          }
        ];
      }
    }
  },
  data() {
    let formInline = {};
    for (const obj of this.formItemList) {
      formInline[obj.param] = obj.defaultSelect || "";
    }
    return {
      formInline
    };
  },
  watch: {
    emitSearch(newVal, oldVal) {
      // 是否立即触发搜索  用在弹窗中异步请求下拉框后  或者给下拉框赋值默认值后  需要用到这个方法
      if (newVal) {
        console.log("此时触发--立即执行搜索");
        this.$emit("search", this.formInline);
      }
    },
    formItemList: {
      handler(newVal, oldVal) {
        for (const obj of this.formItemList) {
          if (obj.defaultSelect) {
            formInline[obj.param] = obj.defaultSelect;
          }
        }
      },
      deep: true
    }
  },
  methods: {
    onSubmit() {
      // console.log('submit!',this.formInline);
      this.$emit("search", this.formInline);
    },
    resetForm(formName) {
      this.$refs[formName].resetFields();
      let formInline = {};
      for (const obj of this.formItemList) {
        // formInline[obj.param] = obj.defaultSelect || "";  // 重置时下拉框的默认值如果要保留就选用这个
        formInline[obj.param] = ""; // 所有筛选条件清空
      }
      this.formInline = formInline;

      this.$emit("search", this.formInline);
    }
  }
};
</script>

<style lang="scss" scoped>
.dialog-search {
  // margin: 0 1rem;
  margin-bottom: 20px;
  text-align: left;
  /deep/ .el-form-item__content {
    // width: 16rem;
    .el-input {
      width: 16rem;
    }
    .el-select {
      .el-input__inner {
        // height: 3.2rem;
        width: 16rem;
      }
    }
  }
}
</style>

2、使用的时候只需要引入BaseSearch.vue再传入formItemList,即能生成带下拉框和输入框的搜索条件,绑定search方法

<template>
  <div class="divBox">
    <el-card class="box-card">
      <BaseSearch :formItemList="formItemList" @search="search">
        <div slot="formButton">
          <el-button type="primary" size="mini" @click="add">新增</el-button>
          <el-button type="primary" size="mini">操作按钮</el-button>
        </div>
      </BaseSearch>
      <BaseTable
        :loading="loading"
        :tableData="tableData"
        :page="page"
        :tableOption.sync="tableOption"
        @page-change="getList"
      >
        <template slot="ranks" slot-scope="scope">
          <el-tag>{{ scope.row.name }}</el-tag>
        </template>
        <template slot="menu" slot-scope="scope">
          <el-button
            type="text"
            size="mini"
            icon="el-icon-delete"
            @click="deleteHandle(scope.row.id)"
            >删除</el-button
          >
        </template>
      </BaseTable>
    </el-card>
    <DialogA
      ref="DialogA"
      width="50%"
      type="form"
      :fullscreen="true"
      :title="title"
      footer
      :before-close="close"
      @closed="closed"
    >
      <template slot="body">
        <div>tree</div>
      </template>
      <template slot="footer">
        <el-button type="primary">保存</el-button>
        <el-button @click="close()">取消</el-button>
      </template>
    </DialogA>
  </div>
</template>

<script>
import BaseSearch from "@/components/Table/Search.vue";
import BaseTable from "@/components/Table/Table.vue";
import DialogA from "@/components/Table/Dialog.vue";


import { promoterListApi } from "@/api/promoter";

export default {
  name: "ceshi",
  components: { BaseSearch, BaseTable, DialogA },
  data() {
    return {
      formItemList: [
        {
          label: "下拉框单选:",
          type: "select",
          selectOptions: [{ text: 111, value: 111 }],
          param: "company"
        },
        {
          label: "化学品名称:",
          type: "input",
          param: "name"
        },
        {
          label: "下拉框多选:",
          type: "select",
          selectOptions: [{ text: 111, value: 111 }, { text: 222, value: 222 }],
          multiple: true,
          param: "parm222"
        },
        {
          label: "日期范围",
          type: "daterange",
          param: "createtime",
          startPlaceholder: "开始日期",
          endPlaceholder: "结束日期"
        },
        {
          label: "级联选择器",
          type: "cascader",
          param: "cascader",
          options: []
        }
      ],
      tableOption: [
        { label: "姓名", prop: "name" },
        { label: "性别", prop: "sex" },
        { label: "身份证号", prop: "idNumber" },
        { label: "职务", prop: "duty" },
        { label: "职级", prop: "ranks", solt: true }
      ],
      page: {
        total: 0,
        page: 1,
        limit: 10
      },
      tableData: [],
      loading: false,
      title: ''
    };
  },
  mounted() {
    // 此时请求下拉框的数据接口
    // axios。。。。
    //  this.formItemList[3].selectOptions = res.data
    // 其他下拉框的选项赋值
    //  这里判断 是否立即执行搜索
    // 全部下拉框的数据都塞进去后执行搜索
    // this.emitSearch=true
    this.getList();
  },

  methods: {
    getList(num) {
      this.loading = true;
      this.page.page = num ? num : this.page.page;
      promoterListApi(this.page)
        .then(res => {
          this.tableData = res.data.list;
          this.page.total = res.data.count;
          this.loading = false;
        })
        .catch(res => {
          this.$message.error(res.message);
          this.loading = false;
        });
    },
    search(params) {
      console.log(params);
      // 搜索条件改变时
    },
    deleteHandle() {},
    add() {
      this.$refs.DialogA.open();
      this.title = "新增";
    },
    close() {
      this.$refs.DialogA.close()
    },
    closed() {},
  }
};
</script>

<style lang="scss" scoped></style>

 

<template>
  <div class="divBox">
    <el-card class="box-card">
      <BaseSearch :formItemList="formItemList" @search="search">
        <div slot="formButton">
          <el-button type="primary" size="mini" @click="add">新增</el-button>
          <el-button type="primary" size="mini">操作按钮</el-button>
        </div>
      </BaseSearch>
      <BaseTable
        :loading="loading"
        :tableData="tableData"
        :page="page"
        :tableOption.sync="tableOption"
        @page-change="getList"
      >
        <template slot="ranks" slot-scope="scope">
          <el-tag>{{ scope.row.name }}</el-tag>
        </template>
        <template slot="menu" slot-scope="scope">
          <el-button
            type="text"
            size="mini"
            icon="el-icon-delete"
            @click="deleteHandle(scope.row.id)"
            >删除</el-button
          >
        </template>
      </BaseTable>
    </el-card>
    <DialogA
      ref="DialogA"
      width="50%"
      type="form"
      :fullscreen="true"
      :title="title"
      footer
      :before-close="close"
      @closed="closed"
    >
      <template slot="body">
        <div>tree</div>
      </template>
      <template slot="footer">
        <el-button type="primary">保存</el-button>
        <el-button @click="close()">取消</el-button>
      </template>
    </DialogA>
  </div>
</template>

<script>
import BaseSearch from "@/components/Table/Search.vue";
import BaseTable from "@/components/Table/Table.vue";
import DialogA from "@/components/Table/Dialog.vue";


import { promoterListApi } from "@/api/promoter";

export default {
  name: "ceshi",
  components: { BaseSearch, BaseTable, DialogA },
  data() {
    return {
      formItemList: [
        {
          label: "下拉框单选:",
          type: "select",
          selectOptions: [{ text: 111, value: 111 }],
          param: "company"
        },
        {
          label: "化学品名称:",
          type: "input",
          param: "name"
        },
        {
          label: "下拉框多选:",
          type: "select",
          selectOptions: [{ text: 111, value: 111 }, { text: 222, value: 222 }],
          multiple: true,
          param: "parm222"
        },
        {
          label: "日期范围",
          type: "daterange",
          param: "createtime",
          startPlaceholder: "开始日期",
          endPlaceholder: "结束日期"
        },
        {
          label: "级联选择器",
          type: "cascader",
          param: "cascader",
          options: []
        }
      ],
      tableOption: [
        { label: "姓名", prop: "name" },
        { label: "性别", prop: "sex" },
        { label: "身份证号", prop: "idNumber" },
        { label: "职务", prop: "duty" },
        { label: "职级", prop: "ranks", solt: true }
      ],
      page: {
        total: 0,
        page: 1,
        limit: 10
      },
      tableData: [],
      loading: false,
      title: ''
    };
  },
  mounted() {
    // 此时请求下拉框的数据接口
    // axios。。。。
    //  this.formItemList[3].selectOptions = res.data
    // 其他下拉框的选项赋值
    //  这里判断 是否立即执行搜索
    // 全部下拉框的数据都塞进去后执行搜索
    // this.emitSearch=true
    this.getList();
  },

  methods: {
    getList(num) {
      this.loading = true;
      this.page.page = num ? num : this.page.page;
      promoterListApi(this.page)
        .then(res => {
          this.tableData = res.data.list;
          this.page.total = res.data.count;
          this.loading = false;
        })
        .catch(res => {
          this.$message.error(res.message);
          this.loading = false;
        });
    },
    search(params) {
      console.log(params);
      // 搜索条件改变时
    },
    deleteHandle() {},
    add() {
      this.$refs.DialogA.open();
      this.title = "新增";
    },
    close() {
      this.$refs.DialogA.close()
    },
    closed() {},
  }
};
</script>

<style lang="scss" scoped></style>