基于el-form实现自动展开/收起的查询条件组件

说明

如果查询条件过多,影响页面的展示效果,网上看了一些实现自动展开/收起的,有根据最小高度控制的,有基于条件的如v-show来控制,下面借助js原生的hidden属性实现要素的显示、隐藏控制。
先看一下效果:
在这里插入图片描述

优点

  • 不需要额外的设置,根据想要显示的个数,自动控制【展开/收起】
  • 根据屏幕尺寸,自适应显示
  • 适合基于配置生成的前端自动渲染组件,不用额外的参数配置,还可保持页面的整体布局

缺点

  • 没有增加一行几列的配置,有需要的可以自行实现

一、实现思路

根据最大显示个数,超过设置数量,则触发【展开/收起】,将大于设置数量的元素默认设置为隐藏,点击展开/收起时,再切换对应条件的元素显示、隐藏属性。
可以错助document.querySelectorAll 取到相应的元素,元素属性本身有hidden属性,只要改变hidden的值,就可以实现元素的显示/隐藏。
为了提高获取元素的准确性,用div包一下el-form-item,方便精准获取元素
核心代码:

   // 通过maxShow控制元素显示/折叠
    minShowCtrol() {
    
    
      const group = window.document.querySelectorAll(`#searchFilter .el-form-item.el-form-item--${
      
      this.size}`)
      const len = group?.length ? group?.length - 1 : 0
      if (this.maxShow < len) {
    
    
        group.forEach((item, index) => {
    
    
          if (index > this.maxShow - 1 && index < len) {
    
    
            item.hidden = !this.fold
          }
        })
        this.collapsiable = true
      } else {
    
    
        this.collapsiable = false
      }
    },

通过document.querySelectorAll获取的元素属性如下,有兴趣的可以自已输出一下看看,这里使用hidden属性来切换元素的显示隐藏,由于最后的操作按钮也入在el-form-item里,所以记得排除一下
在这里插入图片描述

二、创建SearchFile组件

关键属性:maxShow,默认值3,超过3个则将元素隐藏,小于3个,则不触发【展开/收起】

<template>
  <Form ref="form" :label-width="labelWidth" :size="size">
    <div id="searchFilter" :gutter="10" style="display: flex; flex-wrap: wrap">
      <slot></slot>
      <FormItem>
        <Button type="primary" @click="handleQuery">查询</Button>
        <Button @click="handleReset">重置</Button>
        <Button v-show="collapsiable" type="text" @click="shiftCollapsiable">
          <span>
            {
    
    {
    
     fold ? '收起' : '展开' }}
            <i :class="fold ? 'el-icon-arrow-up' : 'el-icon-arrow-down'"></i>
          </span>
        </Button>
      </FormItem>
    </div>
  </Form>
</template>
<script>
import {
    
     Form, FormItem, Button } from 'element-ui'
export default {
    
    
  name: 'SearchFilter',
  components: {
    
     Form, FormItem, Button },
  props: {
    
    
    // 最大展示数,默认3个,超过则隐藏,为0时不限制
    maxShow: {
    
    
      type: Number,
      default: 3,
    },
    labelWidth: {
    
    
      type: String,
      default: '100px',
    },
    size: {
    
    
      type: String,
      default: 'small',
    },
  },
  data() {
    
    
    return {
    
    
      collapsiable: false,
      fold: false,
    }
  },
  created() {
    
    },
  mounted() {
    
    
    // 通过最大显示个数控制展开/折叠
    if (this.maxShow > 0) {
    
    
      this.minShowCtrol()
    }
  },
  methods: {
    
    
    shiftCollapsiable() {
    
    
      this.fold = !this.fold
      this.minShowCtrol()   
    },
    // 通过maxShow控制元素显示/折叠
    minShowCtrol() {
    
    
      const group = window.document.querySelectorAll(`#searchFilter .el-form-item.el-form-item--${
      
      this.size}`)
      const len = group?.length ? group?.length - 1 : 0
      if (this.maxShow < len) {
    
    
        group.forEach((item, index) => {
    
    
          if (index > this.maxShow - 1 && index < len) {
    
    
            item.hidden = !this.fold
          }
        })
        this.collapsiable = true
      } else {
    
    
        this.collapsiable = false
      }
    },
    handleQuery() {
    
    
      this.$emit('search')
    },
    handleReset() {
    
    
      this.$emit('reset')
    },
  },
}
</script>
<style lang="scss" scoped></style>

组件属性 Props

参数 说明 类型 可选项 默认值
maxShow 最大展示个数 Number 3
labelWidth 标签宽度 String 100px
size 组件的尺寸 String medium / small / mini small

事件 Events

事件名 说明
search 触发查询操作,需要自定义实现
reset 触发重置操作,需要自定义实现

插槽 Slots

插槽名 说明
default 默认插槽,定义表单项

三、使用组件

这里不多说,直接把组件引入使用就可以

<template>
  <div>
    <SearchFilter size="mini" :maxShow="3" @search="search" @reset="reset">
      <el-form-item label="收款人信息">
        <el-input v-model="searchData.info" placeholder="账号/开户名"></el-input>
      </el-form-item>
      <el-form-item label="单号1">
        <el-input v-model="searchData.itemNo1"></el-input>
      </el-form-item>
      <el-form-item label="单号2">
        <el-input v-model="searchData.itemNo2"></el-input>
      </el-form-item>
      <el-form-item label="单号3">
        <el-input v-model="searchData.itemNo3"></el-input>
      </el-form-item>
      <el-form-item label="申请日期" prop="date">
        <el-date-picker v-model="searchData.date" type="daterange" range-separator="至" start-placeholder="开始日期" end-placeholder="结束日期" value-format="yyyy-MM-dd" style="width: auto"> </el-date-picker>
      </el-form-item>
    </SearchFilter>
  </div>
</template>
<script>
import SearchFilter from './SearchFilter'
  export default {
    
    
    components: {
    
    SearchFilter},
    data() {
    
    
      return {
    
    
        searchData: {
    
    },
      }
    },
    methods: {
    
    
      search() {
    
    },
      reset() {
    
    
        this.searchData = {
    
    }
      },
    },
  }
</script>

猜你喜欢

转载自blog.csdn.net/lqh4188/article/details/128116571