mirror of
https://github.com/pure-admin/vue-pure-admin.git
synced 2025-06-07 17:07:19 +08:00
feat: 优化 PureTableBar
组件,列展示添加拖拽功能 (#545)
* feat: add 表格工具列拖拽 * fix: 修复拖拽 * fix: 修复警告 * fix: 修复点击checkbox表格数据隐藏 * chore: update --------- Co-authored-by: RealityBoy <1923740402@qq.com>
This commit is contained in:
parent
a71bf0befb
commit
43ddf7aba8
@ -1,6 +1,9 @@
|
|||||||
import { useEpThemeStoreHook } from "@/store/modules/epTheme";
|
import { useEpThemeStoreHook } from "@/store/modules/epTheme";
|
||||||
import { delay, getKeyList, cloneDeep } from "@pureadmin/utils";
|
import { delay, getKeyList, cloneDeep } from "@pureadmin/utils";
|
||||||
import { defineComponent, ref, computed, type PropType } from "vue";
|
import { defineComponent, ref, computed, type PropType, nextTick } from "vue";
|
||||||
|
|
||||||
|
import Sortable from "sortablejs";
|
||||||
|
import DragIcon from "./svg/drag.svg?component";
|
||||||
import ExpandIcon from "./svg/expand.svg?component";
|
import ExpandIcon from "./svg/expand.svg?component";
|
||||||
import RefreshIcon from "./svg/refresh.svg?component";
|
import RefreshIcon from "./svg/refresh.svg?component";
|
||||||
import SettingIcon from "./svg/settings.svg?component";
|
import SettingIcon from "./svg/settings.svg?component";
|
||||||
@ -107,16 +110,17 @@ export default defineComponent({
|
|||||||
checkedCount > 0 && checkedCount < checkColumnList.length;
|
checkedCount > 0 && checkedCount < checkColumnList.length;
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleCheckColumnListChange(val: boolean, index: number) {
|
function handleCheckColumnListChange(val: boolean, label: string) {
|
||||||
dynamicColumns.value[index].hide = !val;
|
dynamicColumns.value.filter(item => item.label === label)[0].hide = !val;
|
||||||
}
|
}
|
||||||
|
|
||||||
function onReset() {
|
async function onReset() {
|
||||||
checkAll.value = true;
|
checkAll.value = true;
|
||||||
isIndeterminate.value = false;
|
isIndeterminate.value = false;
|
||||||
checkColumnList = getKeyList(cloneDeep(props?.columns), "label");
|
|
||||||
checkedColumns.value = checkColumnList;
|
|
||||||
dynamicColumns.value = cloneDeep(props?.columns);
|
dynamicColumns.value = cloneDeep(props?.columns);
|
||||||
|
checkColumnList = [];
|
||||||
|
checkColumnList = await getKeyList(cloneDeep(props?.columns), "label");
|
||||||
|
checkedColumns.value = checkColumnList;
|
||||||
}
|
}
|
||||||
|
|
||||||
const dropdown = {
|
const dropdown = {
|
||||||
@ -144,6 +148,47 @@ export default defineComponent({
|
|||||||
)
|
)
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/** 列展示拖拽排序 */
|
||||||
|
const rowDrop = (event: { preventDefault: () => void }) => {
|
||||||
|
event.preventDefault();
|
||||||
|
nextTick(() => {
|
||||||
|
const wrapper: HTMLElement = document.querySelector(
|
||||||
|
".el-checkbox-group>div"
|
||||||
|
);
|
||||||
|
Sortable.create(wrapper, {
|
||||||
|
animation: 300,
|
||||||
|
handle: ".drag-btn",
|
||||||
|
onEnd: ({ newIndex, oldIndex, item }) => {
|
||||||
|
const targetThElem = item;
|
||||||
|
const wrapperElem = targetThElem.parentNode as HTMLElement;
|
||||||
|
const oldColumn = dynamicColumns.value[oldIndex];
|
||||||
|
const newColumn = dynamicColumns.value[newIndex];
|
||||||
|
if (oldColumn?.fixed || newColumn?.fixed) {
|
||||||
|
// 当前列存在fixed属性 则不可拖拽
|
||||||
|
const oldThElem = wrapperElem.children[oldIndex] as HTMLElement;
|
||||||
|
if (newIndex > oldIndex) {
|
||||||
|
wrapperElem.insertBefore(targetThElem, oldThElem);
|
||||||
|
} else {
|
||||||
|
wrapperElem.insertBefore(
|
||||||
|
targetThElem,
|
||||||
|
oldThElem ? oldThElem.nextElementSibling : oldThElem
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const currentRow = dynamicColumns.value.splice(oldIndex, 1)[0];
|
||||||
|
dynamicColumns.value.splice(newIndex, 0, currentRow);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const isFixedColumn = (label: string) => {
|
||||||
|
return dynamicColumns.value.filter(item => item.label === label)[0].fixed
|
||||||
|
? true
|
||||||
|
: false;
|
||||||
|
};
|
||||||
|
|
||||||
const reference = {
|
const reference = {
|
||||||
reference: () => (
|
reference: () => (
|
||||||
<SettingIcon
|
<SettingIcon
|
||||||
@ -191,7 +236,6 @@ export default defineComponent({
|
|||||||
/>
|
/>
|
||||||
</el-tooltip>
|
</el-tooltip>
|
||||||
<el-divider direction="vertical" />
|
<el-divider direction="vertical" />
|
||||||
|
|
||||||
<el-tooltip effect="dark" content="密度" placement="top">
|
<el-tooltip effect="dark" content="密度" placement="top">
|
||||||
<el-dropdown v-slots={dropdown} trigger="click">
|
<el-dropdown v-slots={dropdown} trigger="click">
|
||||||
<CollapseIcon class={["w-[16px]", iconClass.value]} />
|
<CollapseIcon class={["w-[16px]", iconClass.value]} />
|
||||||
@ -228,13 +272,25 @@ export default defineComponent({
|
|||||||
alignment="flex-start"
|
alignment="flex-start"
|
||||||
size={0}
|
size={0}
|
||||||
>
|
>
|
||||||
{checkColumnList.map((item, index) => {
|
{checkColumnList.map(item => {
|
||||||
return (
|
return (
|
||||||
|
<div class="flex items-center">
|
||||||
|
<DragIcon
|
||||||
|
class={[
|
||||||
|
"drag-btn w-[16px] mr-2",
|
||||||
|
isFixedColumn(item)
|
||||||
|
? "!cursor-no-drop"
|
||||||
|
: "!cursor-grab"
|
||||||
|
]}
|
||||||
|
onMouseenter={(event: {
|
||||||
|
preventDefault: () => void;
|
||||||
|
}) => rowDrop(event)}
|
||||||
|
/>
|
||||||
<el-checkbox
|
<el-checkbox
|
||||||
key={item}
|
key={item}
|
||||||
label={item}
|
label={item}
|
||||||
onChange={value =>
|
onChange={value =>
|
||||||
handleCheckColumnListChange(value, index)
|
handleCheckColumnListChange(value, item)
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
<span
|
<span
|
||||||
@ -244,6 +300,7 @@ export default defineComponent({
|
|||||||
{item}
|
{item}
|
||||||
</span>
|
</span>
|
||||||
</el-checkbox>
|
</el-checkbox>
|
||||||
|
</div>
|
||||||
);
|
);
|
||||||
})}
|
})}
|
||||||
</el-space>
|
</el-space>
|
||||||
|
1
src/components/RePureTableBar/src/svg/drag.svg
Normal file
1
src/components/RePureTableBar/src/svg/drag.svg
Normal file
@ -0,0 +1 @@
|
|||||||
|
<svg width="32" height="32" fill="currentColor" aria-hidden="true" data-icon="holder" viewBox="64 64 896 896"><path d="M300 276.5a56 56 0 1 0 56-97 56 56 0 0 0-56 97zm0 284a56 56 0 1 0 56-97 56 56 0 0 0-56 97zM640 228a56 56 0 1 0 112 0 56 56 0 0 0-112 0zm0 284a56 56 0 1 0 112 0 56 56 0 0 0-112 0zM300 844.5a56 56 0 1 0 56-97 56 56 0 0 0-56 97zM640 796a56 56 0 1 0 112 0 56 56 0 0 0-112 0z"/></svg>
|
After Width: | Height: | Size: 398 B |
@ -21,16 +21,18 @@ export function useRole() {
|
|||||||
background: true
|
background: true
|
||||||
});
|
});
|
||||||
const columns: TableColumnList = [
|
const columns: TableColumnList = [
|
||||||
{
|
// {
|
||||||
label: "勾选列", // 如果需要表格多选,此处label必须设置
|
// label: "勾选列", // 如果需要表格多选,此处label必须设置
|
||||||
type: "selection",
|
// type: "selection",
|
||||||
width: 55,
|
// width: 55,
|
||||||
align: "left"
|
// align: "left",
|
||||||
},
|
// fixed: "left"
|
||||||
|
// },
|
||||||
{
|
{
|
||||||
label: "序号",
|
label: "序号",
|
||||||
type: "index",
|
type: "index",
|
||||||
width: 70
|
width: 70,
|
||||||
|
fixed: "left"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: "角色编号",
|
label: "角色编号",
|
||||||
|
@ -24,7 +24,8 @@ export function useUser() {
|
|||||||
{
|
{
|
||||||
label: "序号",
|
label: "序号",
|
||||||
type: "index",
|
type: "index",
|
||||||
width: 70
|
width: 70,
|
||||||
|
fixed: "left"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: "用户编号",
|
label: "用户编号",
|
||||||
|
Loading…
x
Reference in New Issue
Block a user