使用element-ui二次封装公共查询组件

Posted 柳慕笙

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了使用element-ui二次封装公共查询组件相关的知识,希望对你有一定的参考价值。

1.组件
组件中包含了大部分的查询需求,也提供了插槽,并且做了自适应。

<template>
  <div>
    <el-form ref="form" label-position="top">
      <el-row>
        <!-- 前部插槽 -->
        <slot name="front"></slot>
        <!-- span默认值为4  -->
        <!-- 依据span值可计算出xs sm md lg xl的默认值 也可自行设置 -->
        <!-- pull 向左移动格数 push 向右移动格数 offset 和左侧的间隔格数 -->
        <el-col
          v-for="(item, index) in searchForm"
          :key="item.prop"
          :span="item.span ? item.span : 4"
          :xs="item.xs"
          :sm="item.sm"
          :md="item.md"
          :lg="item.lg"
          :xl="item.xl"
          :offset="item.offset"
          :push="item.push"
          :pull="item.pull"
        >
          <el-form-item
            :label="item.label ? item.label : \' \'"
            v-show="item.show === false ? item.show : true"
            :class="item.className"
          >
            <!-- 输入框 -->
            <el-input
              v-if="item.type == \'input\'"
              v-model="searchData[item.prop]"
            ></el-input>

            <!-- 下拉框 -->
            <el-select
              v-if="item.type == \'select\'"
              v-model="searchData[item.prop]"
              :multiple="item.multiple"
              :collapse-tags="item.collapseTags"
              :filterable="item.filterable"
              :remote="item.remote"
              :remote-method="
                (query) => {
                  remoteMethod(query, item.options)
                }
              "
              :loading="remoteLoading"
            >
              <!-- 远程搜索 -->
              <el-option
                v-else
                v-for="ele in item.options"
                :key="ele.value"
                :label="ele.label"
                :value="ele.value"
              >
              </el-option>
            </el-select>
            <!-- 级联选择器 -->
            <el-cascader
              v-if="item.type == \'cascader\'"
              v-model="searchData[item.prop]"
              :options="item.options"
              :placeholder="item.placeholder ? item.placeholder : \'请选择\'"
            ></el-cascader>

            <!-- 单选 -->
            <el-radio-group
              v-if="item.type === \'Radio\'"
              v-model="searchData[item.prop]"
            >
              <el-radio
                v-for="ra in item.radios"
                :label="ra.value"
                :key="ra.value"
              >{{ ra.label }}
              </el-radio
              >
            </el-radio-group>

            <!-- 单选按钮 -->
            <el-radio-group
              v-if="item.type === \'RadioButton\'"
              v-model="searchData[item.prop]"
              @change="item.change && item.change(searchData[item.prop])"
            >
              <el-radio-button
                v-for="ra in item.radios"
                :label="ra.value"
                :key="ra.value"
              >{{ ra.label }}
              </el-radio-button
              >
            </el-radio-group>

            <!-- 复选框 -->
            <el-checkbox-group
              v-if="item.type === \'Checkbox\'"
              v-model="searchData[item.prop]"
            >
              <el-checkbox
                v-for="ch in item.checkboxs"
                :label="ch.value"
                :key="ch.value"
              >{{ ch.label }}
              </el-checkbox
              >
            </el-checkbox-group>

            <!-- 计数器 -->
            <el-input-number
              v-if="item.type === \'inputNumber\'"
              v-model="searchData[item.prop]"
              :min="item.minNum"
              :max="item.maxNum"
            ></el-input-number>

            <!-- 时间 -->
            <el-time-select
              v-if="item.type === \'Time\'"
              v-model="searchData[item.prop]"
              type=""
            ></el-time-select>

            <!-- 日期 -->
            <el-date-picker
              v-if="item.type === \'Date\'"
              v-model="searchData[item.prop]"
            ></el-date-picker>

            <!-- 日期时间 -->
            <el-date-picker
              v-if="item.type === \'DateTime\'"
              type="datetime"
              :picker-options="
                item.pickerOptions
                  ? item.pickerOptions
                  : setOptions(item, index)
              "
              v-model="searchData[item.prop]"
              :format="
                item.dateFormat ? item.dateFormat : \'yyyy-MM-dd HH:mm:ss\'
              "
              :value-format="
                item.dateFormat ? item.dateFormat : \'yyyy-MM-dd HH:mm:ss\'
              "
              :disabled="item.disable && item.disable(searchData[item.prop])"
            >
            </el-date-picker>
          </el-form-item>
        </el-col>
        <!-- 尾部插槽 -->
        <slot name="last"></slot>
        <el-col
          :span="4"
          :xs="12"
          :sm="6"
          :md="8"
          :lg="4"
          :xl="4"
          class="search-button"
        >
          <!-- 查询按钮 -->
          <el-form-item label=" ">
            <el-button
              type="primary"
              @click="sendSearch"
              class="scpp-button"
              v-if="
                showSearch
                  ?
                  searchChildForm && searchChildForm.length > 0: true
              "
            ><i class="el-icon-search"></i> 检索
            </el-button
            >
            <el-button
              class="scpp-reset-button"
              type="text"
              @click="reset"
              v-if="
                showSearch
                  ?
                  searchChildForm && searchChildForm.length > 0: true
              "
            >重置
            </el-button
            >
            <span
              @click="more"
              style="cursor: pointer"
              v-if="searchChildForm && searchChildForm.length > 0"
            >更多条件
              <i
                :class="[
                  showCondition
                    ? \'el-icon-d-arrow-left\'
                    : \'el-icon-d-arrow-right\',
                  \'arrow-icon\',
                ]"
              /></span
            >
          </el-form-item>
        </el-col>
      </el-row>
      <common-query
        v-if="showCondition"
        :searchForm="searchChildForm"
        :searchData="searchChildData"
        :showSearch="true"
      ></common-query>
    </el-form>
 </div>
</template>
<script>
  export default {
    name: "common-query",
    data() {
      return {
        remoteOptions: [],
        remoteLoading: false,
        showCondition: false,
      }
    },
    props: {
      searchForm: {
        type: Array,
      },
      searchData: {
        type: Object,
      },
      searchChildForm: {
        type: Array,
      },
      searchChildData: {
        type: Object,
      },
      showSearch: {
        type: Boolean,
      },
      changeHeight: {
        type: Boolean,
        default: false,
      },
    },
    created() {
      if (this.searchForm) {
        this.displayFlex(this.searchForm)
      }
      if (this.searchChildForm) {
        this.displayFlex(this.searchChildForm)
      }
    },
    watch: {
      addressId(newVal) {
        if (newVal) {
          this.getArea()
        }
      },
      showCondition(newVal) {
        //修改显示高度
        this.$emit("update:changeHeight", newVal);
      }
    },
    methods: {
      // 自适应方法   依据span值计算 各个屏幕尺寸下的栅格列数
      displayFlex(array) {
        array.forEach((item) => {
          item.xs = 24
          item.lg = item.span
          item.xl = item.span
          if (item.span > 6) {
            item.sm = 12
            item.md = item.span
          } else {
            item.sm = 8
            item.md = 4
          }
          if (item.type == "streetAddress") {
            this.getStreet()
          }
        })
      },

      // 依据传入的值类型 判断是开始时间还是结束时间
      // 遵循结束时间大于开始时间的原则即可
      setOptions(item, index) {
        if (item.startTime) {
          let end = this.searchForm[index + 1]
          let disabledEnd = {
            disabledDate: (time) => {
              return (
                new Date(this.searchData[end.prop]).getTime() < time.getTime()
              )
            },
          }
          return disabledEnd
        } else if (item.endTime) {
          let start = this.searchForm[index - 1]
          let disabledStart = {
            disabledDate: (time) => {
              return (
                new Date(this.searchData[start.prop]).getTime() > time.getTime()
              )
            },
          }
          return disabledStart
        }
      },
      // 点击树时获取到当前的code以及name
      treeCheck(node) {
        let prop = ""
        let id = ""
        this.searchForm.forEach((item) => {
          if (item.type == "tree") {
            prop = item.prop
            id = item.propId
          }
        })
        this.$set(this.searchData, prop, node.shortName)
        this.$set(this.searchData, id, node.orgCode)
      },
      // 查询
      sendSearch() {
        this.showCondition = false
        this.$emit("sendSearch", this.searchData, this.searchChildData)
      },
      // 重置
      reset() {
        this.showCondition = false
        if (this.$refs.place) {
          this.$refs.place[0].clear()
        }
        this.$emit("sendReset")
      },
      more() {
        if (this.showCondition) {
          this.showCondition = false
        } else {
          this.showCondition = true
        }
      },
    },
  }
</script>
<style lang="css">
  .search-button {
    float: right;
  }

  .el-input-number {
    width: 100% !important;
    line-height: 30px !important;
  }

  .el-date-editor.el-input, .el-date-editor.el-input__inner {
    width: 100% !important;
  }

  /* 更多图标 */
  .arrow-icon {
    color: #1796ff;
    transform: rotate(90deg);
  }
</style>

2.使用方式

  • 在当前页面中引入公共查询组件并使用
 <common-query
          ref="searchForm"
          :searchForm="query"
          :searchData="form"
          :searchChildForm="searchChildForm"
          :searchChildData="searchChildData"
          :showSearch="true"
          @sendSearch="sendSearch"
          @sendReset="resetForm"
        ></common-query>
  • 在data中定义需要的数据
{
          type: "input",
          label: "组织名称",
          prop: "mgmtName"
        },
        {
          type: "select",
          label: "组织类型",
          prop: "type",
        },
        {
          type: "select",
          label: "组织层级",
          prop: "level",
        },
        {
          type: "input",
          label: "姓名",
          prop: "name"
        },
        {
          type: "input",
          label: "证件号码",
          prop: "idNumber"
        },
  • 在method中定义查询和重置方法
      sendSearch(searchData, moreData) {
        this.form = Object.assign(searchData, moreData);
        this.submitForm(1);  // 查询表格的方法
      },
       resetForm() {
        Object.assign(this.$data.form, this.$options.data.call(this).form);
        Object.assign(this.$data.searchChildData, this.$options.data.call(this).searchChildData);
        }

以上是关于使用element-ui二次封装公共查询组件的主要内容,如果未能解决你的问题,请参考以下文章

使用element-ui二次封装一个可复用弹窗组件

element-ui组件的二次封装

agel-form 基于 element-ui form 的二次封装,数据配置表单,快速开发!

vue-form-table(vuejs+element-ui的表格表单控件的二次封装插件)

vue+Ts+element组件封装

element-UI——el-table二次封装