This commit is contained in:
sc 2021-07-31 16:50:52 +08:00
parent 0a57f08fc2
commit 31a1c69319
8 changed files with 464 additions and 489 deletions

View File

@ -7,7 +7,6 @@
[class*="sc-icon-"] {
font-family: "scicon" !important;
font-size: 16px;
font-style: normal;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;

View File

@ -1,251 +1,284 @@
<!--
* @Descripttion: 过滤器V2
* @version: 2.0
* @Author: sakuya
* @Date: 2021年7月30日14:48:41
* @LastEditors:
* @LastEditTime:
-->
<template>
<div class="sc-filterBar">
<div class="sc-filterBar-scrollbar" ref="scFilterBarScrollbar">
<div class="sc-filterBar-tags">
<div class="filter-tag" v-for="item in filter" :key="item.keyLabel"><span class="field">{{item.keyLabel}}</span><span class="value">{{item.valueLabel}}<i @click="handleClose(item)" class="el-icon-close"></i></span></div>
</div>
</div>
<el-popover title="新建过滤器" :width="550" trigger="manual" v-model:visible="isadd">
<template #reference>
<el-button class="button-new-tag" size="small" type="primary" @click="openAdd" icon="el-icon-zoom-in"></el-button>
<el-badge :value="filterObjLength" type="danger" :hidden="filterObjLength<=0">
<el-button size="small" icon="sc-icon-filter-fill" @click="openFilter"></el-button>
</el-badge>
<el-drawer title="过滤器" v-model="drawer" :size="650" append-to-body>
<el-container v-loading="saveLoading">
<el-main style="padding:0">
<el-tabs class="root">
<el-tab-pane lazy>
<template #label>
<div class="tabs-label">过滤项</div>
</template>
<el-form ref="ruleForm" :model="addFilterForm" :rules="addFilterRules" label-width="80px" style="padding-top:10px;">
<el-form-item label="字段" prop="field">
<el-select v-model="addFilterForm.field" placeholder="请选择" value-key="value" @change="fieldChange" filterable clearable>
<el-option v-for="item in options" :key="item.value" :label="item.label" :value="item" :disabled="item.disabled">
</el-option>
<el-scrollbar>
<div class="sc-filter-main">
<h2>设置过滤条件</h2>
<div v-if="filter.length<=0" class="nodata">
没有默认过滤条件请点击增加过滤项
</div>
<table v-else>
<colgroup>
<col width="50">
<col width="140">
<col width="120">
<col>
<col width="40">
</colgroup>
<tr v-for="(item,index) in filter" :key="index">
<td>
<el-tag size="medium">{{index+1}}</el-tag>
</td>
<td>
<el-select v-model="item.field" placeholder="过滤字段" filterable @change="fieldChange(item)">
<el-option v-for="field in fields" :key="field.value" :label="field.label" :value="field"></el-option>
</el-select>
</el-form-item>
<el-form-item label="值" prop="value">
<el-input v-if="!addFilterForm.field.type" v-model="addFilterForm.value" placeholder="请先选择过滤字段" disabled style="width: 400px;"></el-input>
<el-input v-if="addFilterForm.field.type=='text'" v-model="addFilterForm.value" placeholder="请输入内容" clearable style="width: 400px;"></el-input>
<el-select v-if="addFilterForm.field.type=='select'" v-model="addFilterForm.value" :loading="selectLoading" :multiple="addFilterForm.field.extend?addFilterForm.field.extend.multiple:false" :remote="addFilterForm.field.extend?addFilterForm.field.extend.remote:false" @visible-change="visibleChange($event)" :remote-method="remoteMethod" filterable clearable placeholder="请选择/输入关键词" style="width: 400px;">
<el-option v-for="item in addFilterForm.field.extend.data" :key="item.value" value-key="value" :label="item.label" :value="item"></el-option>
</td>
<td>
<el-select v-model="item.operator" placeholder="运算符">
<el-option v-for="ope in operator" :key="ope.value" :label="ope.label" :value="ope.value"></el-option>
</el-select>
<el-date-picker v-if="addFilterForm.field.type=='date'" v-model="addFilterForm.value" type="date" placeholder="请选择日期" style="width: 400px;"></el-date-picker>
<el-date-picker v-if="addFilterForm.field.type=='daterange'" v-model="addFilterForm.value" type="daterange" range-separator="至" start-placeholder="开始日期" end-placeholder="结束日期" placeholder="请选择日期" style="width: 400px;"></el-date-picker>
<el-date-picker v-if="addFilterForm.field.type=='datetime'" v-model="addFilterForm.value" type="datetime" placeholder="请选择日期" style="width: 400px;"></el-date-picker>
<el-date-picker v-if="addFilterForm.field.type=='datetimerange'" v-model="addFilterForm.value" type="datetimerange" :default-time="defaultTime" range-separator="至" start-placeholder="开始日期" end-placeholder="结束日期" placeholder="请选择日期" style="width: 400px;"></el-date-picker>
</el-form-item>
<el-form-item >
<el-button class="button-new-tag" type="primary" @click="ok" icon="el-icon-search">立即过滤</el-button>
<el-button class="button-new-tag" @click="cancel">取消</el-button>
</el-form-item>
</el-form>
</el-popover>
</td>
<td>
<el-input v-if="!item.field.type" v-model="item.value" placeholder="请选择过滤字段" disabled></el-input>
<!-- 输入框 -->
<el-input v-if="item.field.type=='text'" v-model="item.value" :placeholder="item.field.placeholder||'请输入'"></el-input>
<!-- 下拉框 -->
<el-select v-if="item.field.type=='select'" v-model="item.value" :placeholder="item.field.placeholder||'请选择'" filterable :multiple="item.field.extend.multiple" :loading="item.selectLoading" @visible-change="visibleChange($event, item)" :remote="item.field.extend.remote" :remote-method="(query)=>{remoteMethod(query, item)}">
<el-option v-for="field in item.field.extend.data" :key="field.value" :label="field.label" :value="field.value"></el-option>
</el-select>
<!-- 日期 -->
<el-date-picker v-if="item.field.type=='date'" v-model="item.value" type="date" value-format="YYYY-MM-DD" :placeholder="item.field.placeholder||'请选择日期'" style="width: 100%;"></el-date-picker>
<!-- 日期范围 -->
<el-date-picker v-if="item.field.type=='daterange'" v-model="item.value" type="daterange" value-format="YYYY-MM-DD HH:mm:ss" start-placeholder="开始日期" end-placeholder="结束日期" style="width: 100%;"></el-date-picker>
<!-- 日期时间 -->
<el-date-picker v-if="item.field.type=='datetime'" v-model="item.value" type="datetime" value-format="YYYY-MM-DD HH:mm:ss" :placeholder="item.field.placeholder||'请选择日期'" style="width: 100%;"></el-date-picker>
<!-- 日期时间范围 -->
<el-date-picker v-if="item.field.type=='datetimerange'" v-model="item.value" type="datetimerange" value-format="YYYY-MM-DD HH:mm:ss" start-placeholder="开始日期" end-placeholder="结束日期" style="width: 100%;"></el-date-picker>
<!-- 开关 -->
<el-switch v-if="item.field.type=='switch'" v-model="item.value"></el-switch>
</td>
<td>
<i class="el-icon-delete del" @click="delFilter(index)"></i>
</td>
</tr>
</table>
<el-button type="text" icon="el-icon-plus" @click="addFilter">增加过滤项</el-button>
</div>
</el-scrollbar>
</el-tab-pane>
<el-tab-pane lazy>
<template #label>
<div class="tabs-label">常用</div>
</template>
<el-scrollbar>
<my ref="my" :data="myFilter" :filterName="filterName" @selectMyfilter="selectMyfilter"></my>
</el-scrollbar>
</el-tab-pane>
</el-tabs>
</el-main>
<el-footer>
<el-button type="primary" @click="ok" :disabled="filter.length<=0">立即过滤</el-button>
<el-button type="primary" plain @click="saveMy" :disabled="filter.length<=0">另存为常用</el-button>
<el-button @click="clear">清空过滤</el-button>
</el-footer>
</el-container>
</el-drawer>
</div>
</template>
<script>
import config from "@/config/filterBar";
import my from './my'
export default {
name: 'filterBar',
components: {
my
},
props: {
options: { type: Object, default: () => {} },
defaultFilter: { type: Object, default: () => {} }
filterName: { type: String, default: "" },
options: { type: Object, default: () => {} }
},
data() {
return {
defaultTime: [
new Date(2000, 1, 1, 0, 0, 0),
new Date(2000, 2, 1, 23, 59, 59)
],
isadd: false,
selectLoading: false,
addFilterForm: {
field: '',
value: ''
drawer: false,
operator: config.operator,
fields: this.options,
filter: [],
myFilter: [],
filterObjLength: 0,
saveLoading: false
}
},
addFilterRules: {
field: [{required: true, message: '请选择过滤字段', trigger: 'change'}],
value: [{required: true, message: '过滤值不能为空', trigger: 'change'}]
},
filter: []
computed: {
filterObj(){
const obj = {}
this.filter.forEach((item) => {
obj[item.field.value] = `${item.value}${config.separator}${item.operator}`
})
return obj
}
},
mounted(){
this.filter = this.defaultFilter || [];
this.scrollInit()
//
this.fields.forEach((item) => {
if(item.selected){
this.filter.push({
field: item,
operator: item.operator || 'include',
value: ''
})
}
})
},
methods: {
openAdd(){
if(this.isadd){
this.isadd = false;
}else{
this.isadd = true;
//
openFilter(){
this.drawer = true
},
//
addFilter(){
if(this.fields.length<=0){
this.$message.warning('无过滤项');
return false
}
//
for(let f of this.options){
const _f = this.filter.find((item)=>{return item.key === f.value});
if(_f){
f.disabled = true
}else{
f.disabled = false
const filterNum = this.fields[this.filter.length] || this.fields[0]
this.filter.push({
field: filterNum,
operator: filterNum.operator || 'include',
value: ''
})
},
//
delFilter(index){
this.filter.splice(index, 1)
},
//
fieldChange(tr){
let oldType = tr.field.type
tr.field.type = ''
this.$nextTick(() => {
tr.field.type = oldType
})
tr.operator = tr.field.operator || 'include'
tr.value = ''
},
//
async visibleChange(isopen, item){
if(isopen && item.field.extend.request && !item.field.extend.remote){
item.selectLoading = true;
try {
var data = await item.field.extend.request()
}catch (error) {
console.log(error);
}
item.field.extend.data = data;
item.selectLoading = false;
}
},
async remoteMethod(query){
//
async remoteMethod(query, item){
if(query !== ''){
this.selectLoading = true;
item.selectLoading = true;
try {
var data = await this.addFilterForm.field.extend.request(query);
var data = await item.field.extend.request(query);
}catch (error) {
console.log(error);
}
this.addFilterForm.field.extend.data = data;
this.selectLoading = false;
item.field.extend.data = data;
item.selectLoading = false;
}else{
this.addFilterForm.field.extend.data = [];
item.field.extend.data = [];
}
},
async visibleChange(isopen){
if(isopen && this.addFilterForm.field.extend && this.addFilterForm.field.extend.request && !this.addFilterForm.field.extend.remote){
//
this.selectLoading = true;
//
selectMyfilter(item){
this.filterObjLength = Object.keys(item.filterObj).length
this.$emit('filterChange',item.filterObj)
this.drawer = false
},
//
ok(){
this.filterObjLength = this.filter.length
this.$emit('filterChange',this.filterObj)
this.drawer = false
},
//
saveMy(){
this.$prompt('常用过滤名称', '另存为常用', {
inputPlaceholder: '请输入识别度较高的常用过滤名称',
inputPattern: /\S/,
inputErrorMessage: '名称不能为空'
})
.then(async ({ value }) => {
this.saveLoading = true
const saveObj = {
title: value,
filterObj: this.filterObj
}
try {
var data = await this.addFilterForm.field.extend.request();
var save = await config.saveMy(this.filterName, saveObj)
}catch (error) {
this.saveLoading = false
console.log(error);
return false
}
this.addFilterForm.field.extend.data = data;
this.selectLoading = false;
if(!save){
return false
}
},
fieldChange(){
this.addFilterForm.value = '';
if(this.addFilterForm.field.type=='select'){
this.addFilterForm.field.type=''
this.$nextTick(() => {
this.addFilterForm.field.type='select'
})
}
if(this.addFilterForm.field.type=='date'){
this.addFilterForm.field.type=''
this.$nextTick(() => {
this.addFilterForm.field.type='date'
})
}
},
ok() {
this.$refs.ruleForm.validate((valid) => {
if (valid) {
var item = {
keyLabel: this.addFilterForm.field.label,
valueLabel: this.addFilterForm.value,
key: this.addFilterForm.field.value,
value: this.addFilterForm.value
}
if(this.addFilterForm.field.type=='select'){
if(this.addFilterForm.field.extend && this.addFilterForm.field.extend.multiple){
item.valueLabel = this.addFilterForm.value.map(v => v.label).join(",");
item.value = this.addFilterForm.value.map(v => v.value).join(",");
}else{
item.valueLabel = this.addFilterForm.value.label;
item.value = this.addFilterForm.value.value;
}
}
if(this.addFilterForm.field.type=='date'){
item.valueLabel = this.dateFormat(this.addFilterForm.value, 'yyyy-MM-dd');
item.value = this.dateFormat(this.addFilterForm.value, 'yyyy-MM-dd');
}
if(this.addFilterForm.field.type=='datetime'){
item.valueLabel = this.dateFormat(this.addFilterForm.value, 'yyyy-MM-dd hh:mm:ss');
item.value = this.dateFormat(this.addFilterForm.value, 'yyyy-MM-dd hh:mm:ss');
}
if(this.addFilterForm.field.type=='daterange'){
item.valueLabel = this.addFilterForm.value.map(item => this.dateFormat(item, 'yyyy-MM-dd')).join(" - ")
item.value = this.addFilterForm.value.map(item => this.dateFormat(item, 'yyyy-MM-dd')).join(" - ")
}
if(this.addFilterForm.field.type=='datetimerange'){
item.valueLabel = this.addFilterForm.value.map(item => this.dateFormat(item, 'yyyy-MM-dd hh:mm:ss')).join(" - ")
item.value = this.addFilterForm.value.map(item => this.dateFormat(item, 'yyyy-MM-dd hh:mm:ss')).join(" - ")
}
this.filter.push(item);
this.cancel();
this.change();
}else{
return false;
}
})
this.myFilter.push(saveObj)
this.$message.success(`${this.filterName} 保存常用成功`)
this.saveLoading = false
})
.catch(() => {
//
})
},
cancel(){
this.isadd = false;
this.addFilterForm.value = '';
this.$refs.ruleForm.resetFields();
},
handleClose(item) {
this.filter = this.filter.filter(obj => obj.key !== item.key);
this.cancel();
this.change();
},
getFilter(){
var _filter = this.filter;
var formatData = {};
_filter.map(item => {
formatData.[item.key]=item.value
});
return formatData;
},
change(){
this.$emit('change', this.getFilter())
},
scrollInit(){
const scrollDiv = this.$refs.scFilterBarScrollbar;
scrollDiv.addEventListener('mousewheel', handler, false)
function handler(event) {
const detail = event.wheelDelta || event.detail;
const moveForwardStep = 1;
const moveBackStep = -1;
let step = 0;
if (detail < 0) {
step = moveForwardStep * 50;
}else{
step = moveBackStep * 50;
}
scrollDiv.scrollLeft += step;
}
},
dateFormat(date, fmt='yyyy-MM-dd'){
date = new Date(date)
var o = {
"M+" : date.getMonth()+1, //
"d+" : date.getDate(), //
"h+" : date.getHours(), //
"m+" : date.getMinutes(), //
"s+" : date.getSeconds(), //
"q+" : Math.floor((date.getMonth()+3)/3), //
"S" : date.getMilliseconds() //
};
if(/(y+)/.test(fmt)) {
fmt=fmt.replace(RegExp.$1, (date.getFullYear()+"").substr(4 - RegExp.$1.length));
}
for(var k in o) {
if(new RegExp("("+ k +")").test(fmt)){
fmt = fmt.replace(RegExp.$1, (RegExp.$1.length==1) ? (o[k]) : (("00"+ o[k]).substr((""+ o[k]).length)));
}
}
return fmt;
//
clear(){
this.filter = []
this.filterObjLength = 0
this.$emit('filterChange',this.filterObj)
}
}
}
</script>
<style scoped>
.sc-filterBar {height: 32px;display: flex;align-items:center;}
.sc-filterBar-scrollbar {overflow: auto;}
.sc-filterBar-scrollbar::-webkit-scrollbar {display: none;}
.sc-filterBar-tags {display: flex;}
.filter-tag {display: flex;flex-shrink: 0;padding-right:10px;}
.filter-tag .field {display: inline-block;background-color: #d9ecff;color: #409eff;height: 32px;line-height: 30px;padding: 0 10px;border-radius: 4px 0 0 4px;border: 1px solid #d9ecff;border-right: 0;}
.filter-tag .value {display: inline-block;background-color: #ecf5ff;color: #409eff;height: 32px;line-height: 30px;padding: 0 10px;border-radius: 0 4px 4px 0;border: 1px solid #d9ecff;border-left: 0;}
.filter-tag i {height: 16px;width: 16px;line-height: 16px;cursor: pointer;text-align: center;vertical-align: middle;position: relative;top: -1px;right: -5px;border-radius: 50%;}
.filter-tag i:hover {background-color: #409eff;color: #FFF;}
.tabs-label {padding:0 20px;}
.nodata {height:46px;line-height: 46px;margin:15px 0;border: 1px dashed #e6e6e6;color: #999;text-align: center;border-radius: 3px;}
.sc-filter-main {padding:20px;border-bottom: 1px solid #e6e6e6;background: #fff;}
.sc-filter-main h2 {font-size: 12px;color: #999;font-weight: normal;}
.sc-filter-main table {width: 100%;margin: 15px 0;}
.sc-filter-main table tr {}
.sc-filter-main table td {padding:5px 10px 5px 0;}
.sc-filter-main table td:deep(.el-input .el-input__inner) {vertical-align: top;}
.sc-filter-main table td .el-select {display: block;}
.sc-filter-main table td .el-date-editor.el-input {display: block;width: 100%;}
.sc-filter-main table td .del {background: #fff;color: #999;width: 32px;height: 32px;line-height: 32px;text-align: center;border-radius:50%;font-size: 12px;cursor: pointer;}
.sc-filter-main table td .del:hover {background: #F56C6C;color: #fff;}
.root {
display: flex;
height: 100%;
flex-direction: column
}
.root:deep(.el-tabs__header) {margin: 0;}
.root:deep(.el-tabs__content) {flex: 1;background: #f6f8f9;}
.root:deep(.el-tabs__content) .el-tab-pane{overflow: auto;height:100%;}
</style>

View File

@ -0,0 +1,97 @@
<!--
* @Descripttion: 过滤器V2 常用组件
* @version: 2.0
* @Author: sakuya
* @Date: 2021年7月31日16:49:56
* @LastEditors:
* @LastEditTime:
-->
<template>
<div class="sc-filter-my">
<el-skeleton v-if="loading" :rows="2" animated />
<template v-else>
<el-empty v-if="myFilter.length<=0" :image-size="100">
<template #description>
<h2>没有常用的过滤</h2>
<p style="margin-top: 10px;max-width: 300px;">常用过滤可以将多个过滤条件保存为一个集合方便下次进行相同条件的过滤</p>
</template>
</el-empty>
<ul v-else class="sc-filter-my-list">
<li v-for="(item, index) in myFilter" :key="index"><el-tag closable size="medium" effect="dark" type="info" @click="selectMyfilter(item)" @close="closeMyfilter(item, index)">{{item.title}}</el-tag></li>
</ul>
</template>
</div>
</template>
<script>
import config from "@/config/filterBar";
export default {
props: {
filterName: { type: String, default: "" },
data: { type: Object, default: () => {} }
},
data() {
return {
loading: false,
myFilter: []
}
},
watch:{
data: {
handler(){
this.myFilter = this.data
},
deep: true
}
},
mounted() {
this.myFilter = this.data
this.getMyfilter()
},
methods: {
//
selectMyfilter(item){
this.$emit('selectMyfilter', item)
},
//
closeMyfilter(item, index){
this.$confirm('此操作将永久删除该常用, 是否继续?', '提示', {
type: 'warning'
}).then(async () => {
try {
var del = await config.delMy(this.filterName)
}catch (error) {
return false
}
if(!del){
return false
}
this.myFilter.splice(index, 1)
this.$message.success('删除常用成功')
}).catch(() => {
//
})
},
//
async getMyfilter(){
this.loading = true
try {
this.myFilter = await config.getMy(this.filterName)
}catch (error) {
return false
}
this.loading = false
}
}
}
</script>
<style scoped>
.sc-filter-my {padding:15px;}
.sc-filter-my-list {list-style-type: none;}
.sc-filter-my-list li {margin-bottom: 15px;}
.sc-filter-my-list li .el-tag {cursor: pointer;}
</style>

74
src/config/filterBar.js Normal file
View File

@ -0,0 +1,74 @@
export default {
//运算符
operator: [
{
label: '等于',
value: '=',
},
{
label: '不等于',
value: '!=',
},
{
label: '大于',
value: '>',
},
{
label: '大于等于',
value: '>=',
},
{
label: '小于',
value: '<',
},
{
label: '小于等于',
value: '<=',
},
{
label: '包含',
value: 'include',
},
{
label: '不包含',
value: 'notinclude',
}
],
//过滤结果运算符的分隔符
separator: '|',
//获取我的常用
getMy: function (name) {
return new Promise((resolve) => {
console.log(`这里可以根据${name}参数请求接口`)
var list = []
setTimeout(()=>{
resolve(list)
},500)
})
},
/**
* 常用保存处理 返回resolve后继续操作
* @name scFilterBar组件的props->filterName
* @obj 过滤项整理好的对象
*/
saveMy: function (name, obj) {
return new Promise((resolve) => {
console.log(name, obj)
setTimeout(()=>{
resolve(true)
},500)
})
},
/**
* 常用删除处理 返回resolve后继续操作
* @name scFilterBar组件的props->filterName
*/
delMy: function (name) {
return new Promise((resolve) => {
console.log(name)
setTimeout(()=>{
resolve(true)
},500)
})
}
}

View File

@ -41,15 +41,6 @@ const routes = [{
icon: "el-icon-orange",
},
component: () => import(/* webpackChunkName: "usercenter" */ '@/views/vab/iconselect'),
},
{
name: "filterbar2",
path: "/vab/filterbar2",
meta: {
title: "过滤器v2",
icon: "el-icon-set-up",
},
component: () => import(/* webpackChunkName: "usercenter" */ '@/views/vab/filterbar2'),
}
]
}

2
src/utils/pinyin.js Normal file

File diff suppressed because one or more lines are too long

View File

@ -1,9 +1,9 @@
<template>
<el-main>
<el-card shadow="never">
<scFilterBar :options="options" :defaultFilter="defaultFilter" @change="change"></scFilterBar>
<scFilterBar filterName="filterName" :options="options" @filterChange="change"></scFilterBar>
</el-card>
<el-alert title="SCUI 独创的过滤条Filterbar,可配置不同类型的过滤字段,以及异步获取数据,操作上方过滤条查看下方change事件的回调,在表格查询的场景下非常合适" type="success" style="margin:20px 0;"></el-alert>
<el-alert title="SCUI 独创的过滤条Filterbar,可配置不同类型的过滤字段,以及异步获取数据,在@/config/filterBar.js中可以更改运算符以及其他配置,操作上方过滤条查看下方change事件的回调,在表格查询的场景下非常合适" type="success" style="margin:20px 0;"></el-alert>
<el-card shadow="never">
<pre>{{ filterData }}</pre>
</el-card>
@ -24,14 +24,19 @@
defaultFilter : [],
options: [
{
label: '输入框',
value: 'name',
type: 'text'
label: '订单号',
value: 'id',
type: 'text',
selected: true,
placeholder: '请输入订单号'
},
{
label: '固定下拉框',
label: '类型',
value: 'type',
type: 'select',
operator: '=',
selected: true,
placeholder: '请选择类型',
extend: {
data:[
{
@ -46,9 +51,11 @@
}
},
{
label: '固定下拉框(多选)',
label: '类型(多选)',
value: 'type2',
type: 'select',
operator: '=',
placeholder: '请选择类型',
extend: {
multiple: true,
data:[
@ -64,28 +71,42 @@
}
},
{
label: '异步下拉框',
value: 'type3',
label: '通知(异步)',
value: 'noticeType',
type: 'select',
operator: '=',
placeholder: '请选择通知类型',
extend: {
request: async () => {
var list = await this.$API.demo.select.get();
return list.data;
var list = await this.$API.dic.info.get()
return list.data.map(item => {
return {
label: item.name,
value: item.key
}
})
}
}
},
{
label: '远程搜索下拉框',
value: 'type4',
label: '通知(远程搜索)',
value: 'noticeType2',
type: 'select',
operator: '=',
placeholder: '请输入关键词后检索',
extend: {
remote: true,
request: async (query) => {
var data = {
keyword: query,
}
var list = await this.$API.demo.select.get(data);
return list.data;
var list = await this.$API.dic.info.get(data)
return list.data.map(item => {
return {
label: item.name,
value: item.key
}
})
}
}
},

View File

@ -1,242 +0,0 @@
<!--
* @Descripttion: 过滤器V2
* @version: 2.0
* @Author: sakuya
* @Date: 2021年7月30日14:48:41
* @LastEditors:
* @LastEditTime:
-->
<template>
<el-main>
<el-card shadow="never">
<el-badge :value="2" type="danger">
<el-button size="small" icon="sc-icon-filter-line" @click="openFilter"></el-button>
</el-badge>
<el-drawer title="过滤器" v-model="drawer" :size="650">
<el-container>
<el-main style="padding:0">
<el-tabs class="root">
<el-tab-pane>
<template #label>
<div class="tabs-label">
过滤项
</div>
</template>
<el-scrollbar>
<div class="sc-filter-main">
<h2>设置过滤条件</h2>
<el-alert v-if="filter.length<=0" title="没有默认过滤条件,请点击增加过滤项" type="warning" :closable="false" center style="margin:15px 0;"></el-alert>
<table v-else>
<colgroup>
<col width="50">
<col width="140">
<col>
<col width="40">
</colgroup>
<tr v-for="(item,index) in filter" :key="index">
<td>
<el-tag size="medium">{{index+1}}</el-tag>
</td>
<td>
<el-select v-model="item.field" placeholder="过滤字段" filterable @change="fieldChange(item)">
<el-option v-for="field in fields" :key="field.value" :label="field.label" :value="field"></el-option>
</el-select>
</td>
<td>
<el-input v-if="item.field.type=='text'" v-model="item.value" :placeholder="item.field.placeholder"></el-input>
<el-select v-if="item.field.type=='select'" v-model="item.value" :placeholder="item.field.placeholder" filterable :multiple="item.field.extend.multiple">
<el-option v-for="field in item.field.extend.data" :key="field.value" :label="field.label" :value="field.value"></el-option>
</el-select>
<el-date-picker v-if="item.field.type=='datetime'" v-model="item.value" type="datetime" :placeholder="item.field.placeholder" style="width: 100%;"></el-date-picker>
<el-date-picker v-if="item.field.type=='datetimerange'" v-model="item.value" type="datetimerange" start-placeholder="开始日期" end-placeholder="结束日期" style="width: 100%;"></el-date-picker>
<el-switch v-if="item.field.type=='switch'" v-model="item.value"></el-switch>
</td>
<td>
<i class="el-icon-delete del" @click="delFilter(index)"></i>
</td>
</tr>
</table>
<el-button type="text" icon="el-icon-plus" @click="addFilter">增加过滤项</el-button>
</div>
</el-scrollbar>
</el-tab-pane>
<el-tab-pane>
<template #label>
<div class="tabs-label">
常用
</div>
</template>
<el-scrollbar>
<ul class="sc-filter-my">
<li><label>已过期的用户</label></li>
<li><label>类型为正常且已缴费的用户</label></li>
</ul>
</el-scrollbar>
</el-tab-pane>
</el-tabs>
</el-main>
<el-footer>
<el-button type="primary" @click="ok">立即过滤</el-button>
<el-button type="primary" plain @click="savemy">保存常用</el-button>
<el-button>重置</el-button>
</el-footer>
</el-container>
</el-drawer>
</el-card>
</el-main>
</template>
<script>
export default {
name: 'filterBar2',
data() {
return {
drawer: false,
form: {
checkboxGroup1: ['1'],
radio1: ''
},
fields: [
{
label: 'ID',
value: 'id',
type: 'text',
selected: true,
placeholder: '请输入ID'
},
{
label: '姓名',
value: 'name',
type: 'text',
placeholder: '请输入姓名'
},
{
label: '类型',
value: 'type',
type: 'select',
selected: true,
placeholder: '请选择类型',
extend: {
//multiple: true,
data: [
{
label: "选项1",
value: "1"
},
{
label: "选项2",
value: "2"
}
]
}
},
{
label: '注册日期',
value: 'date',
type: 'datetime',
placeholder: '请选择日期时间'
},
{
label: '有效期',
value: 'date2',
type: 'datetimerange',
placeholder: '请选择日期时间'
},
{
label: '是否警用',
value: 'switch',
type: 'switch'
}
],
filter: []
}
},
mounted() {
//
this.fields.forEach((item) => {
if(item.selected){
this.filter.push({
field: item,
value: ''
})
}
})
},
methods: {
openFilter(){
this.drawer = true
},
addFilter(){
this.filter.push({
field: this.fields[0],
value: ''
})
},
delFilter(index){
console.log(index)
this.filter.splice(index, 1)
},
ok(){
console.log(this.filter);
},
fieldChange(tr){
tr.value = ''
},
savemy(){
this.$prompt('请输入常用过滤名称', '提示', {
inputPlaceholder: '请输入常用过滤名称'
})
.then(({ value }) => {
console.log(value);
})
.catch(() => {
//
})
}
}
}
</script>
<style scoped>
.tabs-label {padding:0 20px;}
.sc-filter-main {padding:20px;border-bottom: 1px solid #e6e6e6;background: #fff;}
.sc-filter-main h2 {font-size: 12px;color: #999;font-weight: normal;}
.sc-filter-main table {width: 100%;margin: 15px 0;}
.sc-filter-main table tr {}
.sc-filter-main table td {padding:5px 10px 5px 0;}
.sc-filter-main table td .el-select {display: block;}
.sc-filter-main table td .el-date-editor.el-input {display: block;width: 100%;}
.sc-filter-main table td .del {background: #fff;color: #999;width: 32px;height: 32px;line-height: 32px;text-align: center;border-radius:50%;font-size: 12px;cursor: pointer;}
.sc-filter-main table td .del:hover {background: #F56C6C;color: #fff;}
.sc-filter-my {list-style-type: none;padding:15px;}
.sc-filter-my li {font-size: 12px;margin-bottom: 15px;}
.sc-filter-my li label {background: #222b45;color: #fff;padding:5px 10px;border-radius:4px;}
.sc-filter-my li:hover {box-shadow: 0 2px 12px 0 rgba(0,0,0,0.1);position: relative;}
.root {
display: flex;
height: 100%;
flex-direction: column
}
.root:deep(.el-tabs__header) {margin: 0;}
.root:deep(.el-tabs__content) {flex: 1;background: #f6f8f9;}
.root:deep(.el-tabs__content) .el-tab-pane{overflow: auto;height:100%;}
</style>