143 lines
3.9 KiB
Vue
143 lines
3.9 KiB
Vue
<template>
|
||
<div class="top-right-btn" :style="style">
|
||
<div class="flex items-center">
|
||
<!-- 添加按钮 -->
|
||
<el-button :disabled="props.disableAdd" v-if="props.showAdd" icon="Plus" type="primary" @click="toggleSearch()">
|
||
{{ props.addTitle }}
|
||
</el-button>
|
||
<slot name="actions"></slot>
|
||
<!-- 批量操作下拉框 -->
|
||
<el-dropdown v-if="props.showDelete || props.showEdit || $slots.dropdown" trigger="click" style="margin-left: 10px">
|
||
<el-button @click.stop="refresh"> {{ props.moreTitle }} </el-button>
|
||
|
||
<!-- 👇 核心:优先使用外部插槽,没有则使用默认内容 -->
|
||
<template #dropdown>
|
||
<!-- 这里直接渲染,不嵌套插槽 -->
|
||
<el-dropdown-menu v-if="!$slots.dropdown">
|
||
<el-dropdown-item :disabled="props.disableEdit" v-if="props.showEdit" @click="emits('update:edit')">
|
||
{{ props.editTitle }}
|
||
</el-dropdown-item>
|
||
<el-dropdown-item :disabled="props.disableDelete" v-if="props.showDelete" @click="emits('update:delete')">
|
||
{{ props.deleteTitle }}
|
||
</el-dropdown-item>
|
||
</el-dropdown-menu>
|
||
<!-- 外部自定义内容直接渲染,不包任何多余标签 -->
|
||
<template v-else>
|
||
<slot name="dropdown" />
|
||
</template>
|
||
</template>
|
||
</el-dropdown>
|
||
|
||
<!-- 显隐列(保留你原有逻辑) -->
|
||
<el-tooltip v-if="columns" class="item" effect="dark" content="显示/隐藏列" placement="top">
|
||
<div class="show-btn">
|
||
<el-popover placement="bottom" trigger="click">
|
||
<div class="tree-header">显示/隐藏列</div>
|
||
<el-tree
|
||
ref="columnRef"
|
||
:data="columns"
|
||
show-checkbox
|
||
node-key="key"
|
||
:props="{ label: 'label', children: 'children' }"
|
||
@check="columnChange"
|
||
></el-tree>
|
||
<template #reference>
|
||
<el-button circle icon="Menu" />
|
||
</template>
|
||
</el-popover>
|
||
</div>
|
||
</el-tooltip>
|
||
</div>
|
||
</div>
|
||
</template>
|
||
|
||
<script setup lang="ts">
|
||
import { propTypes } from '@/utils/propTypes';
|
||
import { CSSProperties } from 'vue';
|
||
|
||
const props = defineProps({
|
||
columns: propTypes.fieldOption,
|
||
gutter: propTypes.number.def(10),
|
||
moreTitle: propTypes.string.def('更多操作'),
|
||
|
||
showAdd: propTypes.bool.def(true),
|
||
showDelete: propTypes.bool.def(true),
|
||
showEdit: propTypes.bool.def(true),
|
||
|
||
addTitle: propTypes.string.def('新建'),
|
||
editTitle: propTypes.string.def('编辑'),
|
||
deleteTitle: propTypes.string.def('批量删除'),
|
||
|
||
disableAdd: propTypes.bool.def(false),
|
||
disableDelete: propTypes.bool.def(false),
|
||
disableEdit: propTypes.bool.def(false)
|
||
});
|
||
|
||
const columnRef = ref();
|
||
const emits = defineEmits(['update:add', 'update:edit', 'update:delete']);
|
||
|
||
const style = computed<CSSProperties>(() => {
|
||
const ret: CSSProperties = {};
|
||
if (props.gutter) {
|
||
ret.marginRight = `${props.gutter / 2}px`;
|
||
}
|
||
return ret;
|
||
});
|
||
|
||
// 添加
|
||
function toggleSearch() {
|
||
emits('update:add');
|
||
}
|
||
|
||
const isExpent = ref(false);
|
||
// 批量操作展开
|
||
function refresh() {
|
||
isExpent.value = !isExpent.value;
|
||
}
|
||
|
||
// 更改显示隐藏列
|
||
function columnChange(...args) {
|
||
props.columns?.forEach((item) => {
|
||
item.visible = args[1].checkedKeys.includes(item.key);
|
||
});
|
||
}
|
||
|
||
onMounted(() => {
|
||
props.columns?.forEach((item) => {
|
||
if (item.visible) {
|
||
columnRef.value?.setChecked(item.key, true, false);
|
||
}
|
||
});
|
||
});
|
||
</script>
|
||
|
||
<style lang="scss" scoped>
|
||
.hiddenActions {
|
||
margin-left: 10px;
|
||
}
|
||
|
||
:deep(.el-transfer__button) {
|
||
border-radius: 50%;
|
||
display: block;
|
||
margin-left: 0;
|
||
}
|
||
|
||
:deep(.el-transfer__button:first-child) {
|
||
margin-bottom: 10px;
|
||
}
|
||
|
||
.my-el-transfer {
|
||
text-align: center;
|
||
}
|
||
|
||
.tree-header {
|
||
width: 100%;
|
||
line-height: 24px;
|
||
text-align: center;
|
||
}
|
||
|
||
.show-btn {
|
||
margin-left: 12px;
|
||
}
|
||
</style>
|