可信代码库-软件详情增加恶意代码信息
This commit is contained in:
210
src/components/TableFilter/TableFilter.vue
Normal file
210
src/components/TableFilter/TableFilter.vue
Normal file
@@ -0,0 +1,210 @@
|
||||
<template>
|
||||
<div>
|
||||
<d-popover
|
||||
style="background-color: white;"
|
||||
trigger="click"
|
||||
:position="['bottom', 'right', 'left', 'top']"
|
||||
@show="handleShow"
|
||||
>
|
||||
<i :class="['filter-icon', !conditionIsEmpty && 'filter-icon-active']">
|
||||
<svg width="16px" height="16px" viewBox="0 0 16 16" version="1.1" xmlns="http://www.w3.org/2000/svg">
|
||||
<g stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||
<g>
|
||||
<polygon points="10.0085775 7 10.0085775 15 6 13 6 7 2 3 2 1 14 1 14 3"></polygon>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
</i>
|
||||
|
||||
<template #content>
|
||||
<div class="py-[8px] px-[10px]">
|
||||
<div>
|
||||
<d-input v-if="type === 'input'" v-model="formData.input" placeholder="请输入" />
|
||||
<div v-else-if="type === 'checkbox' || type === 'radio'">
|
||||
<div>
|
||||
<div v-if="type === 'checkbox'" class="flex">
|
||||
<d-checkbox
|
||||
v-model="allCheckbox"
|
||||
label="全选"
|
||||
class="mr-[8px]"
|
||||
:half-checked="allCheckboxHalfFlag"
|
||||
@change="allCheckboxChange"
|
||||
/>
|
||||
<d-button size="sm" @click="invertClick">反选</d-button>
|
||||
</div>
|
||||
<div class="max-h-[200px] overflow-y-scroll">
|
||||
<d-radio-group
|
||||
v-if="type === 'radio'"
|
||||
v-model="formData.radio"
|
||||
>
|
||||
<d-radio
|
||||
v-for="item of filterList"
|
||||
:key="item.value"
|
||||
:value="item.value"
|
||||
>{{ item.label }}</d-radio>
|
||||
</d-radio-group>
|
||||
|
||||
<d-checkbox-group v-else v-model="formData.checkbox">
|
||||
<d-checkbox
|
||||
v-for="item in filterList"
|
||||
:key="item.value"
|
||||
:label="item.label"
|
||||
:value="item.value"
|
||||
/>
|
||||
</d-checkbox-group>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex justify-center mt-[8px]">
|
||||
<d-button
|
||||
variant="solid"
|
||||
size="sm"
|
||||
class="mr-[8px]"
|
||||
@click="confirm"
|
||||
>确定</d-button>
|
||||
<d-button size="sm" @click="resetClick">重置</d-button>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</d-popover>
|
||||
<div ref="clickDivRef" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, computed, reactive } from "vue";
|
||||
|
||||
type FilterItemType = string | number | boolean | null;
|
||||
|
||||
const props = defineProps({
|
||||
type: {
|
||||
type: String,
|
||||
default: 'input',
|
||||
validator: value => {
|
||||
return ['input', 'radio', 'checkbox'].includes(value.type);
|
||||
}
|
||||
},
|
||||
condition: { // 默认值
|
||||
type: [String, Number, Array<FilterItemType>, Boolean],
|
||||
default: '',
|
||||
},
|
||||
field: { // 过滤项的key
|
||||
type: String,
|
||||
required: true,
|
||||
},
|
||||
filterList: { // 多选、单选 的选项列表
|
||||
type: Array<{ value: FilterItemType; label: string }>,
|
||||
default: () => {
|
||||
return [];
|
||||
},
|
||||
},
|
||||
});
|
||||
const emit = defineEmits(['filterChange']);
|
||||
|
||||
const clickDivRef = ref();
|
||||
const formData = reactive({
|
||||
input: '',
|
||||
radio: null,
|
||||
checkbox: [] as Array<FilterItemType>,
|
||||
});
|
||||
const allCheckbox = ref(false);
|
||||
const allCheckboxHalfFlag = computed(() => {
|
||||
if (formData.checkbox.length === props.filterList.length) {
|
||||
allCheckbox.value = true;
|
||||
}
|
||||
return formData.checkbox.length && formData.checkbox.length < props.filterList.length;
|
||||
});
|
||||
const filterListValues = computed(() => {
|
||||
return props.filterList.map(item => item.value);
|
||||
});
|
||||
const formDataIsEmpty = computed(() => {
|
||||
if (props.type === 'input') {
|
||||
return formData.input === '';
|
||||
} else if (props.type === 'radio') {
|
||||
return filterListValues.value.findIndex(item => formData.radio === item) === -1;
|
||||
} else if (props.type === 'checkbox') {
|
||||
return formData.checkbox.length === 0;
|
||||
}
|
||||
});
|
||||
const conditionIsEmpty = computed(() => {
|
||||
if (props.type === 'input') {
|
||||
return props.condition === '';
|
||||
} else if (props.type === 'radio') {
|
||||
return filterListValues.value.findIndex(item => props.condition === item) === -1;
|
||||
} else if (props.type === 'checkbox') {
|
||||
return !Array.isArray(props.condition) || props.condition.length === 0;
|
||||
}
|
||||
});
|
||||
|
||||
function handleShow() {
|
||||
formData[props.type] = props.condition;
|
||||
}
|
||||
|
||||
function resetClick() {
|
||||
if (props.type === 'input') {
|
||||
formData.input = '';
|
||||
} else if (props.type === 'radio') {
|
||||
formData.radio = null;
|
||||
}
|
||||
emitFilterChange();
|
||||
}
|
||||
|
||||
function confirm() {
|
||||
emitFilterChange();
|
||||
}
|
||||
|
||||
function emitFilterChange() {
|
||||
emit('filterChange', {
|
||||
field: props.field,
|
||||
value: formData[props.type],
|
||||
});
|
||||
clickDivRef.value.click(); // 用于点击 确认/重置 后关闭弹窗
|
||||
}
|
||||
|
||||
function allCheckboxChange(checkAll: boolean) {
|
||||
if (checkAll) {
|
||||
formData.checkbox = filterListValues.value;
|
||||
} else {
|
||||
formData.checkbox = [];
|
||||
}
|
||||
}
|
||||
|
||||
function invertClick() {
|
||||
formData.checkbox = props.filterList.filter(item => !formData.checkbox.includes(item.value)).map(item => item.value);
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.filter-icon {
|
||||
flex: 1;
|
||||
display: block;
|
||||
height: 16px;
|
||||
text-align: right;
|
||||
cursor: pointer;
|
||||
|
||||
> svg g {
|
||||
fill: $devui-dividing-line;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
> svg g {
|
||||
fill: $devui-icon-fill-active-hover;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.filter-icon-active {
|
||||
visibility: visible !important;
|
||||
|
||||
> svg g {
|
||||
fill: $devui-icon-fill-active;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
> svg g {
|
||||
fill: $devui-icon-fill-active-hover;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user