vue查询区表单公用封装。。。

51 阅读3分钟

一.组件调用

1.引入组件

import CardSearch from "@/components/CardSearch/index";

2.引入配置文件

import { searchData } from "./config/common.js";

3.template、script写法

<script>
export default {
  components: { CardSearch },
  data() {
    return {
      searchData: searchData,
      queryParams: {},
     }
   },
   methods: {
   search(params) {
     console.log(params)
    },
    reset() {
      this.queryParams = JSON.parse(JSON.stringify(this.queryParams));
      this.search(this.queryParams);
    },
   }
}
</script>
<template>
 <CardSearch
    :searchData="searchData"
    :searchObj="queryParams"
    @search="search"
    @reset="reset"
   />
</template>

2.配置文件

1.在js文件中进行配置json

export const searchData = [
  {
    placeholder: "请选择月份",
    type: "month",
    model: "",
    valueFormat: "yyyy-MM", // 定义日期格式
    default: "",
  },
  {
    placeholder: "请输入",
    type: "input",
    model: "",
  },
  {
    placeholder: "请选择",
    type: "select",
    model: "",
    default: "", // 默认字段赋值
    list: [],
  },
];

3.公用组件

<template>
  <!-- 头部筛选栏 组件 -->
  <div style="margin-bottom: 20px">
    <el-row :gutter="24">
      <el-col :span="24">
        <el-card>
          <el-row :gutter="24">
            <el-col :span="24">
              <!-- color: $store.state.settings.theme, -->
              <p
                :style="{
                  color: $store.state.settings.theme,
                  fontSize: '16px',
                }"
              >
                基本查询条件
              </p>
            </el-col>
          </el-row>
          <el-row :gutter="24">
            <el-col
              :span="4"
              v-for="item in searchData"
              :key="item.model"
              v-show="!item.isRowShow"
            >
              <el-input
                v-if="item.type == 'input'"
                v-model.trim="searchObj[item.model]"
                :placeholder="item.placeholder"
                size="small"
                clearable
                @keyup.enter.native="search"
                :maxlength="item.maxLength ? item.maxLength : 30"
              >
              </el-input>
              <!-- 插槽 -->
              <slot
                v-if="item.type == 'slot'"
                :name="item.model"
                :content="item"
              ></slot>
              <!-- 项目id  根据关键词模糊搜索 -->
              <el-select
                v-if="item.type == 'inputSelect' && item.model == 'projectId'"
                v-model="searchObj[item.model]"
                size="small"
                clearable
                filterable
                remote
                reserve-keyword
                placeholder="请选择项目,可远程搜索"
                :remote-method="remoteMethod"
                style="width: 100%"
                :loading="projectIdLoading"
              >
                <el-option
                  v-for="item in projectIdOptions"
                  :key="item.id"
                  :label="item.name"
                  :value="item.id"
                >
                </el-option>
              </el-select>
              <!-- 主体公司  根据关键词模糊搜索 -->
              <el-select
                v-if="item.type == 'inputSelect' && item.model == 'companyId'"
                v-model="searchObj[item.model]"
                size="small"
                clearable
                filterable
                reserve-keyword
                :placeholder="item.placeholder"
                style="width: 100%"
                :loading="projectIdLoading"
              >
                <el-option
                  v-for="item in item.list"
                  :key="item.id"
                  :label="item.label"
                  :value="item.value"
                >
                </el-option>
              </el-select>
              <!-- //下拉框 -->
              <el-select
                v-model="searchObj[item.model]"
                :clearable="!item.noClear"
                :placeholder="item.placeholder"
                v-if="item.type == 'select' && !item.multiple"
                size="small"
                style="width: 100%"
                filterable
              >
                <template v-for="item in item.list">
                  <el-option
                    v-if="item.statusString"
                    :key="item.status"
                    :label="item.statusString"
                    :value="item.status"
                  >
                  </el-option>
                  <!-- 因为status和其他选项矛盾 所有单独拿出来判断 后期需要后端同步枚举 属性名 -->
                  <el-option
                    v-else-if="item.dictLabel"
                    :key="item.dictValue"
                    :label="item.dictLabel"
                    :value="item.dictValue"
                  >
                  </el-option>
                  <!-- 招标 页 投标人 -->
                  <el-option
                    v-else-if="item.company"
                    :key="item.id"
                    :label="item.regName"
                    :value="item.id"
                  >
                  </el-option>
                  <!-- 招标 页 招标人 -->
                  <el-option
                    v-else-if="item.customer"
                    :key="item.id"
                    :label="item.name"
                    :value="item.id"
                  >
                  </el-option>
                  <!-- 所属部门 -->
                  <el-option
                    v-else-if="item.orgName"
                    :key="item.id"
                    :label="item.orgName"
                    :value="item.id"
                  >
                  </el-option>
                  <!-- 所属业务线 -->
                  <el-option
                    v-else-if="item.leaderName"
                    :key="item.id"
                    :label="item.name"
                    :value="item.id"
                  >
                  </el-option>
                  <el-option
                    v-else
                    :key="item.value"
                    :label="item.label"
                    :value="item.value"
                  >
                  </el-option>
                </template>
              </el-select>
              <!-- //下拉框复选 -->
              <el-select
                v-model="searchObj[item.model]"
                :placeholder="item.placeholder"
                v-if="item.type == 'select' && item.multiple"
                size="small"
                style="width: 100%"
                multiple
              >
                <template v-for="item in item.list">
                  <el-option
                    v-if="item.statusString"
                    :key="item.status"
                    :label="item.statusString"
                    :value="item.status"
                  >
                  </el-option>
                  <!-- 因为status和其他选项矛盾 所有单独拿出来判断 后期需要后端同步枚举 属性名 -->
                  <el-option
                    v-else-if="item.dictLabel"
                    :key="item.dictValue"
                    :label="item.dictLabel"
                    :value="item.dictValue"
                  >
                  </el-option>
                  <!-- 招标 页 投标人 -->
                  <el-option
                    v-else-if="item.company"
                    :key="item.id"
                    :label="item.regName"
                    :value="item.id"
                  >
                  </el-option>
                  <!-- 招标 页 招标人 -->
                  <el-option
                    v-else-if="item.customer"
                    :key="item.id"
                    :label="item.name"
                    :value="item.id"
                  >
                  </el-option>
                  <!-- 所属部门 -->
                  <el-option
                    v-else-if="item.orgName"
                    :key="item.id"
                    :label="item.orgName"
                    :value="item.id"
                  >
                  </el-option>
                  <!-- 所属业务线 -->
                  <el-option
                    v-else-if="item.leaderName"
                    :key="item.id"
                    :label="item.name"
                    :value="item.id"
                  >
                  </el-option>
                  <el-option
                    v-else
                    :key="item.value"
                    :label="item.label"
                    :value="item.value"
                  >
                  </el-option>
                </template>
              </el-select>
              <!-- 时间区间选择 -->
              <el-date-picker
                v-if="item.type == 'daterange'"
                v-model="searchObj[item.model]"
                :type="item.type"
                unlink-panels
                range-separator="至"
                start-placeholder="开始日期"
                end-placeholder="结束日期"
                size="small"
                clearable
                value-format="yyyy-MM-dd"
                :picker-options="pickerOptions"
              />
              <!-- 单个日期选择 -->
              <el-date-picker
                v-else-if="item.type == 'date'"
                v-model="searchObj[item.model]"
                :type="item.type"
                style="width: 100%"
                size="small"
                clearable
                value-format="yyyy-MM-dd"
                :placeholder="item.placeholder"
              />
              <!-- 单个年份选择 -->
              <el-date-picker
                v-else-if="item.type == 'year'"
                v-model="searchObj[item.model]"
                :type="item.type"
                style="width: 100%"
                size="small"
                clearable
                value-format="yyyy"
                :placeholder="item.placeholder"
                :picker-options="pickerOptions"
              />
              <!-- 月份选择 -->
              <el-date-picker
                v-else-if="item.type == 'month' && item.showYear"
                v-model="searchObj[item.model]"
                style="width: 100%"
                :type="item.type"
                size="small"
                clearable
                value-format="yyyy-MM-dd"
                format="yyyy-MM"
                :placeholder="item.placeholder"
                :picker-options="
                  item.pickerOptions ? item.pickerOptions : pickerOptions
                "
              />
              <!-- 单个月份选择 -->
              <el-date-picker
                v-else-if="item.type == 'month'"
                v-model="searchObj[item.model]"
                :type="item.type"
                style="width: 100%"
                size="small"
                clearable
                :value-format="item.valueFormat || 'yyyy-M'"
                format="yyyy-MM"
                :placeholder="item.placeholder"
                :picker-options="pickerOptions"
                @change="changeDate($event)"
              />
              <!-- 选择甲方 -->
              <el-tooltip
                v-if="item.type == 'corporation'"
                class="item"
                effect="dark"
                :disabled="searchObj[item.model] ? false : true"
                :content="searchObj[item.model]"
                placement="top"
              >
                <Corporation
                  :title="item.placeholder || '请选择甲方'"
                  :CorporationName="searchObj[item.model]"
                  @selectCorporation="selectCorporation"
                />
              </el-tooltip>


              <!-- 选择乙方 -->
              <el-tooltip
                v-if="item.type == 'supplier'"
                class="item"
                effect="dark"
                :disabled="searchObj[item.model] ? false : true"
                :content="searchObj[item.model]"
                placement="top"
              >
                <Supplier
                  :title="item.placeholder || '请选择乙方'"
                  :type="item.requestType || 'getSupplier'"
                  :SupplierName="searchObj[item.model]"
                  @selectCompany="selectCompany"
                />
              </el-tooltip>
            </el-col>
            <el-col :span="6" style="text-align: right">
              <slot name="button"></slot>
              <el-button type="primary" size="small" @click="search">
                <i class="el-icon-search"></i>
                搜索
              </el-button>
              <el-button size="small" @click="reset">
                <i class="el-icon-refresh-left"></i>
                重置
              </el-button>
            </el-col>
          </el-row>
        </el-card>
      </el-col>
    </el-row>
  </div>
</template>

<script>
import { projectListDialog } from "@/api/pm/project/index";
import Supplier from "@/components/Supplier"; //乙方
import Corporation from "@/components/Corporation"; //甲方
import { debounce } from "@/utils";
export default {
  components: { Supplier, Corporation },
  name: "CardSearch",
  props: {
    searchData: {
      type: Array,
      defaultValue: () => [],
    },
    //  searchObj: {
    //   type: Object,
    //   defaultValue: () => {},
    // },
  },
  data() {
    return {
      searchObj: {},
      time: "",
      choiceDate: null,
      pickerOptions: {
        onPick: ({ maxDate, minDate }) => {
          this.choiceDate = minDate.getTime();
          if (maxDate) this.choiceDate = "";
        },
        disabledDate: (time) => {
          if (this.choiceDate) {
            // console.log(time.getTime(), 66, this.choiceDate);
            // 7天的时间戳
            // const one = 6 * 24 * 3600 * 1000;
            // 当前日期 - one =  7天前
            // const minTime = this.choiceDate - one;
            // 当前日期 +one =  7天后
            // const maxTime = this.choiceDate + one;
            return (
              // time.getTime() < minTime ||
              // time.getTime() > maxTime ||
              time.getTime() > Date.now()
            );
          } else {
            return time.getTime() > Date.now();
          }
        },
      },
      projectIdOptions: [],
      projectIdLoading: false,
    };
  },
  watch: {
    searchData: {
      handler(newVal) {
        this.query = JSON.parse(JSON.stringify(newVal));
        this.query.forEach((v) => {
          // 是否有默认值
          let value = v.default ? v.default : null;
          this.$set(this.searchObj, v.model, value);
        });
      },
      deep: true,
      immediate: true,
    },
  },
  mounted() {
    // 查询条件初始化
    this.query = JSON.parse(JSON.stringify(this.searchData));
    this.query.forEach((v) => {
      // 是否有默认值
      let value = v.default ? v.default : null;
      this.$set(this.searchObj, v.model, value);
    });
  },
  created() {
    const ism = this.searchData.findIndex((item) => item.type === "month");
    const isy = this.searchData.findIndex((item) => item.type === "year");
    if (ism || isy) {
      this.getNowDate(ism, isy);
    }
  },
  methods: {
    // 获取当前年月
    getNowDate(ism, isy) {
      let date = new Date();
      let y = date.getFullYear();
      let m = date.getMonth() + 1;
      m = m < 10 ? "0" + m : m;
      ism || this.$set(this.searchObj, "month", date + "");
      isy || this.$set(this.searchObj, "year", date + "");
    },
    changeDate(event) {
      this.$set(this.searchObj, "month", event + "");
      this.$set(this.searchObj, "year", event + "");
    },
    // 选择乙方返回的数据(公司组件)
    selectCompany(id, name) {
      this.$set(this.searchObj, "customerName", name);
      this.searchObj.customerId = id;
    },
    // 选择甲方组件返回的数据(客户组件)
    selectCorporation(id, name) {
      this.$set(this.searchObj, "companyName", name);
      this.searchObj.companyId = id;
    },
    search() {
      if (Object.keys(this.searchObj).length != 0) {
        this.searchObj.pageSize = 10;
        this.searchObj.pageNum = 1;
        this.$emit("search", this.searchObj);
      } else {
        this.$emit("search");
      }
    },
    reset() {
      this.searchObj = {};
      this.query = JSON.parse(JSON.stringify(this.searchData));
      this.query.forEach((v) => {
        // 是否有默认值
        let value = v.default ? v.default : null;
        if (value && !this.searchObj[v.model]) {
          this.$set(this.searchObj, v.model, value);
        }
      });
      this.$emit("reset");
    },
    remoteMethod: debounce(
      function (query) {
        if (!query) return;
        this.projectIdLoading = true;
        projectListDialog({ pageNum: 1, pageSize: 999, key: query }).then(
          (res) => {
            this.projectIdOptions = res.data.rows;
            this.projectIdLoading = false;
          }
        );
      },
      1000,
      true
    ),
  },
};
</script>

<style scoped lang="scss">
.cardStyle {
  margin: 10px 20px 0 0;
}

.el-card__body {
  & .el-row:last-child {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-end;

    & .el-col:last-child {
      flex: 1;
    }
  }

  // .el-col {
  //   margin-top: 10px;
  // }
  .el-col-6 {
    padding-bottom: 0;
  }
}
</style>

持续更新中...