提交 8d26ccc5 编写于 作者: RedPig97's avatar RedPig97

update: 搜索栏组件

上级 ef033278
...@@ -139,6 +139,7 @@ import AppPresetButton from './components/layout-element/interactive/app-preset- ...@@ -139,6 +139,7 @@ import AppPresetButton from './components/layout-element/interactive/app-preset-
import AppFieldImageDynamic from './components/layout-element/media/app-field-image-dynamic/app-field-image-dynamic.vue'; import AppFieldImageDynamic from './components/layout-element/media/app-field-image-dynamic/app-field-image-dynamic.vue';
import AppTodoList from './components/app-todo-list/app-todo-list.vue'; import AppTodoList from './components/app-todo-list/app-todo-list.vue';
import AppGridPagination from './components/app-grid-pagination/app-grid-pagination.vue'; import AppGridPagination from './components/app-grid-pagination/app-grid-pagination.vue';
import AppSearchbar from './components/app-searchbar/app-searchbar.vue';
import ExtendActionTimeline from './components/extend-action-timeline/extend-action-timeline.vue'; import ExtendActionTimeline from './components/extend-action-timeline/extend-action-timeline.vue';
// 布局组件 // 布局组件
import AppIndexViewLayoutLeft from './layout/index-view-layout-left/index-view-layout-left.vue'; import AppIndexViewLayoutLeft from './layout/index-view-layout-left/index-view-layout-left.vue';
...@@ -307,6 +308,7 @@ export const AppComponents = { ...@@ -307,6 +308,7 @@ export const AppComponents = {
v.component('app-field-image-dynamic', AppFieldImageDynamic); v.component('app-field-image-dynamic', AppFieldImageDynamic);
v.component('app-todo-list',AppTodoList); v.component('app-todo-list',AppTodoList);
v.component('app-grid-pagination',AppGridPagination); v.component('app-grid-pagination',AppGridPagination);
v.component('app-searchbar',AppSearchbar);
v.component('extend-action-timeline',ExtendActionTimeline); v.component('extend-action-timeline',ExtendActionTimeline);
v.component('app-pickup-view-layout',AppPickUpViewLayout); v.component('app-pickup-view-layout',AppPickUpViewLayout);
v.component('app-mpickup-view-layout',AppMPickUpViewLayout); v.component('app-mpickup-view-layout',AppMPickUpViewLayout);
......
...@@ -28,12 +28,14 @@ ...@@ -28,12 +28,14 @@
.grid-page-pre-pro,.grid-page-next-pro { .grid-page-pre-pro,.grid-page-next-pro {
font-size: 24px; font-size: 24px;
margin-top: -2px; margin-top: -2px;
cursor: pointer;
} }
.ivu-icon { .ivu-icon {
font-size: 24px; font-size: 24px;
color: var(--app-color-gray-100); color: var(--app-color-gray-100);
} }
.grid-pagination__dropdown { .grid-pagination__dropdown {
cursor: pointer;
span { span {
color: var(--app-color-black); color: var(--app-color-black);
font-weight: 600; font-weight: 600;
......
<template>
<el-select size="small" class="app-searchbar-mode" :placeholder="$t('components.filterMode.placeholder')" v-model="curVal" @change="onChange">
<el-option
v-for="mode in fieldFilterMode"
:key="mode.value"
:label="getLabel(mode)"
:value="mode.value"
>
</el-option>
</el-select>
</template>
<script lang="ts">
import { Vue, Component, Model, Prop, Watch } from "vue-property-decorator";
@Component({})
export default class FilterMode extends Vue {
/**
* 值属性
*
* @type {*}
* @memberof FilterMode
*/
@Model('change') readonly value: any;
/**
* 自定义逻辑集合
*
* @type {*}
* @memberof FilterMode
*/
@Prop() modes!: any[];
@Watch('modes')
onModesChange(newVal: any) {
this.setDefValue();
}
get curVal() {
return this.value;
}
set curVal(val: any) {
const type: string = this.$util.typeOf(val);
val = Object.is(type, 'null') || Object.is(type, 'undefined') ? undefined : val;
this.$emit('change', val);
}
get fieldFilterMode() {
if(this.modes && this.modes.length > 0) {
let index: number = this.modes.findIndex((mode: any) => Object.is(mode.mode, 'all'));
if(index < 0) {
let items: any[] = [];
this.modes.forEach((mode: any) => {
let item: any = this.filterMode.find((filter: any) => Object.is(filter['en-US'], mode.mode));
items.push(item);
})
return items;
}
}
return this.filterMode;
}
/**
* 过滤模式
*
* @type {*}
* @memberof FilterMode
*/
public filterMode: any[] = [
// { name: 'AND', value: '$and' },
// { name: 'OR', value: '$or' },
{ 'zh-CN': '等于(=)', 'en-US': 'EQ', value: '$eq' },
{ 'zh-CN': '不等于(<>)', 'en-US': 'NOTEQ', value: '$ne' },
{ 'zh-CN': '大于(>)', 'en-US': 'GT', value: '$gt' },
{ 'zh-CN': '大于等于(>=)', 'en-US': 'GTANDEQ', value: '$gte' },
{ 'zh-CN': '小于(<)', 'en-US': 'LT', value: '$lt' },
{ 'zh-CN': '小于等于(<=)', 'en-US': 'LTANDEQ', value: '$lte' },
{ 'zh-CN': '值为空(Nil)', 'en-US': 'ISNULL', value: '$null' },
{ 'zh-CN': '值不为空(NotNil)', 'en-US': 'ISNOTNULL', value: '$notNull' },
{ 'zh-CN': '值在范围中(In)', 'en-US': 'IN', value: '$in' },
{ 'zh-CN': '值不在范围中(NotIn)', 'en-US': 'NOTIN', value: '$notIn' },
{ 'zh-CN': '文本包含(%)', 'en-US': 'LIKE', value: '$like' },
{ 'zh-CN': '文本左包含(%#)', 'en-US': 'LIFTLIKE', value: '$startsWith' },
{ 'zh-CN': '文本右包含(#%)', 'en-US': 'RIGHTLIKE', value: '$endsWith' },
// { 'zh-CN': '', en: 'EXISTS', value: '$exists' },
// { 'zh-CN': '', en: 'NOTEXISTS', value: '$notExists' }
];
/**
* 生命周期
*
* @return {void}
* @memberof FilterMode
*/
public mounted() {
this.setDefValue()
}
/**
* 设置默认值
*
* @return {void}
* @memberof FilterMode
*/
public setDefValue() {
if(this.fieldFilterMode.length > 0) {
this.curVal = this.fieldFilterMode[0].value;
this.onChange();
}
}
/**
* 获取语言文本
*
* @return {string}
* @memberof FilterMode
*/
public getLabel(mode: any): string {
if(this.$i18n.locale) {
return mode[this.$i18n.locale];
}
return mode['zh-CN'];
}
/**
* 值改变
*
* @memberof FilterMode
*/
public onChange() {
this.$nextTick(() => {
let item: any = this.filterMode.find((filter: any) => Object.is(filter.value, this.curVal));
if(this.modes && this.modes.length > 0) {
let mode: any = this.modes.find((mode: any) => Object.is(mode.mode, item['en-US']));
if(!mode) {
mode = this.modes.find((mode: any) => Object.is(mode.mode, 'all'));
}
this.$emit('on-change', mode);
}
})
}
}
</script>
\ No newline at end of file
.app-searchbar {
width: 100%;
padding: 10px 20px 0px 20px;
background: var(--app-color-white);
display: flex;
flex-direction: column;
gap: 10px;
.app-searchbar-group {
width: 100%;
display: flex;
align-items: center;
gap: 30px;
.app-searchbar-item {
position: relative;
width: 100%;
padding-right: 110px;
}
.app-searchbar-action {
position: absolute;
right: 75px;
top: 5px;
cursor: pointer;
}
}
}
\ No newline at end of file
<template>
<div class="app-searchbar">
<div class="app-searchbar-group" v-for="(item,index) in condItems">
<el-select size="small" class="app-searchbar-field app-searchbar-item" v-model="item.field" clearable :placeholder="$t('components.filterTree.placeholder')">
<el-option
v-for="field in fieldItems"
:key="field.value"
:label="field.label"
:value="field.value">
</el-option>
</el-select>
<AppSearchMode class="app-searchbar-item" v-model="item.mode" :modes="getModes(item.field)" @on-change="onModeChange($event, item)"></AppSearchMode>
<div class="app-searchbar-value app-searchbar-item">
<i-input v-if="!item.editor"></i-input>
<div v-else :key="item.editor">
<slot :data="item"></slot>
</div>
<div class="app-searchbar-action">
<img v-if="index === condItems.length - 1" src="assets/img/ic_add_circle.svg" @click="onAddItem()">
<img v-else src="assets/img/remove_circle.svg" @click="onRemoveItem(index)">
</div>
</div>
</div>
</div>
</template>
<script lang="ts">
import {Vue, Component, Prop, Watch} from 'vue-property-decorator';
import AppSearchMode from './app-searchbar-mode.vue';
@Component({
components: {
AppSearchMode
}
})
export default class AppSearchbar extends Vue {
/**
* 数据集
*
* @type {*}
* @memberof AppSearchbar
*/
@Prop() items: any;
/**
* 过滤项集合
*
* @type {*}
* @memberof AppSearchbar
*/
@Prop() fields: any;
@Watch("items", {immediate: true})
onItemsChange(newItems: any[]) {
this.condItems = [];
if (newItems && newItems.length > 0) {
this.condItems.push(...newItems);
} else {
this.condItems.push({
field: null,
mode: null,
editor: null
});
}
}
/**
* 属性项集合
*
* @type {*}
* @memberof AppSearchbar
*/
protected fieldItems: any[] = [];
/**
* 条件项集合
*
* @type {*}
* @memberof AppSearchbar
*/
protected condItems: any[] = [];
/**
* 生命周期
*
* @return {void}
* @memberof AppSearchbar
*/
public created() {
if(!this.fields) {
return;
}
this.fields.forEach((field: any) => {
let index: number = this.fieldItems.findIndex((item: any) => Object.is(item.value, field.prop));
if(index < 0) {
this.fieldItems.push({
label: field.label,
value: field.prop,
modes: this.getFieldModes(field.prop)
})
}
});
}
/**
* 获取逻辑模式集合
*
* @return {void}
* @memberof AppSearchbar
*/
public getModes(field: string) {
if(this.fieldItems.length > 0) {
let item: any = this.fieldItems.find((item: any) => Object.is(item.value, field));
if(item) {
return item.modes;
}
}
return [];
}
/**
* 获取属性逻辑模式集合
*
* @return {void}
* @memberof AppSearchbar
*/
public getFieldModes(name: string) {
let modes: any[] = [];
for(let i = 0; i < this.fields.length; i++) {
let field: any = this.fields[i];
if(!Object.is(field.prop, name)) {
continue;
}
modes.push({
name: field.name,
mode: field.mode ? field.mode : 'all'
})
}
return modes;
}
/**
* 添加条件
*
* @return {*}
* @memberof AppSearchbar
*/
public onAddItem(data: any) {
this.items.push({
field: null,
mode: null,
editor: null
});
}
/**
* 删除条件/组
*
* @return {*}
* @memberof AppSearchbar
*/
public onRemoveItem(index: number) {
this.items.splice(index, 1);
}
/**
* 条件逻辑变化
*
* @return {*}
* @memberof AppSearchbar
*/
public onModeChange(mode: any, data: any) {
if(mode && data) {
data.editor = mode.name;
}
}
}
</script>
<style lang="scss">
@import './app-searchbar.scss';
</style>
\ No newline at end of file
...@@ -48,23 +48,6 @@ ...@@ -48,23 +48,6 @@
} }
} }
.el-table--enable-row-hover .el-table__body tr:hover>td {
background-color: #badfffba !important;
}
.el-table th .sort-caret.ascending{
border-bottom-color: #f0f2f5;
}
.el-table th.ascending .sort-caret.ascending {
border-bottom-color: #909399;
}
.el-table th .sort-caret.descending{
border-top-color: #f0f2f5;
}
.el-table th.descending .sort-caret.descending {
border-top-color: #909399;
}
// tab分页模式首页布局 // tab分页模式首页布局
.index_tab_content{ .index_tab_content{
>.view-container { >.view-container {
......
Markdown 格式
0% or
您添加了 0 到此讨论。请谨慎行事。
先完成此消息的编辑!
想要评论请 注册