antv 查询条件封装,可展开收起

57 阅读1分钟
<!-- QueryFilter.vue -->
<template>
  <a-form
    :model="model"
    layout="inline"
    class="form"
    :label-col="{ span: 6 }"
    :wrapper-col="{ span: 18 }"
  >
    <a-row :gutter="gutter">
      <a-col v-for="(item, index) in itemsSearch" :key="index" :span="item.span || 6">
        <a-form-item :colon="item.colon ? false : true">
          <template #label>
            <span>
              <a-tooltip :overlayStyle="{ maxWidth: '500px' }">
                <template #title>
                  <div v-if="Array.isArray(item.tips)">
                    <div v-for="subitem in item.tips">{{ subitem }}</div>
                  </div>
                  <div v-else>{{ item.tips }}</div>
                </template>
                <InfoCircleOutlined v-if="item.tips" />
              </a-tooltip>
              {{ item.label }}
            </span>
          </template>
          <component
            :is="item.component"
            style="width: 100%"
            v-bind="item.props || {}"
            v-model:value="model[item.field]"
            :placeholder="item.placeholder || `请输入${item.label}`"
          />
        </a-form-item>
      </a-col>
      <a-col :span="getSpan()">
        <span class="btn-wrapper">
          <a-form-item :label-col="{ span: 0 }" :wrapper-col="{ span: 24 }">
            <slot name="actions">
              <a-button
                style="margin-left: 8px"
                :icon="h(SwapOutlined)"
                @click="$emit('reset')"
                >重置</a-button
              >
              <a-button type="primary" :icon="h(SearchOutlined)" @click="$emit('search')"
                >查询</a-button
              >
            </slot>
          </a-form-item>
        </span>
      </a-col>
    </a-row>
  </a-form>
  <div class="collapsed" @click="onDown" v-if="collapsed">展开更多<DownOutlined /></div>
  <div class="collapsed" @click="onUp" v-if="!collapsed">收起更多<UpOutlined /></div>
</template>

<script lang="ts" setup>
import { h, nextTick, ref } from 'vue';
import {
  SearchOutlined,
  SwapOutlined,
  DownOutlined,
  UpOutlined,
  InfoCircleOutlined,
} from '@ant-design/icons-vue';

const props: any = defineProps({
  model: {
    type: Object,
    required: true,
  },
  items: {
    type: Array,
    required: true,
  },
  gutter: {
    type: Object,
    default: { xs: 8, sm: 16, md: 24, lg: 32 },
  },
  actionSpan: {
    type: Number,
    default: 6,
  },
  updateHeight: {
    type: Function,
  },
});

/**
 * 展开更多
 */
const collapsed = ref(true);
const itemsSearch: any = ref(props.items.slice(0, 3));
// 展开更多
const onDown = () => {
  collapsed.value = !collapsed.value;
  itemsSearch.value = props.items;
  nextTick(() => {
    props.updateHeight();
  });
};
// 收起更多
const onUp = () => {
  collapsed.value = !collapsed.value;
  itemsSearch.value = props.items.slice(0, 3);
  nextTick(() => {
    props.updateHeight();
  });
};

const getSpan = () => {
  if (itemsSearch.value.length % 3 === 0) {
    return 24;
  } else if (itemsSearch.value.length % 3 === 1) {
    return 16;
  } else if (itemsSearch.value.length % 3 === 2) {
    return 8;
  }
};
</script>

<style lang="less" scoped>
.form {
  width: 100% !important;
  .btn-wrapper {
    width: 100%;
    text-align: right;

    .a-btn-primary {
      margin-left: 16px;
    }
  }

  .a-col {
    margin-bottom: 16px;
  }
}
</style>

使用方式

 <CommonForm
    :items="columns"
    :model="form"
    @search="onSearch"
    @reset="onReset"
    :updateHeight="updateHeight"
  />
  
  // 查询的列
const columns: any = reactive([
  {
    label: 'xxx',
    field: 'xxx',
    component: 'a-tree-select',
    span: 8,
    props: {
      treeData: [],
      'allow-clear': true,
      showSearch: true,
      treeNodeFilterProp: 'label',
      'field-names': {
        label: 'label',
        value: 'id',
        children: 'children',
      },
    },
  },
  {
    label: 'xxx',
    field: 'xxx',
    component: 'a-input',
    span: 8,
  },
  {
    label: `xxx`,
    field: 'xxx',
    component: 'a-range-picker',
    span: 8,
    placeholder: ['开始时间', '结束时间'],
    props: {
      'value-format': 'YYYY-MM-DD',
    },
    // 图标前放个提示图标,tips内是提示内容
    tips: [
      'xxx',
      'xxx',
    ],
  },
  {
    label: 'xxx',
    field: 'xxx',
    component: 'a-select',
    placeholder: 'xxx',
    span: 8,
    props: {
      allowClear: true,
      options: dictData.value?.sjly,
    },
  },
  {
    label: 'xxx',
    field: 'xxx',
    component: 'a-cascader',
    span: 8,
    props: {
      options: [],
      'allow-clear': true,
      'tree-node-filter-prop': 'label',
      'field-names': {
        label: 'label',
        value: 'id',
        children: 'childs',
      },
    },
  }
]);

// 点击展开收起之后更新table高
const updateHeight = () => {}
// 查询
const onSearch = () => {}
// 重置
const onReset = () => {}