mirror of
https://github.com/pure-admin/vue-pure-admin.git
synced 2025-06-09 01:47:20 +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(() => {
|
||||||
|
emitter.on("openPanel", () => {
|
||||||
show.value = true;
|
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>
|
||||||
|
<el-scrollbar :height="`calc(${height}px - 35vh - 340px)`">
|
||||||
<Github />
|
<Github />
|
||||||
|
</el-scrollbar>
|
||||||
</template>
|
</template>
|
||||||
</el-skeleton>
|
</el-skeleton>
|
||||||
</el-card>
|
</el-card>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user