Pārlūkot izejas kodu

fix: layout代码缺失

ystl_myq 7 mēneši atpakaļ
vecāks
revīzija
5854f12c24
3 mainītis faili ar 222 papildinājumiem un 0 dzēšanām
  1. 1 0
      package.json
  2. 16 0
      pnpm-lock.yaml
  3. 205 0
      src/layout/components/appMain.vue

+ 1 - 0
package.json

@@ -75,6 +75,7 @@
     "responsive-storage": "^2.2.0",
     "sortablejs": "^1.15.2",
     "vue": "^3.4.21",
+    "vue-draggable-plus": "^0.5.4",
     "vue-router": "^4.3.0",
     "vue-tippy": "^6.4.1",
     "vue-types": "^5.1.1",

+ 16 - 0
pnpm-lock.yaml

@@ -83,6 +83,9 @@ importers:
       vue:
         specifier: ^3.4.21
         version: 3.4.21(typescript@5.4.3)
+      vue-draggable-plus:
+        specifier: ^0.5.4
+        version: 0.5.4(@types/sortablejs@1.15.8)
       vue-router:
         specifier: ^4.3.0
         version: 4.3.0(vue@3.4.21(typescript@5.4.3))
@@ -3722,6 +3725,15 @@ packages:
       '@vue/composition-api':
         optional: true
 
+  vue-draggable-plus@0.5.4:
+    resolution: {integrity: sha512-7YXbRu6HFL5c0ELP07nNZPGyXmvD8o7Ny7Dj53l9u0sBTjVmHkgr3+/aXgUO1w2bIwE8f6GhaVmLxd7nhqQ0wg==}
+    peerDependencies:
+      '@types/sortablejs': ^1.15.0
+      '@vue/composition-api': '*'
+    peerDependenciesMeta:
+      '@vue/composition-api':
+        optional: true
+
   vue-eslint-parser@9.4.2:
     resolution: {integrity: sha512-Ry9oiGmCAK91HrKMtCrKFWmSFWvYkpGglCeFAIqDdr9zdXmMMpJOmUJS7WWsW7fX81h6mwHmUZCQQ1E0PkSwYQ==}
     engines: {node: ^14.17.0 || >=16.0.0}
@@ -7473,6 +7485,10 @@ snapshots:
     dependencies:
       vue: 3.4.21(typescript@5.4.3)
 
+  vue-draggable-plus@0.5.4(@types/sortablejs@1.15.8):
+    dependencies:
+      '@types/sortablejs': 1.15.8
+
   vue-eslint-parser@9.4.2(eslint@8.57.0):
     dependencies:
       debug: 4.3.4

+ 205 - 0
src/layout/components/appMain.vue

@@ -0,0 +1,205 @@
+<script setup lang="ts">
+import Footer from "./footer/index.vue";
+import { useGlobal, isNumber } from "@pureadmin/utils";
+import KeepAliveFrame from "./keepAliveFrame/index.vue";
+import backTop from "@/assets/svg/back_top.svg?component";
+import { h, computed, Transition, defineComponent } from "vue";
+import { usePermissionStoreHook } from "@/store/modules/permission";
+
+const props = defineProps({
+  fixedHeader: Boolean
+});
+
+const { $storage, $config } = useGlobal<GlobalPropertiesApi>();
+
+const isKeepAlive = computed(() => {
+  return $config?.KeepAlive;
+});
+
+const transitions = computed(() => {
+  return route => {
+    return route.meta.transition;
+  };
+});
+
+const hideTabs = computed(() => {
+  return $storage?.configure.hideTabs;
+});
+
+const hideFooter = computed(() => {
+  return $storage?.configure.hideFooter;
+});
+
+const stretch = computed(() => {
+  return $storage?.configure.stretch;
+});
+
+const layout = computed(() => {
+  return $storage?.layout.layout === "vertical";
+});
+
+const getMainWidth = computed(() => {
+  return isNumber(stretch.value)
+    ? stretch.value + "px"
+    : stretch.value
+      ? "1440px"
+      : "100%";
+});
+
+const getSectionStyle = computed(() => {
+  return [
+    hideTabs.value && layout ? "padding-top: 48px;" : "",
+    !hideTabs.value && layout ? "padding-top: 81px;" : "",
+    hideTabs.value && !layout.value ? "padding-top: 48px;" : "",
+    !hideTabs.value && !layout.value ? "padding-top: 81px;" : "",
+    props.fixedHeader
+      ? ""
+      : `padding-top: 0;${
+          hideTabs.value
+            ? "min-height: calc(100vh - 48px);"
+            : "min-height: calc(100vh - 86px);"
+        }`
+  ];
+});
+
+const transitionMain = defineComponent({
+  props: {
+    route: {
+      type: undefined,
+      required: true
+    }
+  },
+  render() {
+    const transitionName =
+      transitions.value(this.route)?.name || "fade-transform";
+    const enterTransition = transitions.value(this.route)?.enterTransition;
+    const leaveTransition = transitions.value(this.route)?.leaveTransition;
+    return h(
+      Transition,
+      {
+        name: enterTransition ? "pure-classes-transition" : transitionName,
+        enterActiveClass: enterTransition
+          ? `animate__animated ${enterTransition}`
+          : undefined,
+        leaveActiveClass: leaveTransition
+          ? `animate__animated ${leaveTransition}`
+          : undefined,
+        mode: "out-in",
+        appear: true
+      },
+      {
+        default: () => [this.$slots.default()]
+      }
+    );
+  }
+});
+</script>
+
+<template>
+  <section
+    :class="[props.fixedHeader ? 'app-main' : 'app-main-nofixed-header']"
+    :style="getSectionStyle"
+  >
+    <router-view>
+      <template #default="{ Component, route }">
+        <KeepAliveFrame :currComp="Component" :currRoute="route">
+          <template #default="{ Comp, fullPath, frameInfo }">
+            <el-scrollbar
+              v-if="props.fixedHeader"
+              :wrap-style="{
+                display: 'flex',
+                'flex-wrap': 'wrap',
+                'max-width': getMainWidth,
+                margin: '0 auto',
+                transition: 'all 300ms cubic-bezier(0.4, 0, 0.2, 1)'
+              }"
+              :view-style="{
+                display: 'flex',
+                flex: 'auto',
+                overflow: 'hidden',
+                'flex-direction': 'column'
+              }"
+            >
+              <el-backtop
+                title="回到顶部"
+                target=".app-main .el-scrollbar__wrap"
+              >
+                <backTop />
+              </el-backtop>
+              <div class="grow">
+                <transitionMain :route="route">
+                  <keep-alive
+                    v-if="isKeepAlive"
+                    :include="usePermissionStoreHook().cachePageList"
+                  >
+                    <component
+                      :is="Comp"
+                      :key="fullPath"
+                      :frameInfo="frameInfo"
+                      class="main-content"
+                    />
+                  </keep-alive>
+                  <component
+                    :is="Comp"
+                    v-else
+                    :key="fullPath"
+                    :frameInfo="frameInfo"
+                    class="main-content"
+                  />
+                </transitionMain>
+              </div>
+              <Footer v-if="!hideFooter" />
+            </el-scrollbar>
+            <div v-else class="grow">
+              <transitionMain :route="route">
+                <keep-alive
+                  v-if="isKeepAlive"
+                  :include="usePermissionStoreHook().cachePageList"
+                >
+                  <component
+                    :is="Comp"
+                    :key="fullPath"
+                    :frameInfo="frameInfo"
+                    class="main-content"
+                  />
+                </keep-alive>
+                <component
+                  :is="Comp"
+                  v-else
+                  :key="fullPath"
+                  :frameInfo="frameInfo"
+                  class="main-content"
+                />
+              </transitionMain>
+            </div>
+          </template>
+        </KeepAliveFrame>
+      </template>
+    </router-view>
+
+    <!-- 页脚 -->
+    <Footer v-if="!hideFooter && !props.fixedHeader" />
+  </section>
+</template>
+
+<style scoped>
+.app-main {
+  position: relative;
+  width: 100%;
+  height: 100vh;
+  overflow-x: hidden;
+
+  /* border: 1px solid blue; */
+}
+
+.app-main-nofixed-header {
+  position: relative;
+  display: flex;
+  flex-direction: column;
+  width: 100%;
+}
+
+.main-content {
+  margin: 24px;
+}
+</style>