mirror of
				https://github.com/pure-admin/vue-pure-admin.git
				synced 2025-11-03 13:44:47 +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,22 +272,35 @@ export default defineComponent({
 | 
				
			|||||||
                      alignment="flex-start"
 | 
					                      alignment="flex-start"
 | 
				
			||||||
                      size={0}
 | 
					                      size={0}
 | 
				
			||||||
                    >
 | 
					                    >
 | 
				
			||||||
                      {checkColumnList.map((item, index) => {
 | 
					                      {checkColumnList.map(item => {
 | 
				
			||||||
                        return (
 | 
					                        return (
 | 
				
			||||||
                          <el-checkbox
 | 
					                          <div class="flex items-center">
 | 
				
			||||||
                            key={item}
 | 
					                            <DragIcon
 | 
				
			||||||
                            label={item}
 | 
					                              class={[
 | 
				
			||||||
                            onChange={value =>
 | 
					                                "drag-btn w-[16px] mr-2",
 | 
				
			||||||
                              handleCheckColumnListChange(value, index)
 | 
					                                isFixedColumn(item)
 | 
				
			||||||
                            }
 | 
					                                  ? "!cursor-no-drop"
 | 
				
			||||||
                          >
 | 
					                                  : "!cursor-grab"
 | 
				
			||||||
                            <span
 | 
					                              ]}
 | 
				
			||||||
                              title={item}
 | 
					                              onMouseenter={(event: {
 | 
				
			||||||
                              class="inline-block w-[120px] truncate hover:text-text_color_primary"
 | 
					                                preventDefault: () => void;
 | 
				
			||||||
 | 
					                              }) => rowDrop(event)}
 | 
				
			||||||
 | 
					                            />
 | 
				
			||||||
 | 
					                            <el-checkbox
 | 
				
			||||||
 | 
					                              key={item}
 | 
				
			||||||
 | 
					                              label={item}
 | 
				
			||||||
 | 
					                              onChange={value =>
 | 
				
			||||||
 | 
					                                handleCheckColumnListChange(value, item)
 | 
				
			||||||
 | 
					                              }
 | 
				
			||||||
                            >
 | 
					                            >
 | 
				
			||||||
                              {item}
 | 
					                              <span
 | 
				
			||||||
                            </span>
 | 
					                                title={item}
 | 
				
			||||||
                          </el-checkbox>
 | 
					                                class="inline-block w-[120px] truncate hover:text-text_color_primary"
 | 
				
			||||||
 | 
					                              >
 | 
				
			||||||
 | 
					                                {item}
 | 
				
			||||||
 | 
					                              </span>
 | 
				
			||||||
 | 
					                            </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