index.vue 3.03 KB
<template>
  <z-schema-form
    v-model="model"
    class="z-schema-filter"
    :list="formattedList"
    :span="span"
    :labelWidth="labelWidth"
    :colClass="colVisibleRender"
    :size="size"
    :formProps="formProps"
    :params="params"
  >
    <template v-for="key in slotKeys">
      <template v-if="key === 'operation'">
        <slot :name="key" :slot="key" v-bind="{ size, handleSearch, handleReset, handleCollapse, showCollapsed, collapsed, loading }"></slot>
      </template>
      <slot v-else :name="key" :slot="key"></slot>
    </template>
    <div v-if="!slotKeys.includes('operation')" slot="operation" class="z-schema-filter__button-group">
      <el-button-group :size="size">
        <el-button type="primary" @click="handleSearch" :loading="loading" icon="el-icon-search"><span>查询</span></el-button>
        <el-button @click="handleReset"><span>重置</span></el-button>
        <el-button v-if="showCollapsed" @click="handleCollapse">
          <span>{{ collapsed ? '展开' : '收起' }}</span>
        </el-button>
      </el-button-group>
    </div>
  </z-schema-form>
</template>

<script>
export default {
  name: 'SchemaFilter',
  props: {
    value: Object,
    list: Array,
    labelWidth: {
      type: String,
      default: '110px',
    },
    size: {
      type: String,
      default: 'small',
    },
    span: {
      type: Number,
      default: 6,
    },
    collapsedSpan: {
      type: Number,
      default: 6,
    },
    uncollapsedSpan: {
      type: Number,
      default: 24,
    },
    visibleNum: {
      type: Number,
      default: 3,
    },
    loading: Boolean,
    formProps: {
      type: Object,
      default: () => ({}),
    },
    params: Object,
  },
  data() {
    return {
      collapsed: true,
      model: this.value || {},
    };
  },
  watch: {
    value(val = {}) {
      this.model = val;
    },
    model(val) {
      this.$emit('input', val);
    },
  },
  computed: {
    formattedList() {
      return [...this.list, { key: 'operation', label: '', labelWidth: '0px', span: this.collapsed ? this.collapsedSpan : this.uncollapsedSpan }];
    },
    showCollapsed() {
      const { list, visibleNum } = this;
      return list.length > visibleNum;
    },
    slotKeys() {
      return Object.keys(this.$scopedSlots);
    },
  },
  methods: {
    // 渲染列表项class
    colVisibleRender(item, index) {
      if (this.collapsed) {
        const visibleNumber = this.visibleNum ? this.visibleNum - 1 : 2;
        return index > visibleNumber && index < this.list.length ? 'z-schema-filter__item hidden' : 'z-schema-filter__item';
      }
      return 'z-schema-filter__item';
    },
    // 搜索
    handleSearch() {
      this.$emit('search', this.model);
    },
    // 重置
    handleReset() {
      this.model = {};
      this.$emit('reset');
    },
    // 折叠
    handleCollapse() {
      this.collapsed = !this.collapsed;
    },
  },
};
</script>

<style>
.z-schema-filter__item.hidden {
  display: none;
}
.z-schema-filter__button-group {
  width: 100%;
  box-sizing: border-box;
  text-align: right;
}
</style>