123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145 |
- <template>
- <div class="filter-box" :class="{ multiple }">
- <el-input v-if="!multiple" placeholder="请输入内容" class="input-with-select" :clearable="true" size="mini" v-model="filterData.value">
- <el-select class="prepend" slot="prepend" placeholder="请选择" v-model="filterData.name" @clear="handleClear" clearable>
- <el-option v-for="(item, index) in fields" :label="item.field.label" :value="item.field.name" :key="'filter' + index"></el-option>
- </el-select>
- <el-button slot="append" icon="el-icon-search" @click="query"></el-button>
- </el-input>
- <el-form v-else ref="form" :model="form" :inline="true">
- <el-form-item v-for="(item, index) in simpleFields" :key="'form-field-' + index" :label="item.field.label">
- <naf-input v-model="form[item.field.name]" size="mini" :dict="item.dict" :clearable="true"></naf-input>
- </el-form-item>
- <el-form-item>
- <el-dropdown v-if="matcher == 'all'" size="mini" split-button type="primary" @click="query" @command="handleCommand">
- 查询
- <el-dropdown-menu slot="dropdown">
- <el-dropdown-item command="exact">精确查询<i v-if="matching == 'exact'" class="el-icon-check el-icon--right"></i></el-dropdown-item>
- <el-dropdown-item command="like">模糊查询<i v-if="matching == 'like'" class="el-icon-check el-icon--right"></i></el-dropdown-item>
- </el-dropdown-menu>
- </el-dropdown>
- <el-button v-else type="primary" size="mini" @click="query">查询</el-button>
- </el-form-item>
- <el-form-item>
- <el-button type="primary" size="mini" @click="reset">重置</el-button>
- </el-form-item>
- <el-form-item v-if="$scopedSlots.ext || moreFields.length > 0">
- <el-button type="primary" size="mini" @click="toggleMore" v-if="!showMore">更多</el-button>
- <el-button type="default" size="mini" @click="toggleMore" v-else>收起</el-button>
- </el-form-item>
- </el-form>
- <slot name="ext" v-bind="{ form, handleFieldChange }" v-if="showMore">
- <el-form ref="form-ext" :model="form" :inline="true">
- <el-form-item v-for="(item, index) in moreFields" :key="'form-ex-field-' + index" :label="item.field.label">
- <naf-input v-model="form[item.field.name]" size="mini" :dict="item.dict" :clearable="true"></naf-input>
- </el-form-item>
- </el-form>
- </slot>
- </div>
- </template>
- <script>
- import NafInput from './naf-input';
- import { Util } from 'naf-core';
- const defaultMatcher = process.env.VUE_APP_FILTER_MATCHER_DEFAULT || 'like';
- export default {
- components: {
- NafInput,
- },
- props: {
- fields: { type: Array, required: true },
- multiple: { type: Boolean, default: eval(process.env.VUE_APP_FILTER_MULTI || false) },
- matcher: { type: String, default: process.env.VUE_APP_FILTER_MATCHER || 'like' },
- maxFields: { type: Number, default: 4 },
- },
- data() {
- return {
- filterData: { name: '', value: '' },
- form: {},
- matching: (defaultMatcher == 'exact' && 'exact') || (defaultMatcher == 'like' && 'like') || 'like',
- showMore: false,
- };
- },
- methods: {
- async query() {
- const filter = { ...this.filter, exact: this.matching != 'like' };
- const paging = { page: this.page, size: this.size };
- Object.freeze(filter);
- Object.freeze(paging);
- this.$emit('query', {
- filter,
- paging,
- });
- },
- handleClear() {
- this.filterData = { name: '', value: '' };
- },
- reset() {
- this.form = {};
- this.query();
- },
- handleCommand(command) {
- this.matching = command;
- this.query();
- },
- toggleMore() {
- this.showMore = !this.showMore;
- },
- handleFieldChange(name, value) {
- console.debug(`filter field ${name} changed:`, value);
- this.$set(this.form, name, value);
- },
- },
- computed: {
- filterFields() {
- return this.fields.map(p => ({
- ...p,
- dict: p.dict || (this.$dict && p.formatter && p.formatter.name === 'dict' && this.$dict(p.formatter.param)),
- }));
- },
- filter() {
- if (this.multiple) {
- const entries = Object.entries(this.form).filter(p => p[1] != undefined && p[1] != null && p[1] != '');
- return Object.fromEntries(entries);
- }
- let filter = { [this.filterData.name]: this.filterData.value };
- if (this.filterData.name == undefined || this.filterData.value == undefined || this.filterData.value == '') {
- filter = undefined;
- }
- return filter;
- },
- simpleFields() {
- return this.filterFields.slice(0, this.maxFields);
- },
- moreFields() {
- return this.filterFields.slice(this.maxFields) || [];
- },
- },
- };
- </script>
- <style lang="less" scoped>
- .filter-box {
- width: 300px;
- display: inline-block;
- margin-right: 20px;
- .prepend.el-select {
- width: 100px;
- }
- }
- .filter-box.multiple {
- width: 100%;
- min-width: 920px;
- .naf-input {
- width: 100px;
- /deep/ .el-input__inner {
- padding: 0 5px;
- }
- }
- .el-form-item {
- margin-bottom: 0;
- }
- }
- </style>
|