mirror of
				https://github.com/pure-admin/vue-pure-admin.git
				synced 2025-11-03 13:44:47 +08:00 
			
		
		
		
	Merge branch 'main' of github.com:pure-admin/vue-pure-admin into gitee
This commit is contained in:
		
						commit
						2bd7d44119
					
				@ -33,7 +33,6 @@ const include = [
 | 
				
			|||||||
  "@howdyjs/mouse-menu",
 | 
					  "@howdyjs/mouse-menu",
 | 
				
			||||||
  "@logicflow/extension",
 | 
					  "@logicflow/extension",
 | 
				
			||||||
  "vue-virtual-scroller",
 | 
					  "vue-virtual-scroller",
 | 
				
			||||||
  "element-resize-detector",
 | 
					 | 
				
			||||||
  "@amap/amap-jsapi-loader",
 | 
					  "@amap/amap-jsapi-loader",
 | 
				
			||||||
  "el-table-infinite-scroll",
 | 
					  "el-table-infinite-scroll",
 | 
				
			||||||
  "vue-waterfall-plugin-next",
 | 
					  "vue-waterfall-plugin-next",
 | 
				
			||||||
 | 
				
			|||||||
@ -101,7 +101,7 @@ menus:
 | 
				
			|||||||
  hsInfiniteScroll: 表格无限滚动
 | 
					  hsInfiniteScroll: 表格无限滚动
 | 
				
			||||||
  hsdanmaku: 弹幕组件
 | 
					  hsdanmaku: 弹幕组件
 | 
				
			||||||
  hsPureTableBase: 基础用法(23个示例)
 | 
					  hsPureTableBase: 基础用法(23个示例)
 | 
				
			||||||
  hsPureTableHigh: 高级用法(10个示例)
 | 
					  hsPureTableHigh: 高级用法(11个示例)
 | 
				
			||||||
  hsTree: 大数据树业务组件
 | 
					  hsTree: 大数据树业务组件
 | 
				
			||||||
  hsMenuoverflow: 目录超出显示 Tooltip 文字提示
 | 
					  hsMenuoverflow: 目录超出显示 Tooltip 文字提示
 | 
				
			||||||
  hsChildMenuoverflow: 菜单超出显示 Tooltip 文字提示
 | 
					  hsChildMenuoverflow: 菜单超出显示 Tooltip 文字提示
 | 
				
			||||||
 | 
				
			|||||||
@ -33,7 +33,7 @@
 | 
				
			|||||||
    "@logicflow/core": "^1.2.7",
 | 
					    "@logicflow/core": "^1.2.7",
 | 
				
			||||||
    "@logicflow/extension": "^1.2.7",
 | 
					    "@logicflow/extension": "^1.2.7",
 | 
				
			||||||
    "@pureadmin/descriptions": "^1.1.1",
 | 
					    "@pureadmin/descriptions": "^1.1.1",
 | 
				
			||||||
    "@pureadmin/table": "^2.2.0",
 | 
					    "@pureadmin/table": "^2.3.2",
 | 
				
			||||||
    "@pureadmin/utils": "^1.9.2",
 | 
					    "@pureadmin/utils": "^1.9.2",
 | 
				
			||||||
    "@vueuse/core": "^10.1.2",
 | 
					    "@vueuse/core": "^10.1.2",
 | 
				
			||||||
    "@vueuse/motion": "^2.0.0",
 | 
					    "@vueuse/motion": "^2.0.0",
 | 
				
			||||||
@ -47,7 +47,6 @@
 | 
				
			|||||||
    "echarts": "^5.4.2",
 | 
					    "echarts": "^5.4.2",
 | 
				
			||||||
    "el-table-infinite-scroll": "^3.0.1",
 | 
					    "el-table-infinite-scroll": "^3.0.1",
 | 
				
			||||||
    "element-plus": "^2.3.5",
 | 
					    "element-plus": "^2.3.5",
 | 
				
			||||||
    "element-resize-detector": "^1.2.4",
 | 
					 | 
				
			||||||
    "intro.js": "^7.0.1",
 | 
					    "intro.js": "^7.0.1",
 | 
				
			||||||
    "js-cookie": "^3.0.5",
 | 
					    "js-cookie": "^3.0.5",
 | 
				
			||||||
    "jsbarcode": "^3.11.5",
 | 
					    "jsbarcode": "^3.11.5",
 | 
				
			||||||
@ -87,7 +86,6 @@
 | 
				
			|||||||
    "@iconify/vue": "^4.1.1",
 | 
					    "@iconify/vue": "^4.1.1",
 | 
				
			||||||
    "@intlify/unplugin-vue-i18n": "^0.10.0",
 | 
					    "@intlify/unplugin-vue-i18n": "^0.10.0",
 | 
				
			||||||
    "@pureadmin/theme": "^3.0.0",
 | 
					    "@pureadmin/theme": "^3.0.0",
 | 
				
			||||||
    "@types/element-resize-detector": "1.1.3",
 | 
					 | 
				
			||||||
    "@types/intro.js": "^5.1.1",
 | 
					    "@types/intro.js": "^5.1.1",
 | 
				
			||||||
    "@types/js-cookie": "^3.0.3",
 | 
					    "@types/js-cookie": "^3.0.3",
 | 
				
			||||||
    "@types/mockjs": "^1.0.7",
 | 
					    "@types/mockjs": "^1.0.7",
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										8656
									
								
								pnpm-lock.yaml
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										8656
									
								
								pnpm-lock.yaml
									
									
									
										generated
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							@ -1,27 +0,0 @@
 | 
				
			|||||||
import { Directive, type DirectiveBinding, type VNode } from "vue";
 | 
					 | 
				
			||||||
import elementResizeDetectorMaker from "element-resize-detector";
 | 
					 | 
				
			||||||
import type { Erd } from "element-resize-detector";
 | 
					 | 
				
			||||||
import { emitter } from "@/utils/mitt";
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
const erd: Erd = elementResizeDetectorMaker({
 | 
					 | 
				
			||||||
  strategy: "scroll"
 | 
					 | 
				
			||||||
});
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
export const resize: Directive = {
 | 
					 | 
				
			||||||
  mounted(el: HTMLElement, binding?: DirectiveBinding, vnode?: VNode) {
 | 
					 | 
				
			||||||
    erd.listenTo(el, elem => {
 | 
					 | 
				
			||||||
      const width = elem.offsetWidth;
 | 
					 | 
				
			||||||
      const height = elem.offsetHeight;
 | 
					 | 
				
			||||||
      if (binding?.instance) {
 | 
					 | 
				
			||||||
        emitter.emit("resize", { detail: { width, height } });
 | 
					 | 
				
			||||||
      } else {
 | 
					 | 
				
			||||||
        vnode.el.dispatchEvent(
 | 
					 | 
				
			||||||
          new CustomEvent("resize", { detail: { width, height } })
 | 
					 | 
				
			||||||
        );
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
    });
 | 
					 | 
				
			||||||
  },
 | 
					 | 
				
			||||||
  unmounted(el: HTMLElement) {
 | 
					 | 
				
			||||||
    erd.uninstall(el);
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
@ -1,2 +1 @@
 | 
				
			|||||||
export * from "./auth";
 | 
					export * from "./auth";
 | 
				
			||||||
export * from "./elResizeDetector";
 | 
					 | 
				
			||||||
 | 
				
			|||||||
@ -1,7 +1,7 @@
 | 
				
			|||||||
<script setup lang="ts">
 | 
					<script setup lang="ts">
 | 
				
			||||||
import { ref, computed } from "vue";
 | 
					 | 
				
			||||||
import { emitter } from "@/utils/mitt";
 | 
					import { emitter } from "@/utils/mitt";
 | 
				
			||||||
import { onClickOutside } from "@vueuse/core";
 | 
					import { onClickOutside } from "@vueuse/core";
 | 
				
			||||||
 | 
					import { ref, computed, onMounted, onBeforeUnmount } from "vue";
 | 
				
			||||||
import Close from "@iconify-icons/ep/close";
 | 
					import Close from "@iconify-icons/ep/close";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const target = ref(null);
 | 
					const target = ref(null);
 | 
				
			||||||
@ -27,8 +27,15 @@ onClickOutside(target, (event: any) => {
 | 
				
			|||||||
  show.value = false;
 | 
					  show.value = false;
 | 
				
			||||||
});
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
emitter.on("openPanel", () => {
 | 
					onMounted(() => {
 | 
				
			||||||
  show.value = true;
 | 
					  emitter.on("openPanel", () => {
 | 
				
			||||||
 | 
					    show.value = true;
 | 
				
			||||||
 | 
					  });
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					onBeforeUnmount(() => {
 | 
				
			||||||
 | 
					  // 解绑`openPanel`公共事件,防止多次触发
 | 
				
			||||||
 | 
					  emitter.off("openPanel");
 | 
				
			||||||
});
 | 
					});
 | 
				
			||||||
</script>
 | 
					</script>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -7,9 +7,9 @@ import leftCollapse from "./leftCollapse.vue";
 | 
				
			|||||||
import { useNav } from "@/layout/hooks/useNav";
 | 
					import { useNav } from "@/layout/hooks/useNav";
 | 
				
			||||||
import { storageLocal } from "@pureadmin/utils";
 | 
					import { storageLocal } from "@pureadmin/utils";
 | 
				
			||||||
import { responsiveStorageNameSpace } from "@/config";
 | 
					import { responsiveStorageNameSpace } from "@/config";
 | 
				
			||||||
import { ref, computed, watch, onBeforeMount } from "vue";
 | 
					 | 
				
			||||||
import { findRouteByPath, getParentPaths } from "@/router/utils";
 | 
					import { findRouteByPath, getParentPaths } from "@/router/utils";
 | 
				
			||||||
import { usePermissionStoreHook } from "@/store/modules/permission";
 | 
					import { usePermissionStoreHook } from "@/store/modules/permission";
 | 
				
			||||||
 | 
					import { ref, computed, watch, onMounted, onBeforeUnmount } from "vue";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const route = useRoute();
 | 
					const route = useRoute();
 | 
				
			||||||
const showLogo = ref(
 | 
					const showLogo = ref(
 | 
				
			||||||
@ -51,12 +51,6 @@ function getSubMenuData(path: string) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
getSubMenuData(route.path);
 | 
					getSubMenuData(route.path);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
onBeforeMount(() => {
 | 
					 | 
				
			||||||
  emitter.on("logoChange", key => {
 | 
					 | 
				
			||||||
    showLogo.value = key;
 | 
					 | 
				
			||||||
  });
 | 
					 | 
				
			||||||
});
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
watch(
 | 
					watch(
 | 
				
			||||||
  () => [route.path, usePermissionStoreHook().wholeMenus],
 | 
					  () => [route.path, usePermissionStoreHook().wholeMenus],
 | 
				
			||||||
  () => {
 | 
					  () => {
 | 
				
			||||||
@ -65,6 +59,17 @@ watch(
 | 
				
			|||||||
    menuSelect(route.path, routers);
 | 
					    menuSelect(route.path, routers);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
);
 | 
					);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					onMounted(() => {
 | 
				
			||||||
 | 
					  emitter.on("logoChange", key => {
 | 
				
			||||||
 | 
					    showLogo.value = key;
 | 
				
			||||||
 | 
					  });
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					onBeforeUnmount(() => {
 | 
				
			||||||
 | 
					  // 解绑`logoChange`公共事件,防止多次触发
 | 
				
			||||||
 | 
					  emitter.off("logoChange");
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
</script>
 | 
					</script>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
<template>
 | 
					<template>
 | 
				
			||||||
 | 
				
			|||||||
@ -8,7 +8,7 @@ import { isEqual, isAllEmpty } from "@pureadmin/utils";
 | 
				
			|||||||
import { handleAliveRoute, getTopMenu } from "@/router/utils";
 | 
					import { handleAliveRoute, getTopMenu } from "@/router/utils";
 | 
				
			||||||
import { useSettingStoreHook } from "@/store/modules/settings";
 | 
					import { useSettingStoreHook } from "@/store/modules/settings";
 | 
				
			||||||
import { useMultiTagsStoreHook } from "@/store/modules/multiTags";
 | 
					import { useMultiTagsStoreHook } from "@/store/modules/multiTags";
 | 
				
			||||||
import { ref, watch, unref, toRaw, nextTick, onBeforeMount } from "vue";
 | 
					import { ref, watch, unref, toRaw, nextTick, onBeforeUnmount } from "vue";
 | 
				
			||||||
import { useResizeObserver, useDebounceFn, useFullscreen } from "@vueuse/core";
 | 
					import { useResizeObserver, useDebounceFn, useFullscreen } from "@vueuse/core";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import ExitFullscreen from "@iconify-icons/ri/fullscreen-exit-fill";
 | 
					import ExitFullscreen from "@iconify-icons/ri/fullscreen-exit-fill";
 | 
				
			||||||
@ -465,7 +465,17 @@ function tagOnClick(item) {
 | 
				
			|||||||
  // showMenuModel(item?.path, item?.query);
 | 
					  // showMenuModel(item?.path, item?.query);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
onBeforeMount(() => {
 | 
					watch([route], () => {
 | 
				
			||||||
 | 
					  activeIndex.value = -1;
 | 
				
			||||||
 | 
					  dynamicTagView();
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					watch(isFullscreen, () => {
 | 
				
			||||||
 | 
					  tagsViews[6].icon = Fullscreen;
 | 
				
			||||||
 | 
					  tagsViews[6].text = $t("buttons.hswholeFullScreen");
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					onMounted(() => {
 | 
				
			||||||
  if (!instance) return;
 | 
					  if (!instance) return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // 根据当前路由初始化操作标签页的禁用状态
 | 
					  // 根据当前路由初始化操作标签页的禁用状态
 | 
				
			||||||
@ -489,19 +499,7 @@ onBeforeMount(() => {
 | 
				
			|||||||
      showMenuModel(indexPath);
 | 
					      showMenuModel(indexPath);
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
  });
 | 
					  });
 | 
				
			||||||
});
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
watch([route], () => {
 | 
					 | 
				
			||||||
  activeIndex.value = -1;
 | 
					 | 
				
			||||||
  dynamicTagView();
 | 
					 | 
				
			||||||
});
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
watch(isFullscreen, () => {
 | 
					 | 
				
			||||||
  tagsViews[6].icon = Fullscreen;
 | 
					 | 
				
			||||||
  tagsViews[6].text = $t("buttons.hswholeFullScreen");
 | 
					 | 
				
			||||||
});
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
onMounted(() => {
 | 
					 | 
				
			||||||
  useResizeObserver(
 | 
					  useResizeObserver(
 | 
				
			||||||
    scrollbarDom,
 | 
					    scrollbarDom,
 | 
				
			||||||
    useDebounceFn(() => {
 | 
					    useDebounceFn(() => {
 | 
				
			||||||
@ -509,6 +507,13 @@ onMounted(() => {
 | 
				
			|||||||
    }, 200)
 | 
					    }, 200)
 | 
				
			||||||
  );
 | 
					  );
 | 
				
			||||||
});
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					onBeforeUnmount(() => {
 | 
				
			||||||
 | 
					  // 解绑`tagViewsChange`、`tagViewsShowModel`、`changLayoutRoute`公共事件,防止多次触发
 | 
				
			||||||
 | 
					  emitter.off("tagViewsChange");
 | 
				
			||||||
 | 
					  emitter.off("tagViewsShowModel");
 | 
				
			||||||
 | 
					  emitter.off("changLayoutRoute");
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
</script>
 | 
					</script>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
<template>
 | 
					<template>
 | 
				
			||||||
 | 
				
			|||||||
@ -3,14 +3,15 @@ import "animate.css";
 | 
				
			|||||||
// 引入 src/components/ReIcon/src/offlineIcon.ts 文件中所有使用addIcon添加过的本地图标
 | 
					// 引入 src/components/ReIcon/src/offlineIcon.ts 文件中所有使用addIcon添加过的本地图标
 | 
				
			||||||
import "@/components/ReIcon/src/offlineIcon";
 | 
					import "@/components/ReIcon/src/offlineIcon";
 | 
				
			||||||
import { setType } from "./types";
 | 
					import { setType } from "./types";
 | 
				
			||||||
import { emitter } from "@/utils/mitt";
 | 
					 | 
				
			||||||
import { useLayout } from "./hooks/useLayout";
 | 
					import { useLayout } from "./hooks/useLayout";
 | 
				
			||||||
 | 
					import { useResizeObserver } from "@vueuse/core";
 | 
				
			||||||
import { useAppStoreHook } from "@/store/modules/app";
 | 
					import { useAppStoreHook } from "@/store/modules/app";
 | 
				
			||||||
import { useSettingStoreHook } from "@/store/modules/settings";
 | 
					import { useSettingStoreHook } from "@/store/modules/settings";
 | 
				
			||||||
import { deviceDetection, useDark, useGlobal } from "@pureadmin/utils";
 | 
					import { deviceDetection, useDark, useGlobal } from "@pureadmin/utils";
 | 
				
			||||||
import { useDataThemeChange } from "@/layout/hooks/useDataThemeChange";
 | 
					import { useDataThemeChange } from "@/layout/hooks/useDataThemeChange";
 | 
				
			||||||
import {
 | 
					import {
 | 
				
			||||||
  h,
 | 
					  h,
 | 
				
			||||||
 | 
					  ref,
 | 
				
			||||||
  reactive,
 | 
					  reactive,
 | 
				
			||||||
  computed,
 | 
					  computed,
 | 
				
			||||||
  onMounted,
 | 
					  onMounted,
 | 
				
			||||||
@ -26,6 +27,7 @@ import Vertical from "./components/sidebar/vertical.vue";
 | 
				
			|||||||
import Horizontal from "./components/sidebar/horizontal.vue";
 | 
					import Horizontal from "./components/sidebar/horizontal.vue";
 | 
				
			||||||
import backTop from "@/assets/svg/back_top.svg?component";
 | 
					import backTop from "@/assets/svg/back_top.svg?component";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const appWrapperRef = ref();
 | 
				
			||||||
const { isDark } = useDark();
 | 
					const { isDark } = useDark();
 | 
				
			||||||
const { layout } = useLayout();
 | 
					const { layout } = useLayout();
 | 
				
			||||||
const isMobile = deviceDetection();
 | 
					const isMobile = deviceDetection();
 | 
				
			||||||
@ -78,10 +80,10 @@ function toggle(device: string, bool: boolean) {
 | 
				
			|||||||
// 判断是否可自动关闭菜单栏
 | 
					// 判断是否可自动关闭菜单栏
 | 
				
			||||||
let isAutoCloseSidebar = true;
 | 
					let isAutoCloseSidebar = true;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// 监听容器
 | 
					useResizeObserver(appWrapperRef, entries => {
 | 
				
			||||||
emitter.on("resize", ({ detail }) => {
 | 
					 | 
				
			||||||
  if (isMobile) return;
 | 
					  if (isMobile) return;
 | 
				
			||||||
  const { width } = detail;
 | 
					  const entry = entries[0];
 | 
				
			||||||
 | 
					  const { width } = entry.contentRect;
 | 
				
			||||||
  width <= 760 ? setTheme("vertical") : setTheme(useAppStoreHook().layout);
 | 
					  width <= 760 ? setTheme("vertical") : setTheme(useAppStoreHook().layout);
 | 
				
			||||||
  /** width app-wrapper类容器宽度
 | 
					  /** width app-wrapper类容器宽度
 | 
				
			||||||
   * 0 < width <= 760 隐藏侧边栏
 | 
					   * 0 < width <= 760 隐藏侧边栏
 | 
				
			||||||
@ -147,7 +149,7 @@ const layoutHeader = defineComponent({
 | 
				
			|||||||
</script>
 | 
					</script>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
<template>
 | 
					<template>
 | 
				
			||||||
  <div :class="['app-wrapper', set.classes]" v-resize>
 | 
					  <div ref="appWrapperRef" :class="['app-wrapper', set.classes]">
 | 
				
			||||||
    <div
 | 
					    <div
 | 
				
			||||||
      v-show="
 | 
					      v-show="
 | 
				
			||||||
        set.device === 'mobile' &&
 | 
					        set.device === 'mobile' &&
 | 
				
			||||||
 | 
				
			|||||||
@ -15,8 +15,10 @@ const props = withDefaults(defineProps<FormProps>(), {
 | 
				
			|||||||
  formInline: () => ({ user: "", region: "" })
 | 
					  formInline: () => ({ user: "", region: "" })
 | 
				
			||||||
});
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// vue 规定所有的 prop 都遵循着单向绑定原则,不能在子组件中更改 prop 值,该 form.vue 文件为子组件
 | 
					// vue 规定所有的 prop 都遵循着单向绑定原则,直接修改 prop 时,Vue 会抛出警告。此处的写法仅仅是为了消除警告。
 | 
				
			||||||
// 如果需要拿到初始化的 prop 值并使得组件变量可修改,则需要在子组件定义一个新的变量接受这个子组件的 prop
 | 
					// 因为对一个 reactive 对象执行 ref,返回 Ref 对象的 value 值仍为传入的 reactive 对象,
 | 
				
			||||||
 | 
					// 即 newFormInline === props.formInline 为 true,所以此处代码的实际效果,仍是直接修改 props.formInline。
 | 
				
			||||||
 | 
					// 但该写法仅适用于 props.formInline 是一个对象类型的情况,原始类型需抛出事件
 | 
				
			||||||
// 推荐阅读:https://cn.vuejs.org/guide/components/props.html#one-way-data-flow
 | 
					// 推荐阅读:https://cn.vuejs.org/guide/components/props.html#one-way-data-flow
 | 
				
			||||||
const newFormInline = ref(props.formInline);
 | 
					const newFormInline = ref(props.formInline);
 | 
				
			||||||
</script>
 | 
					</script>
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										22
									
								
								src/views/components/dialog/formPrimitive.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										22
									
								
								src/views/components/dialog/formPrimitive.vue
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,22 @@
 | 
				
			|||||||
 | 
					<script setup lang="ts">
 | 
				
			||||||
 | 
					import { useVModel } from "@vueuse/core";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// 声明 props 类型
 | 
				
			||||||
 | 
					export interface FormProps {
 | 
				
			||||||
 | 
					  data: string;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// 声明 props 默认值
 | 
				
			||||||
 | 
					// 推荐阅读:https://cn.vuejs.org/guide/typescript/composition-api.html#typing-component-props
 | 
				
			||||||
 | 
					const props = withDefaults(defineProps<FormProps>(), {
 | 
				
			||||||
 | 
					  data: () => ""
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// 使用 vueuse 的双向绑定工具
 | 
				
			||||||
 | 
					const emit = defineEmits(["update:data"]);
 | 
				
			||||||
 | 
					const data = useVModel(props, "data", emit);
 | 
				
			||||||
 | 
					</script>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<template>
 | 
				
			||||||
 | 
					  <el-input class="!w-[220px]" v-model="data" placeholder="请输入内容" />
 | 
				
			||||||
 | 
					</template>
 | 
				
			||||||
@ -3,6 +3,7 @@ import { useRouter } from "vue-router";
 | 
				
			|||||||
import { h, createVNode, ref } from "vue";
 | 
					import { h, createVNode, ref } from "vue";
 | 
				
			||||||
import { message } from "@/utils/message";
 | 
					import { message } from "@/utils/message";
 | 
				
			||||||
import forms, { type FormProps } from "./form.vue";
 | 
					import forms, { type FormProps } from "./form.vue";
 | 
				
			||||||
 | 
					import formPrimitive from "./formPrimitive.vue";
 | 
				
			||||||
import { cloneDeep, debounce } from "@pureadmin/utils";
 | 
					import { cloneDeep, debounce } from "@pureadmin/utils";
 | 
				
			||||||
import {
 | 
					import {
 | 
				
			||||||
  addDialog,
 | 
					  addDialog,
 | 
				
			||||||
@ -316,7 +317,10 @@ function onFormTwoClick() {
 | 
				
			|||||||
  addDialog({
 | 
					  addDialog({
 | 
				
			||||||
    width: "30%",
 | 
					    width: "30%",
 | 
				
			||||||
    title: "结合Form表单(第二种方式)",
 | 
					    title: "结合Form表单(第二种方式)",
 | 
				
			||||||
    contentRenderer: () => h(forms, { formInline: formInline.value }),
 | 
					    contentRenderer: () =>
 | 
				
			||||||
 | 
					      h(forms, {
 | 
				
			||||||
 | 
					        formInline: formInline.value
 | 
				
			||||||
 | 
					      }),
 | 
				
			||||||
    closeCallBack: () => {
 | 
					    closeCallBack: () => {
 | 
				
			||||||
      message(
 | 
					      message(
 | 
				
			||||||
        `当前表单数据为 姓名:${formInline.value.user} 城市:${formInline.value.region}`
 | 
					        `当前表单数据为 姓名:${formInline.value.user} 城市:${formInline.value.region}`
 | 
				
			||||||
@ -338,7 +342,9 @@ function onFormThreeClick() {
 | 
				
			|||||||
    width: "30%",
 | 
					    width: "30%",
 | 
				
			||||||
    title: "结合Form表单(第三种方式)",
 | 
					    title: "结合Form表单(第三种方式)",
 | 
				
			||||||
    contentRenderer: () =>
 | 
					    contentRenderer: () =>
 | 
				
			||||||
      createVNode(forms, { formInline: formThreeInline.value }),
 | 
					      createVNode(forms, {
 | 
				
			||||||
 | 
					        formInline: formThreeInline.value
 | 
				
			||||||
 | 
					      }),
 | 
				
			||||||
    closeCallBack: () => {
 | 
					    closeCallBack: () => {
 | 
				
			||||||
      message(
 | 
					      message(
 | 
				
			||||||
        `当前表单数据为 姓名:${formThreeInline.value.user} 城市:${formThreeInline.value.region}`
 | 
					        `当前表单数据为 姓名:${formThreeInline.value.user} 城市:${formThreeInline.value.region}`
 | 
				
			||||||
@ -373,6 +379,26 @@ function onFormFourClick() {
 | 
				
			|||||||
  });
 | 
					  });
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// 子组件 prop 为 primitive 类型的 demo
 | 
				
			||||||
 | 
					const formPrimitiveParam = ref("Hello World");
 | 
				
			||||||
 | 
					const resetFormPrimitiveParam = ref(formPrimitiveParam.value);
 | 
				
			||||||
 | 
					function onFormPrimitiveFormClick() {
 | 
				
			||||||
 | 
					  addDialog({
 | 
				
			||||||
 | 
					    width: "30%",
 | 
				
			||||||
 | 
					    title: "子组件 prop 为 primitive 类型 demo",
 | 
				
			||||||
 | 
					    contentRenderer: () =>
 | 
				
			||||||
 | 
					      h(formPrimitive, {
 | 
				
			||||||
 | 
					        data: formPrimitiveParam.value,
 | 
				
			||||||
 | 
					        "onUpdate:data": val => (formPrimitiveParam.value = val)
 | 
				
			||||||
 | 
					      }),
 | 
				
			||||||
 | 
					    closeCallBack: () => {
 | 
				
			||||||
 | 
					      message(`当前表单内容:${formPrimitiveParam.value}`);
 | 
				
			||||||
 | 
					      // 重置表单数据
 | 
				
			||||||
 | 
					      formPrimitiveParam.value = resetFormPrimitiveParam.value;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  });
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function onBeforeCancelClick() {
 | 
					function onBeforeCancelClick() {
 | 
				
			||||||
  addDialog({
 | 
					  addDialog({
 | 
				
			||||||
    title: "点击底部取消按钮的回调",
 | 
					    title: "点击底部取消按钮的回调",
 | 
				
			||||||
@ -474,6 +500,9 @@ function onBeforeSureClick() {
 | 
				
			|||||||
      <el-button @click="onFormFourClick">
 | 
					      <el-button @click="onFormFourClick">
 | 
				
			||||||
        结合Form表单(第四种方式)
 | 
					        结合Form表单(第四种方式)
 | 
				
			||||||
      </el-button>
 | 
					      </el-button>
 | 
				
			||||||
 | 
					      <el-button @click="onFormPrimitiveFormClick">
 | 
				
			||||||
 | 
					        子组件 prop 为 primitive 类型
 | 
				
			||||||
 | 
					      </el-button>
 | 
				
			||||||
    </el-space>
 | 
					    </el-space>
 | 
				
			||||||
    <el-divider />
 | 
					    <el-divider />
 | 
				
			||||||
    <el-space wrap>
 | 
					    <el-space wrap>
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										105
									
								
								src/views/pure-table/high/adaptive/columns.tsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										105
									
								
								src/views/pure-table/high/adaptive/columns.tsx
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,105 @@
 | 
				
			|||||||
 | 
					import type {
 | 
				
			||||||
 | 
					  LoadingConfig,
 | 
				
			||||||
 | 
					  AdaptiveConfig,
 | 
				
			||||||
 | 
					  PaginationProps
 | 
				
			||||||
 | 
					} from "@pureadmin/table";
 | 
				
			||||||
 | 
					import { tableData } from "../data";
 | 
				
			||||||
 | 
					import { ref, onMounted, reactive } from "vue";
 | 
				
			||||||
 | 
					import { clone, delay } from "@pureadmin/utils";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export function useColumns() {
 | 
				
			||||||
 | 
					  const dataList = ref([]);
 | 
				
			||||||
 | 
					  const loading = ref(true);
 | 
				
			||||||
 | 
					  const columns: TableColumnList = [
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					      label: "日期",
 | 
				
			||||||
 | 
					      prop: "date"
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					      label: "姓名",
 | 
				
			||||||
 | 
					      prop: "name"
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					      label: "地址",
 | 
				
			||||||
 | 
					      prop: "address"
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  ];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /** 分页配置 */
 | 
				
			||||||
 | 
					  const pagination = reactive<PaginationProps>({
 | 
				
			||||||
 | 
					    pageSize: 20,
 | 
				
			||||||
 | 
					    currentPage: 1,
 | 
				
			||||||
 | 
					    pageSizes: [20, 40, 60],
 | 
				
			||||||
 | 
					    total: 0,
 | 
				
			||||||
 | 
					    align: "right",
 | 
				
			||||||
 | 
					    background: true,
 | 
				
			||||||
 | 
					    small: false
 | 
				
			||||||
 | 
					  });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /** 加载动画配置 */
 | 
				
			||||||
 | 
					  const loadingConfig = reactive<LoadingConfig>({
 | 
				
			||||||
 | 
					    text: "正在加载第一页...",
 | 
				
			||||||
 | 
					    viewBox: "-10, -10, 50, 50",
 | 
				
			||||||
 | 
					    spinner: `
 | 
				
			||||||
 | 
					        <path class="path" d="
 | 
				
			||||||
 | 
					          M 30 15
 | 
				
			||||||
 | 
					          L 28 17
 | 
				
			||||||
 | 
					          M 25.61 25.61
 | 
				
			||||||
 | 
					          A 15 15, 0, 0, 1, 15 30
 | 
				
			||||||
 | 
					          A 15 15, 0, 1, 1, 27.99 7.5
 | 
				
			||||||
 | 
					          L 15 15
 | 
				
			||||||
 | 
					        " style="stroke-width: 4px; fill: rgba(0, 0, 0, 0)"/>
 | 
				
			||||||
 | 
					      `
 | 
				
			||||||
 | 
					    // svg: "",
 | 
				
			||||||
 | 
					    // background: rgba()
 | 
				
			||||||
 | 
					  });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /** 撑满内容区自适应高度相关配置 */
 | 
				
			||||||
 | 
					  const adaptiveConfig: AdaptiveConfig = {
 | 
				
			||||||
 | 
					    /** 表格距离页面底部的偏移量,默认值为 `96` */
 | 
				
			||||||
 | 
					    offsetBottom: 110
 | 
				
			||||||
 | 
					    /** 是否固定表头,默认值为 `true`(如果不想固定表头,fixHeader设置为false并且表格要设置table-layout="auto") */
 | 
				
			||||||
 | 
					    // fixHeader: true
 | 
				
			||||||
 | 
					    /** 页面 `resize` 时的防抖时间,默认值为 `60` ms */
 | 
				
			||||||
 | 
					    // timeout: 60
 | 
				
			||||||
 | 
					    /** 表头的 `z-index`,默认值为 `100` */
 | 
				
			||||||
 | 
					    // zIndex: 100
 | 
				
			||||||
 | 
					  };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  function onSizeChange(val) {
 | 
				
			||||||
 | 
					    console.log("onSizeChange", val);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  function onCurrentChange(val) {
 | 
				
			||||||
 | 
					    loadingConfig.text = `正在加载第${val}页...`;
 | 
				
			||||||
 | 
					    loading.value = true;
 | 
				
			||||||
 | 
					    delay(600).then(() => {
 | 
				
			||||||
 | 
					      loading.value = false;
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  onMounted(() => {
 | 
				
			||||||
 | 
					    delay(600).then(() => {
 | 
				
			||||||
 | 
					      const newList = [];
 | 
				
			||||||
 | 
					      Array.from({ length: 6 }).forEach(() => {
 | 
				
			||||||
 | 
					        newList.push(clone(tableData, true));
 | 
				
			||||||
 | 
					      });
 | 
				
			||||||
 | 
					      newList.flat(Infinity).forEach((item, index) => {
 | 
				
			||||||
 | 
					        dataList.value.push({ id: index, ...item });
 | 
				
			||||||
 | 
					      });
 | 
				
			||||||
 | 
					      pagination.total = dataList.value.length;
 | 
				
			||||||
 | 
					      loading.value = false;
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					  });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  return {
 | 
				
			||||||
 | 
					    loading,
 | 
				
			||||||
 | 
					    columns,
 | 
				
			||||||
 | 
					    dataList,
 | 
				
			||||||
 | 
					    pagination,
 | 
				
			||||||
 | 
					    loadingConfig,
 | 
				
			||||||
 | 
					    adaptiveConfig,
 | 
				
			||||||
 | 
					    onSizeChange,
 | 
				
			||||||
 | 
					    onCurrentChange
 | 
				
			||||||
 | 
					  };
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										41
									
								
								src/views/pure-table/high/adaptive/index.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										41
									
								
								src/views/pure-table/high/adaptive/index.vue
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,41 @@
 | 
				
			|||||||
 | 
					<script setup lang="ts">
 | 
				
			||||||
 | 
					import { ref } from "vue";
 | 
				
			||||||
 | 
					import { useColumns } from "./columns";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const tableRef = ref();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const {
 | 
				
			||||||
 | 
					  loading,
 | 
				
			||||||
 | 
					  columns,
 | 
				
			||||||
 | 
					  dataList,
 | 
				
			||||||
 | 
					  pagination,
 | 
				
			||||||
 | 
					  loadingConfig,
 | 
				
			||||||
 | 
					  adaptiveConfig,
 | 
				
			||||||
 | 
					  onSizeChange,
 | 
				
			||||||
 | 
					  onCurrentChange
 | 
				
			||||||
 | 
					} = useColumns();
 | 
				
			||||||
 | 
					</script>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<template>
 | 
				
			||||||
 | 
					  <pure-table
 | 
				
			||||||
 | 
					    ref="tableRef"
 | 
				
			||||||
 | 
					    border
 | 
				
			||||||
 | 
					    adaptive
 | 
				
			||||||
 | 
					    :adaptiveConfig="adaptiveConfig"
 | 
				
			||||||
 | 
					    row-key="id"
 | 
				
			||||||
 | 
					    alignWhole="center"
 | 
				
			||||||
 | 
					    showOverflowTooltip
 | 
				
			||||||
 | 
					    :loading="loading"
 | 
				
			||||||
 | 
					    :loading-config="loadingConfig"
 | 
				
			||||||
 | 
					    :data="
 | 
				
			||||||
 | 
					      dataList.slice(
 | 
				
			||||||
 | 
					        (pagination.currentPage - 1) * pagination.pageSize,
 | 
				
			||||||
 | 
					        pagination.currentPage * pagination.pageSize
 | 
				
			||||||
 | 
					      )
 | 
				
			||||||
 | 
					    "
 | 
				
			||||||
 | 
					    :columns="columns"
 | 
				
			||||||
 | 
					    :pagination="pagination"
 | 
				
			||||||
 | 
					    @page-size-change="onSizeChange"
 | 
				
			||||||
 | 
					    @page-current-change="onCurrentChange"
 | 
				
			||||||
 | 
					  />
 | 
				
			||||||
 | 
					</template>
 | 
				
			||||||
@ -1,3 +1,4 @@
 | 
				
			|||||||
 | 
					import Adaptive from "./adaptive/index.vue";
 | 
				
			||||||
import Page from "./page/index.vue";
 | 
					import Page from "./page/index.vue";
 | 
				
			||||||
import RowDrag from "./drag/row/index.vue";
 | 
					import RowDrag from "./drag/row/index.vue";
 | 
				
			||||||
import ColumnDrag from "./drag/column/index.vue";
 | 
					import ColumnDrag from "./drag/column/index.vue";
 | 
				
			||||||
@ -13,6 +14,12 @@ const rendContent = (val: string) =>
 | 
				
			|||||||
  `代码位置:src/views/pure-table/high/${val}/index.vue`;
 | 
					  `代码位置:src/views/pure-table/high/${val}/index.vue`;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export const list = [
 | 
					export const list = [
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    key: "adaptive",
 | 
				
			||||||
 | 
					    content: rendContent("adaptive"),
 | 
				
			||||||
 | 
					    title: "自适应内容区高度",
 | 
				
			||||||
 | 
					    component: Adaptive
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
  {
 | 
					  {
 | 
				
			||||||
    key: "page",
 | 
					    key: "page",
 | 
				
			||||||
    content: rendContent("page"),
 | 
					    content: rendContent("page"),
 | 
				
			||||||
 | 
				
			|||||||
@ -90,6 +90,8 @@ const {
 | 
				
			|||||||
        <pure-table
 | 
					        <pure-table
 | 
				
			||||||
          ref="tableRef"
 | 
					          ref="tableRef"
 | 
				
			||||||
          border
 | 
					          border
 | 
				
			||||||
 | 
					          adaptive
 | 
				
			||||||
 | 
					          :adaptiveConfig="{ offsetBottom: 32 }"
 | 
				
			||||||
          align-whole="center"
 | 
					          align-whole="center"
 | 
				
			||||||
          row-key="id"
 | 
					          row-key="id"
 | 
				
			||||||
          showOverflowTooltip
 | 
					          showOverflowTooltip
 | 
				
			||||||
 | 
				
			|||||||
@ -109,6 +109,7 @@ const {
 | 
				
			|||||||
          table-layout="auto"
 | 
					          table-layout="auto"
 | 
				
			||||||
          :loading="loading"
 | 
					          :loading="loading"
 | 
				
			||||||
          :size="size"
 | 
					          :size="size"
 | 
				
			||||||
 | 
					          adaptive
 | 
				
			||||||
          :data="dataList"
 | 
					          :data="dataList"
 | 
				
			||||||
          :columns="dynamicColumns"
 | 
					          :columns="dynamicColumns"
 | 
				
			||||||
          :pagination="pagination"
 | 
					          :pagination="pagination"
 | 
				
			||||||
 | 
				
			|||||||
@ -39,7 +39,7 @@ const {
 | 
				
			|||||||
<template>
 | 
					<template>
 | 
				
			||||||
  <div class="main">
 | 
					  <div class="main">
 | 
				
			||||||
    <tree class="w-[17%] float-left" />
 | 
					    <tree class="w-[17%] float-left" />
 | 
				
			||||||
    <div class="float-right w-[81%]">
 | 
					    <div class="float-right w-[82%]">
 | 
				
			||||||
      <el-form
 | 
					      <el-form
 | 
				
			||||||
        ref="formRef"
 | 
					        ref="formRef"
 | 
				
			||||||
        :inline="true"
 | 
					        :inline="true"
 | 
				
			||||||
@ -97,6 +97,7 @@ const {
 | 
				
			|||||||
        <template v-slot="{ size, dynamicColumns }">
 | 
					        <template v-slot="{ size, dynamicColumns }">
 | 
				
			||||||
          <pure-table
 | 
					          <pure-table
 | 
				
			||||||
            border
 | 
					            border
 | 
				
			||||||
 | 
					            adaptive
 | 
				
			||||||
            align-whole="center"
 | 
					            align-whole="center"
 | 
				
			||||||
            table-layout="auto"
 | 
					            table-layout="auto"
 | 
				
			||||||
            :loading="loading"
 | 
					            :loading="loading"
 | 
				
			||||||
 | 
				
			|||||||
@ -87,7 +87,10 @@ onMounted(async () => {
 | 
				
			|||||||
</script>
 | 
					</script>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
<template>
 | 
					<template>
 | 
				
			||||||
  <div class="h-full min-h-[780px] bg-bg_color overflow-auto">
 | 
					  <div
 | 
				
			||||||
 | 
					    class="h-full bg-bg_color overflow-auto"
 | 
				
			||||||
 | 
					    :style="{ minHeight: `calc(100vh - 133px)` }"
 | 
				
			||||||
 | 
					  >
 | 
				
			||||||
    <div class="flex items-center h-[34px]">
 | 
					    <div class="flex items-center h-[34px]">
 | 
				
			||||||
      <p class="flex-1 ml-2 font-bold text-base truncate" title="部门列表">
 | 
					      <p class="flex-1 ml-2 font-bold text-base truncate" title="部门列表">
 | 
				
			||||||
        部门列表
 | 
					        部门列表
 | 
				
			||||||
 | 
				
			|||||||
@ -145,7 +145,9 @@ getReleases().then(({ data }) => {
 | 
				
			|||||||
          </template>
 | 
					          </template>
 | 
				
			||||||
          <el-skeleton animated :rows="7" :loading="loading">
 | 
					          <el-skeleton animated :rows="7" :loading="loading">
 | 
				
			||||||
            <template #default>
 | 
					            <template #default>
 | 
				
			||||||
              <Github />
 | 
					              <el-scrollbar :height="`calc(${height}px - 35vh - 340px)`">
 | 
				
			||||||
 | 
					                <Github />
 | 
				
			||||||
 | 
					              </el-scrollbar>
 | 
				
			||||||
            </template>
 | 
					            </template>
 | 
				
			||||||
          </el-skeleton>
 | 
					          </el-skeleton>
 | 
				
			||||||
        </el-card>
 | 
					        </el-card>
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user