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
						227a7b7a2a
					
				@ -12,6 +12,7 @@
 | 
				
			|||||||
  "Grey": false,
 | 
					  "Grey": false,
 | 
				
			||||||
  "Weak": false,
 | 
					  "Weak": false,
 | 
				
			||||||
  "HideTabs": false,
 | 
					  "HideTabs": false,
 | 
				
			||||||
 | 
					  "HideFooter": false,
 | 
				
			||||||
  "SidebarStatus": true,
 | 
					  "SidebarStatus": true,
 | 
				
			||||||
  "EpThemeColor": "#409EFF",
 | 
					  "EpThemeColor": "#409EFF",
 | 
				
			||||||
  "ShowLogo": true,
 | 
					  "ShowLogo": true,
 | 
				
			||||||
 | 
				
			|||||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							@ -1,12 +1,15 @@
 | 
				
			|||||||
import iconifyIconOffline from "./src/iconifyIconOffline";
 | 
					import iconifyIconOffline from "./src/iconifyIconOffline";
 | 
				
			||||||
import iconifyIconOnline from "./src/iconifyIconOnline";
 | 
					import iconifyIconOnline from "./src/iconifyIconOnline";
 | 
				
			||||||
 | 
					import iconSelect from "./src/Select.vue";
 | 
				
			||||||
import fontIcon from "./src/iconfont";
 | 
					import fontIcon from "./src/iconfont";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/** 本地图标组件 */
 | 
					/** 本地图标组件 */
 | 
				
			||||||
const IconifyIconOffline = iconifyIconOffline;
 | 
					const IconifyIconOffline = iconifyIconOffline;
 | 
				
			||||||
/** 在线图标组件 */
 | 
					/** 在线图标组件 */
 | 
				
			||||||
const IconifyIconOnline = iconifyIconOnline;
 | 
					const IconifyIconOnline = iconifyIconOnline;
 | 
				
			||||||
/** iconfont组件 */
 | 
					/** `IconSelect`图标选择器组件 */
 | 
				
			||||||
 | 
					const IconSelect = iconSelect;
 | 
				
			||||||
 | 
					/** `iconfont`组件 */
 | 
				
			||||||
const FontIcon = fontIcon;
 | 
					const FontIcon = fontIcon;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export { IconifyIconOffline, IconifyIconOnline, FontIcon };
 | 
					export { IconifyIconOffline, IconifyIconOnline, IconSelect, FontIcon };
 | 
				
			||||||
 | 
				
			|||||||
@ -1,7 +1,9 @@
 | 
				
			|||||||
<script setup lang="ts">
 | 
					<script setup lang="ts">
 | 
				
			||||||
import { cloneDeep } from "@pureadmin/utils";
 | 
					 | 
				
			||||||
import { IconJson } from "@/components/ReIcon/data";
 | 
					import { IconJson } from "@/components/ReIcon/data";
 | 
				
			||||||
 | 
					import { cloneDeep, isAllEmpty } from "@pureadmin/utils";
 | 
				
			||||||
import { ref, computed, CSSProperties, toRef, watch } from "vue";
 | 
					import { ref, computed, CSSProperties, toRef, watch } from "vue";
 | 
				
			||||||
 | 
					import Search from "@iconify-icons/ri/search-eye-line";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type ParameterCSSProperties = (item?: string) => CSSProperties | undefined;
 | 
					type ParameterCSSProperties = (item?: string) => CSSProperties | undefined;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
defineOptions({
 | 
					defineOptions({
 | 
				
			||||||
@ -16,15 +18,15 @@ const props = defineProps({
 | 
				
			|||||||
});
 | 
					});
 | 
				
			||||||
const emit = defineEmits<{ (e: "update:modelValue", v: string) }>();
 | 
					const emit = defineEmits<{ (e: "update:modelValue", v: string) }>();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const visible = ref(false);
 | 
					 | 
				
			||||||
const inputValue = toRef(props, "modelValue");
 | 
					const inputValue = toRef(props, "modelValue");
 | 
				
			||||||
const iconList = ref(IconJson);
 | 
					const iconList = ref(IconJson);
 | 
				
			||||||
const icon = ref("add-location");
 | 
					const icon = ref();
 | 
				
			||||||
const currentActiveType = ref("ep:");
 | 
					const currentActiveType = ref("ep:");
 | 
				
			||||||
// 深拷贝图标数据,前端做搜索
 | 
					// 深拷贝图标数据,前端做搜索
 | 
				
			||||||
const copyIconList = cloneDeep(iconList.value);
 | 
					const copyIconList = cloneDeep(iconList.value);
 | 
				
			||||||
 | 
					const totalPage = ref(0);
 | 
				
			||||||
const pageSize = ref(96);
 | 
					// 每页显示35个图标
 | 
				
			||||||
 | 
					const pageSize = ref(35);
 | 
				
			||||||
const currentPage = ref(1);
 | 
					const currentPage = ref(1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// 搜索条件
 | 
					// 搜索条件
 | 
				
			||||||
@ -36,8 +38,8 @@ const tabsList = [
 | 
				
			|||||||
    name: "ep:"
 | 
					    name: "ep:"
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
  {
 | 
					  {
 | 
				
			||||||
    label: "Font Awesome 4",
 | 
					    label: "Remix Icon",
 | 
				
			||||||
    name: "fa:"
 | 
					    name: "ri:"
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
  {
 | 
					  {
 | 
				
			||||||
    label: "Font Awesome 5 Solid",
 | 
					    label: "Font Awesome 5 Solid",
 | 
				
			||||||
@ -45,20 +47,14 @@ const tabsList = [
 | 
				
			|||||||
  }
 | 
					  }
 | 
				
			||||||
];
 | 
					];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const pageList = computed(() => {
 | 
					const pageList = computed(() =>
 | 
				
			||||||
  if (currentPage.value === 1) {
 | 
					  copyIconList[currentActiveType.value]
 | 
				
			||||||
    return copyIconList[currentActiveType.value]
 | 
					    .filter(i => i.includes(filterValue.value))
 | 
				
			||||||
      .filter(v => v.includes(filterValue.value))
 | 
					    .slice(
 | 
				
			||||||
      .slice(currentPage.value - 1, pageSize.value);
 | 
					      (currentPage.value - 1) * pageSize.value,
 | 
				
			||||||
  } else {
 | 
					      currentPage.value * pageSize.value
 | 
				
			||||||
    return copyIconList[currentActiveType.value]
 | 
					    )
 | 
				
			||||||
      .filter(v => v.includes(filterValue.value))
 | 
					);
 | 
				
			||||||
      .slice(
 | 
					 | 
				
			||||||
        pageSize.value * (currentPage.value - 1),
 | 
					 | 
				
			||||||
        pageSize.value * (currentPage.value - 1) + pageSize.value
 | 
					 | 
				
			||||||
      );
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
});
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
const iconItemStyle = computed((): ParameterCSSProperties => {
 | 
					const iconItemStyle = computed((): ParameterCSSProperties => {
 | 
				
			||||||
  return item => {
 | 
					  return item => {
 | 
				
			||||||
@ -71,50 +67,63 @@ const iconItemStyle = computed((): ParameterCSSProperties => {
 | 
				
			|||||||
  };
 | 
					  };
 | 
				
			||||||
});
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function setVal() {
 | 
				
			||||||
 | 
					  currentActiveType.value = props.modelValue.substring(
 | 
				
			||||||
 | 
					    0,
 | 
				
			||||||
 | 
					    props.modelValue.indexOf(":") + 1
 | 
				
			||||||
 | 
					  );
 | 
				
			||||||
 | 
					  icon.value = props.modelValue.substring(props.modelValue.indexOf(":") + 1);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function onBeforeEnter() {
 | 
				
			||||||
 | 
					  if (isAllEmpty(icon.value)) return;
 | 
				
			||||||
 | 
					  setVal();
 | 
				
			||||||
 | 
					  // 寻找当前图标在第几页
 | 
				
			||||||
 | 
					  const curIconIndex = copyIconList[currentActiveType.value].findIndex(
 | 
				
			||||||
 | 
					    i => i === icon.value
 | 
				
			||||||
 | 
					  );
 | 
				
			||||||
 | 
					  currentPage.value = Math.ceil((curIconIndex + 1) / pageSize.value);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function onAfterLeave() {
 | 
				
			||||||
 | 
					  filterValue.value = "";
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function handleClick({ props }) {
 | 
					function handleClick({ props }) {
 | 
				
			||||||
  currentPage.value = 1;
 | 
					  currentPage.value = 1;
 | 
				
			||||||
  currentActiveType.value = props.name;
 | 
					  currentActiveType.value = props.name;
 | 
				
			||||||
  emit(
 | 
					 | 
				
			||||||
    "update:modelValue",
 | 
					 | 
				
			||||||
    currentActiveType.value + iconList.value[currentActiveType.value][0]
 | 
					 | 
				
			||||||
  );
 | 
					 | 
				
			||||||
  icon.value = iconList.value[currentActiveType.value][0];
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function onChangeIcon(item) {
 | 
					function onChangeIcon(item) {
 | 
				
			||||||
  icon.value = item;
 | 
					  icon.value = item;
 | 
				
			||||||
  emit("update:modelValue", currentActiveType.value + item);
 | 
					  emit("update:modelValue", currentActiveType.value + item);
 | 
				
			||||||
  visible.value = false;
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function onCurrentChange(page) {
 | 
					function onCurrentChange(page) {
 | 
				
			||||||
  currentPage.value = page;
 | 
					  currentPage.value = page;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function onClear() {
 | 
				
			||||||
 | 
					  icon.value = "";
 | 
				
			||||||
 | 
					  emit("update:modelValue", "");
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
watch(
 | 
					watch(
 | 
				
			||||||
  () => {
 | 
					  () => pageList.value,
 | 
				
			||||||
    return props.modelValue;
 | 
					  () =>
 | 
				
			||||||
  },
 | 
					    (totalPage.value = copyIconList[currentActiveType.value].filter(i =>
 | 
				
			||||||
  () => {
 | 
					      i.includes(filterValue.value)
 | 
				
			||||||
    if (props.modelValue) {
 | 
					    ).length),
 | 
				
			||||||
      currentActiveType.value = props.modelValue.substring(
 | 
					 | 
				
			||||||
        0,
 | 
					 | 
				
			||||||
        props.modelValue.indexOf(":") + 1
 | 
					 | 
				
			||||||
      );
 | 
					 | 
				
			||||||
      icon.value = props.modelValue.substring(
 | 
					 | 
				
			||||||
        props.modelValue.indexOf(":") + 1
 | 
					 | 
				
			||||||
      );
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
  },
 | 
					 | 
				
			||||||
  { immediate: true }
 | 
					  { immediate: true }
 | 
				
			||||||
);
 | 
					);
 | 
				
			||||||
watch(
 | 
					watch(
 | 
				
			||||||
  () => {
 | 
					  () => props.modelValue,
 | 
				
			||||||
    return filterValue.value;
 | 
					  val => val && setVal(),
 | 
				
			||||||
  },
 | 
					  { immediate: true }
 | 
				
			||||||
  () => {
 | 
					);
 | 
				
			||||||
    currentPage.value = 1;
 | 
					watch(
 | 
				
			||||||
  }
 | 
					  () => filterValue.value,
 | 
				
			||||||
 | 
					  () => (currentPage.value = 1)
 | 
				
			||||||
);
 | 
					);
 | 
				
			||||||
</script>
 | 
					</script>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -129,14 +138,15 @@ watch(
 | 
				
			|||||||
          :popper-options="{
 | 
					          :popper-options="{
 | 
				
			||||||
            placement: 'auto'
 | 
					            placement: 'auto'
 | 
				
			||||||
          }"
 | 
					          }"
 | 
				
			||||||
          :visible="visible"
 | 
					          @before-enter="onBeforeEnter"
 | 
				
			||||||
 | 
					          @after-leave="onAfterLeave"
 | 
				
			||||||
        >
 | 
					        >
 | 
				
			||||||
          <template #reference>
 | 
					          <template #reference>
 | 
				
			||||||
            <div
 | 
					            <div
 | 
				
			||||||
              class="w-[40px] h-[32px] cursor-pointer flex justify-center items-center"
 | 
					              class="w-[40px] h-[32px] cursor-pointer flex justify-center items-center"
 | 
				
			||||||
              @click="visible = !visible"
 | 
					 | 
				
			||||||
            >
 | 
					            >
 | 
				
			||||||
              <IconifyIconOnline :icon="currentActiveType + icon" />
 | 
					              <IconifyIconOffline v-if="!icon" :icon="Search" />
 | 
				
			||||||
 | 
					              <IconifyIconOnline v-else :icon="inputValue" />
 | 
				
			||||||
            </div>
 | 
					            </div>
 | 
				
			||||||
          </template>
 | 
					          </template>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -160,7 +170,7 @@ watch(
 | 
				
			|||||||
                    v-for="(item, key) in pageList"
 | 
					                    v-for="(item, key) in pageList"
 | 
				
			||||||
                    :key="key"
 | 
					                    :key="key"
 | 
				
			||||||
                    :title="item"
 | 
					                    :title="item"
 | 
				
			||||||
                    class="icon-item p-2 cursor-pointer mr-2 mt-1 flex justify-center items-center border border-solid"
 | 
					                    class="icon-item p-2 cursor-pointer mr-2 mt-1 flex justify-center items-center border border-[#e5e7eb]"
 | 
				
			||||||
                    :style="iconItemStyle(item)"
 | 
					                    :style="iconItemStyle(item)"
 | 
				
			||||||
                    @click="onChangeIcon(item)"
 | 
					                    @click="onChangeIcon(item)"
 | 
				
			||||||
                  >
 | 
					                  >
 | 
				
			||||||
@ -175,16 +185,31 @@ watch(
 | 
				
			|||||||
            </el-tab-pane>
 | 
					            </el-tab-pane>
 | 
				
			||||||
          </el-tabs>
 | 
					          </el-tabs>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
          <el-pagination
 | 
					          <div
 | 
				
			||||||
            small
 | 
					            class="w-full h-9 flex items-center overflow-auto border-t border-[#e5e7eb]"
 | 
				
			||||||
            :total="copyIconList[currentActiveType].length"
 | 
					          >
 | 
				
			||||||
            :page-size="pageSize"
 | 
					            <el-pagination
 | 
				
			||||||
            :current-page="currentPage"
 | 
					              class="flex-auto ml-2"
 | 
				
			||||||
            background
 | 
					              :total="totalPage"
 | 
				
			||||||
            layout="prev, pager, next"
 | 
					              :current-page="currentPage"
 | 
				
			||||||
            class="flex items-center justify-center h-10"
 | 
					              :page-size="pageSize"
 | 
				
			||||||
            @current-change="onCurrentChange"
 | 
					              :pager-count="5"
 | 
				
			||||||
          />
 | 
					              layout="pager"
 | 
				
			||||||
 | 
					              background
 | 
				
			||||||
 | 
					              small
 | 
				
			||||||
 | 
					              @current-change="onCurrentChange"
 | 
				
			||||||
 | 
					            />
 | 
				
			||||||
 | 
					            <el-button
 | 
				
			||||||
 | 
					              class="justify-end mr-2 ml-2"
 | 
				
			||||||
 | 
					              type="danger"
 | 
				
			||||||
 | 
					              size="small"
 | 
				
			||||||
 | 
					              text
 | 
				
			||||||
 | 
					              bg
 | 
				
			||||||
 | 
					              @click="onClear"
 | 
				
			||||||
 | 
					            >
 | 
				
			||||||
 | 
					              清空
 | 
				
			||||||
 | 
					            </el-button>
 | 
				
			||||||
 | 
					          </div>
 | 
				
			||||||
        </el-popover>
 | 
					        </el-popover>
 | 
				
			||||||
      </template>
 | 
					      </template>
 | 
				
			||||||
    </el-input>
 | 
					    </el-input>
 | 
				
			||||||
@ -231,6 +256,14 @@ watch(
 | 
				
			|||||||
  box-shadow: 0 2px 5px rgb(0 0 0 / 6%);
 | 
					  box-shadow: 0 2px 5px rgb(0 0 0 / 6%);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					:deep(.el-tabs__nav-wrap::after) {
 | 
				
			||||||
 | 
					  height: 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					:deep(.el-tabs__nav-wrap) {
 | 
				
			||||||
 | 
					  padding: 0 24px;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
:deep(.el-tabs__content) {
 | 
					:deep(.el-tabs__content) {
 | 
				
			||||||
  margin-top: 4px;
 | 
					  margin-top: 4px;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -1,7 +1,7 @@
 | 
				
			|||||||
import { h, defineComponent } from "vue";
 | 
					import { h, defineComponent } from "vue";
 | 
				
			||||||
import { Icon as IconifyIcon, addIcon } from "@iconify/vue/dist/offline";
 | 
					import { Icon as IconifyIcon, addIcon } from "@iconify/vue/dist/offline";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Iconify Icon在Vue里本地使用(用于内网环境)https://docs.iconify.design/icon-components/vue/offline.html
 | 
					// Iconify Icon在Vue里本地使用(用于内网环境)
 | 
				
			||||||
export default defineComponent({
 | 
					export default defineComponent({
 | 
				
			||||||
  name: "IconifyIconOffline",
 | 
					  name: "IconifyIconOffline",
 | 
				
			||||||
  components: { IconifyIcon },
 | 
					  components: { IconifyIcon },
 | 
				
			||||||
 | 
				
			|||||||
@ -1,4 +1,5 @@
 | 
				
			|||||||
<script setup lang="ts">
 | 
					<script setup lang="ts">
 | 
				
			||||||
 | 
					import Footer from "./footer/index.vue";
 | 
				
			||||||
import { useGlobal } from "@pureadmin/utils";
 | 
					import { useGlobal } from "@pureadmin/utils";
 | 
				
			||||||
import backTop from "@/assets/svg/back_top.svg?component";
 | 
					import backTop from "@/assets/svg/back_top.svg?component";
 | 
				
			||||||
import { h, computed, Transition, defineComponent } from "vue";
 | 
					import { h, computed, Transition, defineComponent } from "vue";
 | 
				
			||||||
@ -24,6 +25,10 @@ const hideTabs = computed(() => {
 | 
				
			|||||||
  return $storage?.configure.hideTabs;
 | 
					  return $storage?.configure.hideTabs;
 | 
				
			||||||
});
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const hideFooter = computed(() => {
 | 
				
			||||||
 | 
					  return $storage?.configure.hideFooter;
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const layout = computed(() => {
 | 
					const layout = computed(() => {
 | 
				
			||||||
  return $storage?.layout.layout === "vertical";
 | 
					  return $storage?.layout.layout === "vertical";
 | 
				
			||||||
});
 | 
					});
 | 
				
			||||||
@ -32,9 +37,15 @@ const getSectionStyle = computed(() => {
 | 
				
			|||||||
  return [
 | 
					  return [
 | 
				
			||||||
    hideTabs.value && layout ? "padding-top: 48px;" : "",
 | 
					    hideTabs.value && layout ? "padding-top: 48px;" : "",
 | 
				
			||||||
    !hideTabs.value && layout ? "padding-top: 85px;" : "",
 | 
					    !hideTabs.value && layout ? "padding-top: 85px;" : "",
 | 
				
			||||||
    hideTabs.value && !layout.value ? "padding-top: 48px" : "",
 | 
					    hideTabs.value && !layout.value ? "padding-top: 48px;" : "",
 | 
				
			||||||
    !hideTabs.value && !layout.value ? "padding-top: 85px;" : "",
 | 
					    !hideTabs.value && !layout.value ? "padding-top: 85px;" : "",
 | 
				
			||||||
    props.fixedHeader ? "" : "padding-top: 0;"
 | 
					    props.fixedHeader
 | 
				
			||||||
 | 
					      ? ""
 | 
				
			||||||
 | 
					      : `padding-top: 0;${
 | 
				
			||||||
 | 
					          hideTabs.value
 | 
				
			||||||
 | 
					            ? "min-height: calc(100vh - 48px);"
 | 
				
			||||||
 | 
					            : "min-height: calc(100vh - 86px);"
 | 
				
			||||||
 | 
					        }`
 | 
				
			||||||
  ];
 | 
					  ];
 | 
				
			||||||
});
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -78,30 +89,44 @@ const transitionMain = defineComponent({
 | 
				
			|||||||
  >
 | 
					  >
 | 
				
			||||||
    <router-view>
 | 
					    <router-view>
 | 
				
			||||||
      <template #default="{ Component, route }">
 | 
					      <template #default="{ Component, route }">
 | 
				
			||||||
        <el-scrollbar v-if="props.fixedHeader">
 | 
					        <el-scrollbar
 | 
				
			||||||
 | 
					          v-if="props.fixedHeader"
 | 
				
			||||||
 | 
					          :wrap-style="{
 | 
				
			||||||
 | 
					            display: 'flex'
 | 
				
			||||||
 | 
					          }"
 | 
				
			||||||
 | 
					          :view-style="{
 | 
				
			||||||
 | 
					            display: 'flex',
 | 
				
			||||||
 | 
					            flex: 'auto',
 | 
				
			||||||
 | 
					            overflow: 'auto',
 | 
				
			||||||
 | 
					            'flex-direction': 'column'
 | 
				
			||||||
 | 
					          }"
 | 
				
			||||||
 | 
					        >
 | 
				
			||||||
          <el-backtop title="回到顶部" target=".app-main .el-scrollbar__wrap">
 | 
					          <el-backtop title="回到顶部" target=".app-main .el-scrollbar__wrap">
 | 
				
			||||||
            <backTop />
 | 
					            <backTop />
 | 
				
			||||||
          </el-backtop>
 | 
					          </el-backtop>
 | 
				
			||||||
          <transitionMain :route="route">
 | 
					          <div class="grow">
 | 
				
			||||||
            <keep-alive
 | 
					            <transitionMain :route="route">
 | 
				
			||||||
              v-if="isKeepAlive"
 | 
					              <keep-alive
 | 
				
			||||||
              :include="usePermissionStoreHook().cachePageList"
 | 
					                v-if="isKeepAlive"
 | 
				
			||||||
            >
 | 
					                :include="usePermissionStoreHook().cachePageList"
 | 
				
			||||||
 | 
					              >
 | 
				
			||||||
 | 
					                <component
 | 
				
			||||||
 | 
					                  :is="Component"
 | 
				
			||||||
 | 
					                  :key="route.fullPath"
 | 
				
			||||||
 | 
					                  class="main-content"
 | 
				
			||||||
 | 
					                />
 | 
				
			||||||
 | 
					              </keep-alive>
 | 
				
			||||||
              <component
 | 
					              <component
 | 
				
			||||||
 | 
					                v-else
 | 
				
			||||||
                :is="Component"
 | 
					                :is="Component"
 | 
				
			||||||
                :key="route.fullPath"
 | 
					                :key="route.fullPath"
 | 
				
			||||||
                class="main-content"
 | 
					                class="main-content"
 | 
				
			||||||
              />
 | 
					              />
 | 
				
			||||||
            </keep-alive>
 | 
					            </transitionMain>
 | 
				
			||||||
            <component
 | 
					          </div>
 | 
				
			||||||
              v-else
 | 
					          <Footer v-if="!hideFooter" />
 | 
				
			||||||
              :is="Component"
 | 
					 | 
				
			||||||
              :key="route.fullPath"
 | 
					 | 
				
			||||||
              class="main-content"
 | 
					 | 
				
			||||||
            />
 | 
					 | 
				
			||||||
          </transitionMain>
 | 
					 | 
				
			||||||
        </el-scrollbar>
 | 
					        </el-scrollbar>
 | 
				
			||||||
        <div v-else>
 | 
					        <div v-else class="grow">
 | 
				
			||||||
          <transitionMain :route="route">
 | 
					          <transitionMain :route="route">
 | 
				
			||||||
            <keep-alive
 | 
					            <keep-alive
 | 
				
			||||||
              v-if="isKeepAlive"
 | 
					              v-if="isKeepAlive"
 | 
				
			||||||
@ -123,6 +148,9 @@ const transitionMain = defineComponent({
 | 
				
			|||||||
        </div>
 | 
					        </div>
 | 
				
			||||||
      </template>
 | 
					      </template>
 | 
				
			||||||
    </router-view>
 | 
					    </router-view>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    <!-- 页脚 -->
 | 
				
			||||||
 | 
					    <Footer v-if="!hideFooter && !props.fixedHeader" />
 | 
				
			||||||
  </section>
 | 
					  </section>
 | 
				
			||||||
</template>
 | 
					</template>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -136,8 +164,9 @@ const transitionMain = defineComponent({
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
.app-main-nofixed-header {
 | 
					.app-main-nofixed-header {
 | 
				
			||||||
  position: relative;
 | 
					  position: relative;
 | 
				
			||||||
 | 
					  display: flex;
 | 
				
			||||||
 | 
					  flex-direction: column;
 | 
				
			||||||
  width: 100%;
 | 
					  width: 100%;
 | 
				
			||||||
  min-height: 100vh;
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.main-content {
 | 
					.main-content {
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										29
									
								
								src/layout/components/footer/index.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										29
									
								
								src/layout/components/footer/index.vue
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,29 @@
 | 
				
			|||||||
 | 
					<script lang="ts" setup>
 | 
				
			||||||
 | 
					import { getConfig } from "@/config";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const TITLE = getConfig("Title");
 | 
				
			||||||
 | 
					</script>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<template>
 | 
				
			||||||
 | 
					  <footer class="layout-footer">
 | 
				
			||||||
 | 
					    MIT © 2020-PRESENT
 | 
				
			||||||
 | 
					    <a
 | 
				
			||||||
 | 
					      class="ml-1 hover:text-primary"
 | 
				
			||||||
 | 
					      href="https://github.com/pure-admin"
 | 
				
			||||||
 | 
					      target="_blank"
 | 
				
			||||||
 | 
					    >
 | 
				
			||||||
 | 
					      {{ TITLE }}
 | 
				
			||||||
 | 
					    </a>
 | 
				
			||||||
 | 
					  </footer>
 | 
				
			||||||
 | 
					</template>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<style lang="scss" scoped>
 | 
				
			||||||
 | 
					.layout-footer {
 | 
				
			||||||
 | 
					  display: flex;
 | 
				
			||||||
 | 
					  align-items: center;
 | 
				
			||||||
 | 
					  justify-content: center;
 | 
				
			||||||
 | 
					  width: 100%;
 | 
				
			||||||
 | 
					  padding: 0 0 8px;
 | 
				
			||||||
 | 
					  color: #c0c4cc;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					</style>
 | 
				
			||||||
@ -66,6 +66,7 @@ const settings = reactive({
 | 
				
			|||||||
  tabsVal: $storage.configure.hideTabs,
 | 
					  tabsVal: $storage.configure.hideTabs,
 | 
				
			||||||
  showLogo: $storage.configure.showLogo,
 | 
					  showLogo: $storage.configure.showLogo,
 | 
				
			||||||
  showModel: $storage.configure.showModel,
 | 
					  showModel: $storage.configure.showModel,
 | 
				
			||||||
 | 
					  hideFooter: $storage.configure.hideFooter,
 | 
				
			||||||
  multiTagsCache: $storage.configure.multiTagsCache
 | 
					  multiTagsCache: $storage.configure.multiTagsCache
 | 
				
			||||||
});
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -111,12 +112,20 @@ const weekChange = (value): void => {
 | 
				
			|||||||
  storageConfigureChange("weak", value);
 | 
					  storageConfigureChange("weak", value);
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/** 隐藏标签页设置 */
 | 
				
			||||||
const tagsChange = () => {
 | 
					const tagsChange = () => {
 | 
				
			||||||
  const showVal = settings.tabsVal;
 | 
					  const showVal = settings.tabsVal;
 | 
				
			||||||
  storageConfigureChange("hideTabs", showVal);
 | 
					  storageConfigureChange("hideTabs", showVal);
 | 
				
			||||||
  emitter.emit("tagViewsChange", showVal as unknown as string);
 | 
					  emitter.emit("tagViewsChange", showVal as unknown as string);
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/** 隐藏页脚设置 */
 | 
				
			||||||
 | 
					const hideFooterChange = () => {
 | 
				
			||||||
 | 
					  const hideFooter = settings.hideFooter;
 | 
				
			||||||
 | 
					  storageConfigureChange("hideFooter", hideFooter);
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/** 标签页持久化设置 */
 | 
				
			||||||
const multiTagsCacheChange = () => {
 | 
					const multiTagsCacheChange = () => {
 | 
				
			||||||
  const multiTagsCache = settings.multiTagsCache;
 | 
					  const multiTagsCache = settings.multiTagsCache;
 | 
				
			||||||
  storageConfigureChange("multiTagsCache", multiTagsCache);
 | 
					  storageConfigureChange("multiTagsCache", multiTagsCache);
 | 
				
			||||||
@ -218,6 +227,7 @@ onBeforeMount(() => {
 | 
				
			|||||||
    settings.weakVal &&
 | 
					    settings.weakVal &&
 | 
				
			||||||
      document.querySelector("html")?.setAttribute("class", "html-weakness");
 | 
					      document.querySelector("html")?.setAttribute("class", "html-weakness");
 | 
				
			||||||
    settings.tabsVal && tagsChange();
 | 
					    settings.tabsVal && tagsChange();
 | 
				
			||||||
 | 
					    settings.hideFooter && hideFooterChange();
 | 
				
			||||||
  });
 | 
					  });
 | 
				
			||||||
});
 | 
					});
 | 
				
			||||||
</script>
 | 
					</script>
 | 
				
			||||||
@ -344,6 +354,17 @@ onBeforeMount(() => {
 | 
				
			|||||||
          @change="tagsChange"
 | 
					          @change="tagsChange"
 | 
				
			||||||
        />
 | 
					        />
 | 
				
			||||||
      </li>
 | 
					      </li>
 | 
				
			||||||
 | 
					      <li>
 | 
				
			||||||
 | 
					        <span class="dark:text-white">隐藏页脚</span>
 | 
				
			||||||
 | 
					        <el-switch
 | 
				
			||||||
 | 
					          v-model="settings.hideFooter"
 | 
				
			||||||
 | 
					          inline-prompt
 | 
				
			||||||
 | 
					          inactive-color="#a6a6a6"
 | 
				
			||||||
 | 
					          active-text="开"
 | 
				
			||||||
 | 
					          inactive-text="关"
 | 
				
			||||||
 | 
					          @change="hideFooterChange"
 | 
				
			||||||
 | 
					        />
 | 
				
			||||||
 | 
					      </li>
 | 
				
			||||||
      <li>
 | 
					      <li>
 | 
				
			||||||
        <span class="dark:text-white">侧边栏Logo</span>
 | 
					        <span class="dark:text-white">侧边栏Logo</span>
 | 
				
			||||||
        <el-switch
 | 
					        <el-switch
 | 
				
			||||||
 | 
				
			|||||||
@ -36,6 +36,7 @@ export function useLayout() {
 | 
				
			|||||||
        grey: $config?.Grey ?? false,
 | 
					        grey: $config?.Grey ?? false,
 | 
				
			||||||
        weak: $config?.Weak ?? false,
 | 
					        weak: $config?.Weak ?? false,
 | 
				
			||||||
        hideTabs: $config?.HideTabs ?? false,
 | 
					        hideTabs: $config?.HideTabs ?? false,
 | 
				
			||||||
 | 
					        hideFooter: $config.HideFooter ?? false,
 | 
				
			||||||
        showLogo: $config?.ShowLogo ?? true,
 | 
					        showLogo: $config?.ShowLogo ?? true,
 | 
				
			||||||
        showModel: $config?.ShowModel ?? "smart",
 | 
					        showModel: $config?.ShowModel ?? "smart",
 | 
				
			||||||
        multiTagsCache: $config?.MultiTagsCache ?? false
 | 
					        multiTagsCache: $config?.MultiTagsCache ?? false
 | 
				
			||||||
 | 
				
			|||||||
@ -24,6 +24,7 @@ export const injectResponsiveStorage = (app: App, config: PlatformConfigs) => {
 | 
				
			|||||||
        grey: config.Grey ?? false,
 | 
					        grey: config.Grey ?? false,
 | 
				
			||||||
        weak: config.Weak ?? false,
 | 
					        weak: config.Weak ?? false,
 | 
				
			||||||
        hideTabs: config.HideTabs ?? false,
 | 
					        hideTabs: config.HideTabs ?? false,
 | 
				
			||||||
 | 
					        hideFooter: config.HideFooter ?? false,
 | 
				
			||||||
        showLogo: config.ShowLogo ?? true,
 | 
					        showLogo: config.ShowLogo ?? true,
 | 
				
			||||||
        showModel: config.ShowModel ?? "smart",
 | 
					        showModel: config.ShowModel ?? "smart",
 | 
				
			||||||
        multiTagsCache: config.MultiTagsCache ?? false
 | 
					        multiTagsCache: config.MultiTagsCache ?? false
 | 
				
			||||||
 | 
				
			|||||||
@ -1,6 +1,6 @@
 | 
				
			|||||||
<script setup lang="ts">
 | 
					<script setup lang="ts">
 | 
				
			||||||
import { ref } from "vue";
 | 
					import { ref } from "vue";
 | 
				
			||||||
import IconSelect from "@/components/ReIcon/src/Select.vue";
 | 
					import { IconSelect } from "@/components/ReIcon";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
defineOptions({
 | 
					defineOptions({
 | 
				
			||||||
  name: "IconSelect"
 | 
					  name: "IconSelect"
 | 
				
			||||||
 | 
				
			|||||||
@ -22,9 +22,9 @@ onMounted(() => {
 | 
				
			|||||||
    videoAttributes: {
 | 
					    videoAttributes: {
 | 
				
			||||||
      crossOrigin: "anonymous"
 | 
					      crossOrigin: "anonymous"
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    url: "https://sf1-hscdn-tos.pstatp.com/obj/media-fe/xgplayer_doc_video/mp4/xgplayer-demo-720p.mp4",
 | 
					    url: "//lf3-static.bytednsdoc.com/obj/eden-cn/nupenuvpxnuvo/xgplayer_doc/xgplayer-demo.mp4",
 | 
				
			||||||
    poster:
 | 
					    poster:
 | 
				
			||||||
      "https://s2.pstatp.com/cdn/expire-1-M/byted-player-videos/1.0.0/poster.jpg",
 | 
					      "//lf9-cdn-tos.bytecdntp.com/cdn/expire-1-M/byted-player-videos/1.0.0/poster.jpg",
 | 
				
			||||||
    fluid: deviceDetection(),
 | 
					    fluid: deviceDetection(),
 | 
				
			||||||
    //传入倍速可选数组
 | 
					    //传入倍速可选数组
 | 
				
			||||||
    playbackRate: [0.5, 0.75, 1, 1.5, 2]
 | 
					    playbackRate: [0.5, 0.75, 1, 1.5, 2]
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										3
									
								
								types/global.d.ts
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										3
									
								
								types/global.d.ts
									
									
									
									
										vendored
									
									
								
							@ -89,6 +89,7 @@ declare global {
 | 
				
			|||||||
    Grey?: boolean;
 | 
					    Grey?: boolean;
 | 
				
			||||||
    Weak?: boolean;
 | 
					    Weak?: boolean;
 | 
				
			||||||
    HideTabs?: boolean;
 | 
					    HideTabs?: boolean;
 | 
				
			||||||
 | 
					    HideFooter?: boolean;
 | 
				
			||||||
    SidebarStatus?: boolean;
 | 
					    SidebarStatus?: boolean;
 | 
				
			||||||
    EpThemeColor?: string;
 | 
					    EpThemeColor?: string;
 | 
				
			||||||
    ShowLogo?: boolean;
 | 
					    ShowLogo?: boolean;
 | 
				
			||||||
@ -125,6 +126,7 @@ declare global {
 | 
				
			|||||||
    grey?: boolean;
 | 
					    grey?: boolean;
 | 
				
			||||||
    weak?: boolean;
 | 
					    weak?: boolean;
 | 
				
			||||||
    hideTabs?: boolean;
 | 
					    hideTabs?: boolean;
 | 
				
			||||||
 | 
					    hideFooter?: boolean;
 | 
				
			||||||
    sidebarStatus?: boolean;
 | 
					    sidebarStatus?: boolean;
 | 
				
			||||||
    epThemeColor?: string;
 | 
					    epThemeColor?: string;
 | 
				
			||||||
    showLogo?: boolean;
 | 
					    showLogo?: boolean;
 | 
				
			||||||
@ -158,6 +160,7 @@ declare global {
 | 
				
			|||||||
      grey?: boolean;
 | 
					      grey?: boolean;
 | 
				
			||||||
      weak?: boolean;
 | 
					      weak?: boolean;
 | 
				
			||||||
      hideTabs?: boolean;
 | 
					      hideTabs?: boolean;
 | 
				
			||||||
 | 
					      hideFooter?: boolean;
 | 
				
			||||||
      showLogo?: boolean;
 | 
					      showLogo?: boolean;
 | 
				
			||||||
      showModel?: string;
 | 
					      showModel?: string;
 | 
				
			||||||
      multiTagsCache?: boolean;
 | 
					      multiTagsCache?: boolean;
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user