fix: 【用户管理】筛选条件,组件优化

This commit is contained in:
dataeaseShu 2023-12-14 15:12:07 +08:00
parent 0771b63d5a
commit ae5eaf003f
2 changed files with 42 additions and 203 deletions

View File

@ -1,8 +1,7 @@
<script setup lang="ts"> <script setup lang="ts">
import { propTypes } from '@/utils/propTypes' import { propTypes } from '@/utils/propTypes'
import { ElSelect, ElPopover, ElOption, ElIcon } from 'element-plus-secondary' import { ElSelect, ElOption } from 'element-plus-secondary'
import { computed, reactive, nextTick, ref } from 'vue' import { computed, reactive } from 'vue'
import { Icon } from '@/components/icon-custom'
const props = defineProps({ const props = defineProps({
optionList: propTypes.arrayOf( optionList: propTypes.arrayOf(
@ -15,28 +14,19 @@ const props = defineProps({
}) })
const state = reactive({ const state = reactive({
currentStatus: [],
activeStatus: [] activeStatus: []
}) })
const emits = defineEmits(['filter-change'])
const elPopoverU = ref(null)
const more = ref(null)
const statusChange = (id: string | number) => {
state.activeStatus = state.activeStatus.filter(ele => ele.id !== id)
}
const selectStatus = ids => { const selectStatus = ids => {
const [item] = ids emits(
state.activeStatus.push(item) 'filter-change',
state.currentStatus = [] ids.map(item => item.label)
nextTick(() => { )
elPopoverU.value?.hide()
more.value?.click()
})
} }
const optionListNotSelect = computed(() => { const optionListNotSelect = computed(() => {
return props.optionList.filter(ele => !state.activeStatus.map(t => t.id).includes(ele.id)) return [...props.optionList]
}) })
const clear = () => { const clear = () => {
state.activeStatus = [] state.activeStatus = []
@ -50,48 +40,22 @@ defineExpose({
<div class="filter"> <div class="filter">
<span>{{ title }}</span> <span>{{ title }}</span>
<div class="filter-item"> <div class="filter-item">
<span <el-select
v-for="ele in state.activeStatus" :teleported="false"
:key="ele.id" style="width: 100%"
class="item active" v-model="state.activeStatus"
@click="statusChange(ele.id)" value-key="id"
>{{ $t(ele.name) }}</span filterable
multiple
@change="selectStatus"
> >
<slot v-if="!!optionListNotSelect.length"> <el-option
<el-popover v-for="item in optionListNotSelect"
:show-arrow="false" :key="item.name"
ref="elPopoverU" :label="item.name"
placement="bottom" :value="item"
popper-class="filter-popper" />
width="200" </el-select>
trigger="click"
>
<el-select
:teleported="false"
style="width: 100%"
v-model="state.currentStatus"
value-key="id"
filterable
multiple
@change="selectStatus"
>
<el-option
v-for="item in optionListNotSelect"
:key="item.name"
:label="item.name"
:value="item"
/>
</el-select>
<template #reference>
<span ref="more" class="more">
<el-icon>
<Icon name="icon_add_outlined"> </Icon>
</el-icon>
更多
</span>
</template>
</el-popover>
</slot>
</div> </div>
</div> </div>
</template> </template>
@ -113,45 +77,6 @@ defineExpose({
.filter-item { .filter-item {
flex: 1; flex: 1;
.item,
.more {
font-family: PingFang SC;
white-space: nowrap;
font-size: 14px;
font-weight: 400;
line-height: 24px;
margin-right: 12px;
text-align: center;
padding: 1px 6px;
background: var(--deTextPrimary5, #f5f6f7);
color: var(--deTextPrimary, #1f2329);
border-radius: 2px;
cursor: pointer;
display: inline-block;
margin-bottom: 12px;
}
.active,
.more:hover {
background: var(--primary10, rgba(51, 112, 255, 0.1));
color: var(--primaryselect, #0c296e);
}
.more {
white-space: nowrap;
display: inline-flex;
align-items: center;
i {
margin-right: 5px;
}
}
} }
} }
</style> </style>
<style lang="less">
.filter-popper {
padding: 0 !important;
background: #fff !important;
}
</style>

View File

@ -1,8 +1,7 @@
<script setup lang="ts"> <script setup lang="ts">
import { propTypes } from '@/utils/propTypes' import { propTypes } from '@/utils/propTypes'
import { ElTreeSelect, ElPopover, ElIcon } from 'element-plus-secondary' import { ElTreeSelect } from 'element-plus-secondary'
import { computed, reactive, ref, watch } from 'vue' import { computed, reactive, ref } from 'vue'
import { Icon } from '@/components/icon-custom'
const props = defineProps({ const props = defineProps({
optionList: propTypes.arrayOf( optionList: propTypes.arrayOf(
@ -21,18 +20,8 @@ const state = reactive({
activeStatus: [] activeStatus: []
}) })
const elPopoverU = ref(null) const emits = defineEmits(['filter-change'])
const more = ref(null) const filterTree = ref()
const filterTree = ref(null)
const statusChange = (value: string | number) => {
state.activeStatus = state.activeStatus.filter(ele => ele?.value !== value)
state.currentStatus = state.currentStatus.filter(val => val !== value)
emits(
'filter-change',
state.activeStatus.map(item => item.value)
)
}
const treeChange = () => { const treeChange = () => {
const nodes = state.currentStatus.map(id => { const nodes = state.currentStatus.map(id => {
return filterTree.value?.getNode(id).data return filterTree.value?.getNode(id).data
@ -43,23 +32,12 @@ const treeChange = () => {
state.activeStatus.map(item => item.value) state.activeStatus.map(item => item.value)
) )
} }
watch(
() => state.currentStatus,
() => {
treeChange()
},
{ deep: true, immediate: true }
)
const optionListNotSelect = computed(() => { const optionListNotSelect = computed(() => {
return [...props.optionList] return [...props.optionList]
}) })
const clear = () => { const clear = () => {
state.activeStatus = []
state.currentStatus = [] state.currentStatus = []
} }
const emits = defineEmits(['filter-change'])
defineExpose({ defineExpose({
clear clear
}) })
@ -69,46 +47,21 @@ defineExpose({
<div class="filter"> <div class="filter">
<span>{{ title }}</span> <span>{{ title }}</span>
<div class="filter-item"> <div class="filter-item">
<span <el-tree-select
v-for="ele in state.activeStatus" node-key="value"
:key="ele.value" ref="filterTree"
class="item active" :teleported="false"
@click="statusChange(ele.value)" style="width: 100%"
>{{ $t(ele.label) }}</span @change="treeChange"
> v-model="state.currentStatus"
<slot v-if="!!optionListNotSelect.length"> :data="optionListNotSelect"
<el-popover :highlight-current="true"
:show-arrow="false" multiple
ref="elPopoverU" :render-after-expand="false"
placement="bottom" :placeholder="$t('common.please_select') + $t('user.role')"
popper-class="filter-popper" show-checkbox
width="200" check-on-click-node
trigger="click" />
>
<el-tree-select
ref="filterTree"
node-key="value"
:teleported="false"
style="width: 100%"
v-model="state.currentStatus"
:data="optionListNotSelect"
:highlight-current="true"
multiple
:render-after-expand="false"
:placeholder="$t('common.please_select') + $t('user.role')"
show-checkbox
check-on-click-node
/>
<template #reference>
<span ref="more" class="more">
<el-icon>
<Icon name="icon_add_outlined"> </Icon>
</el-icon>
更多
</span>
</template>
</el-popover>
</slot>
</div> </div>
</div> </div>
</template> </template>
@ -130,45 +83,6 @@ defineExpose({
.filter-item { .filter-item {
flex: 1; flex: 1;
.item,
.more {
font-family: PingFang SC;
white-space: nowrap;
font-size: 14px;
font-weight: 400;
line-height: 24px;
margin-right: 12px;
text-align: center;
padding: 1px 6px;
background: var(--deTextPrimary5, #f5f6f7);
color: var(--deTextPrimary, #1f2329);
border-radius: 2px;
cursor: pointer;
display: inline-block;
margin-bottom: 12px;
}
.active,
.more:hover {
background: var(--primary10, rgba(51, 112, 255, 0.1));
color: var(--primaryselect, #0c296e);
}
.more {
white-space: nowrap;
display: inline-flex;
align-items: center;
i {
margin-right: 5px;
}
}
} }
} }
</style> </style>
<style lang="less">
.filter-popper {
padding: 0 !important;
background: #fff !important;
}
</style>