Merge branch 'main' of github.com:pure-admin/vue-pure-admin into gitee

This commit is contained in:
xiaoxian521 2023-05-24 12:58:59 +08:00
commit 6294a3ffac
28 changed files with 3032 additions and 6149 deletions

View File

@ -1,6 +1,6 @@
# 预发布也需要生产环境的行为 # 预发布也需要生产环境的行为
# https://cn.vitejs.dev/guide/env-and-mode.html#modes # https://cn.vitejs.dev/guide/env-and-mode.html#modes
NODE_ENV=production # NODE_ENV = development
VITE_PUBLIC_PATH = / VITE_PUBLIC_PATH = /

View File

@ -1,19 +1,19 @@
{ {
"Vue3.0快速生成模板": { "Vue3.0快速生成模板": {
"scope": "vue",
"prefix": "Vue3.0", "prefix": "Vue3.0",
"body": [ "body": [
"<template>", "<template>",
"\t<div>\n", "\t<div>test</div>",
"\t</div>",
"</template>\n", "</template>\n",
"<script lang='ts'>", "<script lang='ts'>",
"export default {", "export default {",
"\tsetup() {", "\tsetup() {",
"\t\treturn{\n\n\t\t}", "\t\treturn {}",
"\t},", "\t}",
"}", "}",
"</script>\n", "</script>\n",
"<style scoped>\n", "<style lang='scss' scoped>\n",
"</style>", "</style>",
"$2" "$2"
], ],

View File

@ -1,14 +1,14 @@
{ {
"Vue3.2+快速生成模板": { "Vue3.2+快速生成模板": {
"scope": "vue",
"prefix": "Vue3.2+", "prefix": "Vue3.2+",
"body": [ "body": [
"<script setup lang='ts'>", "<script setup lang='ts'>",
"</script>\n", "</script>\n",
"<template>", "<template>",
"\t<div>\n", "\t<div>test</div>",
"\t</div>",
"</template>\n", "</template>\n",
"<style scoped>\n", "<style lang='scss' scoped>\n",
"</style>", "</style>",
"$2" "$2"
], ],

20
.vscode/vue3.3.code-snippets vendored Normal file
View File

@ -0,0 +1,20 @@
{
"Vue3.3+defineOptions快速生成模板": {
"scope": "vue",
"prefix": "Vue3.3+",
"body": [
"<script setup lang='ts'>",
"defineOptions({",
"\tname: ''",
"})",
"</script>\n",
"<template>",
"\t<div>test</div>",
"</template>\n",
"<style lang='scss' scoped>\n",
"</style>",
"$2"
],
"description": "Vue3.3+defineOptions快速生成模板"
}
}

View File

@ -22,7 +22,7 @@ The simplified version is based on the shelf extracted from [vue-pure-admin](htt
- [Click Watch Tutorial](https://www.bilibili.com/video/BV1kg411v7QT) - [Click Watch Tutorial](https://www.bilibili.com/video/BV1kg411v7QT)
- [Click Watch UI Design](https://www.bilibili.com/video/BV17g411T7rq) - [Click Watch UI Design](https://www.bilibili.com/video/BV17g411T7rq)
## Docs (support `PWA` fast, offline access) ## Docs
- [Click me to view the domestic documentation site](https://yiming_chang.gitee.io/pure-admin-doc) - [Click me to view the domestic documentation site](https://yiming_chang.gitee.io/pure-admin-doc)
- [Click me to view foreign document site](https://pure-admin.github.io/pure-admin-doc) - [Click me to view foreign document site](https://pure-admin.github.io/pure-admin-doc)
@ -140,34 +140,12 @@ Support modern browsers, not IE
[xiaoxian521](https://github.com/xiaoxian521)、[Ten-K](https://github.com/Ten-K) [xiaoxian521](https://github.com/xiaoxian521)、[Ten-K](https://github.com/Ten-K)
## Donate
If you think this project is helpful to you, you can help the author buy a glass of juice 🍹 Show your support
<img src="https://p9-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/f69bf13c5b854ed5b699807cafa0e3ce~tplv-k3u1fbpfcp-zoom-in-crop-mark:1304:0:0:0.awebp?" width="150px" height="150px" />
## License ## License
In principle, no fees and copyrights are charged, and you can use it with confidence, but if you need secondary open source, please contact the author for permission! In principle, no fees and copyrights are charged, and it is commercially available, but if you need secondary open source (such as using this platform for secondary development and open source, the front-end code must be open source and free), please contact the author for permission! (Free, just take a record)
[MIT © 2020-present, pure-admin](./LICENSE) [MIT © 2020-present, pure-admin](./LICENSE)
## Backers
Thank you very much for your support, I believe the project will get better and better :heart:
| xueyuheng | taolei1990 | hang-kim | madwolfcrazy | limuen | BenLakes |
| :--------------------------------------------------------------------------------------------------------------------------------------: | :---------------------------------------------------------------------------------------------------------------------------------------: | :-------------------------------------------------------------------------------------------------------------------------------------: | :---------------------------------------------------------------------------------------------------------------------------------------: | :-----------------------------------------------------------------------------------------------------------------------------------: | :-------------------------------------------------------------------------------------------------------------------------------------: |
| <a href="https://github.com/xueyuheng"><img src="https://avatars.githubusercontent.com/u/48202935?v=4" width="60px" height="60px" /></a> | <a href="https://github.com/taolei1990"><img src="https://avatars.githubusercontent.com/u/23173640?v=4" width="60px" height="60px" /></a> | <a href="https://github.com/hang-kim"><img src="https://avatars.githubusercontent.com/u/52914259?v=4" width="60px" height="60px" /></a> | <a href="https://github.com/madwolfcrazy"><img src="https://avatars.githubusercontent.com/u/223671?v=4" width="60px" height="60px" /></a> | <a href="https://github.com/limuen"><img src="https://avatars.githubusercontent.com/u/31790606?v=4" width="60px" height="60px" /></a> | <a href="https://github.com/BenLakes"><img src="https://avatars.githubusercontent.com/u/15206046?v=4" width="60px" height="60px" /></a> |
| mollerzhu | TLovers | cnyyk | | | |
| <a href="https://github.com/mollerzhu"><img src="https://avatars.githubusercontent.com/u/49627902?v=4" width="60px" height="60px" /></a> | <a href="https://github.com/TLovers"><img src="https://avatars.githubusercontent.com/u/26561694?v=4" width="60px" height="60px" /></a> | <a href="https://github.com/cnyyk"><img src="https://avatars.githubusercontent.com/u/275233?v=4" width="60px" height="60px" /></a> | | | |
## Contributors
Thanks to all the people who contribute :heart:
<a href="https://github.com/pure-admin/vue-pure-admin/graphs/contributors"><img src="https://contrib.rocks/image?repo=pure-admin/vue-pure-admin" /></a>
## `Star` ## `Star`
Many thanks to the kind individuals who leave a star. Your support is much appreciated :heart: Many thanks to the kind individuals who leave a star. Your support is much appreciated :heart:

View File

@ -22,7 +22,7 @@
- [点我查看快速开发教程](https://www.bilibili.com/video/BV1kg411v7QT) - [点我查看快速开发教程](https://www.bilibili.com/video/BV1kg411v7QT)
- [点我查看 UI 设计](https://www.bilibili.com/video/BV17g411T7rq) - [点我查看 UI 设计](https://www.bilibili.com/video/BV17g411T7rq)
## 配套保姆级文档(支持 `PWA` 快速、离线访问) ## 配套保姆级文档
- [点我查看国内文档站](https://yiming_chang.gitee.io/pure-admin-doc) - [点我查看国内文档站](https://yiming_chang.gitee.io/pure-admin-doc)
- [点我查看国外文档站](https://pure-admin.github.io/pure-admin-doc) - [点我查看国外文档站](https://pure-admin.github.io/pure-admin-doc)
@ -140,38 +140,12 @@ pnpm build
[xiaoxian521](https://github.com/xiaoxian521)、[Ten-K](https://github.com/Ten-K) [xiaoxian521](https://github.com/xiaoxian521)、[Ten-K](https://github.com/Ten-K)
## 支持
如果您觉得这个项目对您有帮助,可以帮作者买一杯果汁 🍹 表示支持
<img src="https://p9-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/f69bf13c5b854ed5b699807cafa0e3ce~tplv-k3u1fbpfcp-zoom-in-crop-mark:1304:0:0:0.awebp?" width="150px" height="150px" />
## `QQ` 交流群
[点击去加入](https://yiming_chang.gitee.io/pure-admin-doc/pages/support/#qq-%E4%BA%A4%E6%B5%81%E7%BE%A4)
## 许可证 ## 许可证
原则上不收取任何费用及版权,可以放心使用,不过如需二次开源(比如用此平台二次开发并开源)请联系作者获取许可! 原则上不收取任何费用及版权,可商用,不过如需二次开源(比如用此平台二次开发并开源,要求前端代码必须开源免费)请联系作者获取许可!(免费,走个记录而已)
[MIT © 2020-present, pure-admin](./LICENSE) [MIT © 2020-present, pure-admin](./LICENSE)
## 支持者
非常感谢您们的支持,相信项目会越来越好 :heart:
| xueyuheng | taolei1990 | hang-kim | madwolfcrazy | limuen | BenLakes |
| :--------------------------------------------------------------------------------------------------------------------------------------: | :---------------------------------------------------------------------------------------------------------------------------------------: | :-------------------------------------------------------------------------------------------------------------------------------------: | :---------------------------------------------------------------------------------------------------------------------------------------: | :-----------------------------------------------------------------------------------------------------------------------------------: | :-------------------------------------------------------------------------------------------------------------------------------------: |
| <a href="https://github.com/xueyuheng"><img src="https://avatars.githubusercontent.com/u/48202935?v=4" width="60px" height="60px" /></a> | <a href="https://github.com/taolei1990"><img src="https://avatars.githubusercontent.com/u/23173640?v=4" width="60px" height="60px" /></a> | <a href="https://github.com/hang-kim"><img src="https://avatars.githubusercontent.com/u/52914259?v=4" width="60px" height="60px" /></a> | <a href="https://github.com/madwolfcrazy"><img src="https://avatars.githubusercontent.com/u/223671?v=4" width="60px" height="60px" /></a> | <a href="https://github.com/limuen"><img src="https://avatars.githubusercontent.com/u/31790606?v=4" width="60px" height="60px" /></a> | <a href="https://github.com/BenLakes"><img src="https://avatars.githubusercontent.com/u/15206046?v=4" width="60px" height="60px" /></a> |
| mollerzhu | TLovers | cnyyk | | | |
| <a href="https://github.com/mollerzhu"><img src="https://avatars.githubusercontent.com/u/49627902?v=4" width="60px" height="60px" /></a> | <a href="https://github.com/TLovers"><img src="https://avatars.githubusercontent.com/u/26561694?v=4" width="60px" height="60px" /></a> | <a href="https://github.com/cnyyk"><img src="https://avatars.githubusercontent.com/u/275233?v=4" width="60px" height="60px" /></a> | | | |
## 贡献者
感谢所有做出贡献的人 :heart:
<a href="https://github.com/pure-admin/vue-pure-admin/graphs/contributors"><img src="https://contrib.rocks/image?repo=pure-admin/vue-pure-admin" /></a>
## `Star` ## `Star`
非常感谢留下星星的好心人,感谢您的支持 :heart: 非常感谢留下星星的好心人,感谢您的支持 :heart:

View File

@ -56,7 +56,7 @@
"mockjs": "^1.1.0", "mockjs": "^1.1.0",
"nprogress": "^0.2.0", "nprogress": "^0.2.0",
"path": "^0.12.7", "path": "^0.12.7",
"pinia": "^2.1.1", "pinia": "^2.1.3",
"qrcode": "^1.5.3", "qrcode": "^1.5.3",
"qs": "^6.11.1", "qs": "^6.11.1",
"responsive-storage": "^2.2.0", "responsive-storage": "^2.2.0",
@ -69,7 +69,7 @@
"vue-i18n": "^9.2.2", "vue-i18n": "^9.2.2",
"vue-json-pretty": "^2.2.4", "vue-json-pretty": "^2.2.4",
"vue-pdf-embed": "^1.1.6", "vue-pdf-embed": "^1.1.6",
"vue-router": "^4.2.0", "vue-router": "^4.2.1",
"vue-types": "^5.0.3", "vue-types": "^5.0.3",
"vue-virtual-scroller": "2.0.0-beta.7", "vue-virtual-scroller": "2.0.0-beta.7",
"vue-waterfall-plugin-next": "^2.2.1", "vue-waterfall-plugin-next": "^2.2.1",
@ -104,9 +104,9 @@
"autoprefixer": "^10.4.14", "autoprefixer": "^10.4.14",
"cloc": "^2.11.0", "cloc": "^2.11.0",
"cssnano": "^6.0.1", "cssnano": "^6.0.1",
"eslint": "^8.40.0", "eslint": "^8.41.0",
"eslint-plugin-prettier": "^4.2.1", "eslint-plugin-prettier": "^4.2.1",
"eslint-plugin-vue": "^9.13.0", "eslint-plugin-vue": "^9.14.0",
"husky": "^8.0.3", "husky": "^8.0.3",
"lint-staged": "^13.2.2", "lint-staged": "^13.2.2",
"picocolors": "^1.0.0", "picocolors": "^1.0.0",
@ -114,12 +114,12 @@
"postcss-html": "^1.5.0", "postcss-html": "^1.5.0",
"postcss-import": "^15.1.0", "postcss-import": "^15.1.0",
"postcss-scss": "^4.0.6", "postcss-scss": "^4.0.6",
"prettier": "^2.8.7", "prettier": "^2.8.8",
"pretty-quick": "3.1.1", "pretty-quick": "^3.1.3",
"rimraf": "^5.0.0", "rimraf": "^5.0.1",
"rollup-plugin-visualizer": "^5.9.0", "rollup-plugin-visualizer": "^5.9.0",
"sass": "^1.62.1", "sass": "^1.62.1",
"sass-loader": "^13.2.2", "sass-loader": "^13.3.0",
"stylelint": "^15.6.2", "stylelint": "^15.6.2",
"stylelint-config-html": "^1.1.0", "stylelint-config-html": "^1.1.0",
"stylelint-config-recess-order": "^4.0.0", "stylelint-config-recess-order": "^4.0.0",
@ -133,9 +133,9 @@
"stylelint-scss": "^5.0.0", "stylelint-scss": "^5.0.0",
"svgo": "^3.0.2", "svgo": "^3.0.2",
"tailwindcss": "^3.3.2", "tailwindcss": "^3.3.2",
"terser": "^5.17.4", "terser": "^5.17.5",
"typescript": "^5.0.4", "typescript": "^5.0.4",
"vite": "^4.3.7", "vite": "^4.3.8",
"vite-plugin-cdn-import": "^0.3.5", "vite-plugin-cdn-import": "^0.3.5",
"vite-plugin-compression": "^0.5.1", "vite-plugin-compression": "^0.5.1",
"vite-plugin-mock": "^2.9.6", "vite-plugin-mock": "^2.9.6",

8278
pnpm-lock.yaml generated

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 8.5 KiB

After

Width:  |  Height:  |  Size: 8.5 KiB

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 10 KiB

After

Width:  |  Height:  |  Size: 10 KiB

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 11 KiB

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 13 KiB

After

Width:  |  Height:  |  Size: 13 KiB

View File

@ -12,6 +12,7 @@ import type {
const dialogStore = ref<Array<DialogOptions>>([]); const dialogStore = ref<Array<DialogOptions>>([]);
/** 打开弹框 */
const addDialog = (options: DialogOptions) => { const addDialog = (options: DialogOptions) => {
const open = () => const open = () =>
dialogStore.value.push(Object.assign(options, { visible: true })); dialogStore.value.push(Object.assign(options, { visible: true }));
@ -24,16 +25,40 @@ const addDialog = (options: DialogOptions) => {
} }
}; };
/** 关闭弹框 */
const closeDialog = (options: DialogOptions, index: number, args?: any) => { const closeDialog = (options: DialogOptions, index: number, args?: any) => {
dialogStore.value.splice(index, 1); dialogStore.value.splice(index, 1);
options.closeCallBack && options.closeCallBack({ options, index, args }); options.closeCallBack && options.closeCallBack({ options, index, args });
}; };
/**
* @description
* @param value
* @param key `title`
* @param index `0``index`
*/
const updateDialog = (value: any, key = "title", index = 0) => {
dialogStore.value[index][key] = value;
};
/** 关闭所有弹框 */
const closeAllDialog = () => { const closeAllDialog = () => {
dialogStore.value = []; dialogStore.value = [];
}; };
/** 使`addDialog`
* https://github.com/pure-admin/vue-pure-admin/blob/main/src/App.vue#L4
* https://github.com/pure-admin/vue-pure-admin/blob/main/src/App.vue#L13
* https://github.com/pure-admin/vue-pure-admin/blob/main/src/App.vue#L18
*/
const ReDialog = withInstall(reDialog); const ReDialog = withInstall(reDialog);
export type { EventType, ArgsType, DialogProps, ButtonProps, DialogOptions }; export type { EventType, ArgsType, DialogProps, ButtonProps, DialogOptions };
export { ReDialog, dialogStore, addDialog, closeDialog, closeAllDialog }; export {
ReDialog,
dialogStore,
addDialog,
closeDialog,
updateDialog,
closeAllDialog
};

View File

@ -200,9 +200,13 @@ export default defineComponent({
return () => ( return () => (
<> <>
<div {...attrs} class="w-[99/100] mt-4 px-2 pb-2 bg-bg_color"> <div {...attrs} class="w-[99/100] mt-2 px-2 pb-2 bg-bg_color">
<div class="flex justify-between w-full h-[60px] p-4"> <div class="flex justify-between w-full h-[60px] p-4">
{slots?.title ? (
slots.title()
) : (
<p class="font-bold truncate">{props.title}</p> <p class="font-bold truncate">{props.title}</p>
)}
<div class="flex items-center justify-around"> <div class="flex items-center justify-around">
{slots?.buttons ? ( {slots?.buttons ? (
<div class="flex mr-4">{slots.buttons()}</div> <div class="flex mr-4">{slots.buttons()}</div>

View File

@ -51,20 +51,21 @@ let startPosX = null;
let isHover = false; let isHover = false;
let ease = "ease-in"; let ease = "ease-in";
// eslint-disable-next-line vue/no-setup-props-destructure if (props.classOption["key"] === undefined) {
const { classOption } = props; // eslint-disable-next-line vue/no-mutating-props
props.classOption["key"] = 0;
if (classOption["key"] === undefined) {
classOption["key"] = 0;
} }
const wrap = templateRef<HTMLElement | null>(`wrap${classOption["key"]}`, null); const wrap = templateRef<HTMLElement | null>(
`wrap${props.classOption["key"]}`,
null
);
const slotList = templateRef<HTMLElement | null>( const slotList = templateRef<HTMLElement | null>(
`slotList${classOption["key"]}`, `slotList${props.classOption["key"]}`,
null null
); );
const realBox = templateRef<HTMLElement | null>( const realBox = templateRef<HTMLElement | null>(
`realBox${classOption["key"]}`, `realBox${props.classOption["key"]}`,
null null
); );
@ -107,7 +108,7 @@ const defaultOption = computed(() => {
const options = computed(() => { const options = computed(() => {
// @ts-expect-error // @ts-expect-error
return copyObj({}, unref(defaultOption), classOption); return copyObj({}, unref(defaultOption), props.classOption);
}); });
const leftSwitchClass = computed(() => { const leftSwitchClass = computed(() => {
@ -495,7 +496,7 @@ defineExpose({
</script> </script>
<template> <template>
<div :ref="'wrap' + classOption['key']"> <div :ref="'wrap' + props.classOption['key']">
<div <div
:style="leftSwitch" :style="leftSwitch"
v-if="navigation" v-if="navigation"
@ -513,7 +514,7 @@ defineExpose({
<slot name="right-switch" /> <slot name="right-switch" />
</div> </div>
<div <div
:ref="'realBox' + classOption['key']" :ref="'realBox' + props.classOption['key']"
:style="pos" :style="pos"
@mouseenter="enter" @mouseenter="enter"
@mouseleave="leave" @mouseleave="leave"
@ -522,7 +523,7 @@ defineExpose({
@touchend="touchEnd" @touchend="touchEnd"
@mousewheel.passive="wheel" @mousewheel.passive="wheel"
> >
<div :ref="'slotList' + classOption['key']" :style="float"> <div :ref="'slotList' + props.classOption['key']" :style="float">
<slot /> <slot />
</div> </div>
<div v-html="copyHtml" :style="float" /> <div v-html="copyHtml" :style="float" />

View File

@ -164,7 +164,7 @@ onKeyStroke("ArrowDown", handleDown);
</template> </template>
</el-input> </el-input>
<div class="search-result-container"> <div class="search-result-container">
<el-scrollbar ref="scrollbarRef" max-height="600px"> <el-scrollbar ref="scrollbarRef" max-height="calc(90vh - 140px)">
<el-empty <el-empty
v-if="resultOptions.length === 0" v-if="resultOptions.length === 0"
description="暂无搜索结果" description="暂无搜索结果"

View File

@ -1,8 +1,9 @@
<script setup lang="ts"> <script setup lang="ts">
import { useI18n } from "vue-i18n"; import { useI18n } from "vue-i18n";
import { computed, getCurrentInstance } from "vue"; import { useResizeObserver } from "@vueuse/core";
import { useEpThemeStoreHook } from "@/store/modules/epTheme"; import { useEpThemeStoreHook } from "@/store/modules/epTheme";
import { useRenderIcon } from "@/components/ReIcon/src/hooks"; import { useRenderIcon } from "@/components/ReIcon/src/hooks";
import { ref, computed, getCurrentInstance, onMounted } from "vue";
import enterOutlined from "@/assets/svg/enter_outlined.svg?component"; import enterOutlined from "@/assets/svg/enter_outlined.svg?component";
import Bookmark2Line from "@iconify-icons/ri/bookmark-2-line"; import Bookmark2Line from "@iconify-icons/ri/bookmark-2-line";
@ -26,6 +27,8 @@ interface Emits {
(e: "enter"): void; (e: "enter"): void;
} }
const resultRef = ref();
const innerHeight = ref();
const props = withDefaults(defineProps<Props>(), {}); const props = withDefaults(defineProps<Props>(), {});
const emit = defineEmits<Emits>(); const emit = defineEmits<Emits>();
const instance = getCurrentInstance()!; const instance = getCurrentInstance()!;
@ -59,19 +62,32 @@ function handleTo() {
emit("enter"); emit("enter");
} }
function resizeResult() {
// el-scrollbar max-height="calc(90vh - 140px)"
innerHeight.value = window.innerHeight - window.innerHeight / 10 - 140;
}
useResizeObserver(resultRef, () => {
resizeResult();
});
function handleScroll(index: number) { function handleScroll(index: number) {
const curInstance = instance?.proxy?.$refs[`resultItemRef${index}`]; const curInstance = instance?.proxy?.$refs[`resultItemRef${index}`];
if (!curInstance) return 0; if (!curInstance) return 0;
const curRef = curInstance[0] as ElRef; const curRef = curInstance[0] as ElRef;
const scrollTop = curRef.offsetTop + 128; // 128 result-item56px+56px=112pxmargin8px+8px=16px const scrollTop = curRef.offsetTop + 128; // 128 result-item56px+56px=112pxmargin8px+8px=16px
return scrollTop > 600 ? scrollTop - 600 : 0; // 600 el-scrollbar max-height="600px" return scrollTop > innerHeight.value ? scrollTop - innerHeight.value : 0;
} }
onMounted(() => {
resizeResult();
});
defineExpose({ handleScroll }); defineExpose({ handleScroll });
</script> </script>
<template> <template>
<div class="result"> <div ref="resultRef" class="result">
<div <div
v-for="(item, index) in options" v-for="(item, index) in options"
:key="item.path" :key="item.path"

View File

@ -218,7 +218,6 @@ watch($storage, ({ layout }) => {
}); });
onBeforeMount(() => { onBeforeMount(() => {
dataThemeChange();
/* 初始化项目配置 */ /* 初始化项目配置 */
nextTick(() => { nextTick(() => {
settings.greyVal && settings.greyVal &&

View File

@ -8,7 +8,15 @@ import { useLayout } from "./hooks/useLayout";
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 { h, reactive, computed, onMounted, defineComponent } from "vue"; import { useDataThemeChange } from "@/layout/hooks/useDataThemeChange";
import {
h,
reactive,
computed,
onMounted,
onBeforeMount,
defineComponent
} from "vue";
import navbar from "./components/navbar.vue"; import navbar from "./components/navbar.vue";
import tag from "./components/tag/index.vue"; import tag from "./components/tag/index.vue";
@ -102,6 +110,10 @@ onMounted(() => {
} }
}); });
onBeforeMount(() => {
useDataThemeChange().dataThemeChange();
});
const layoutHeader = defineComponent({ const layoutHeader = defineComponent({
render() { render() {
return h( return h(

View File

@ -23,7 +23,7 @@ import {
formatFlatteningRoutes formatFlatteningRoutes
} from "./utils"; } from "./utils";
import { buildHierarchyTree } from "@/utils/tree"; import { buildHierarchyTree } from "@/utils/tree";
import { isUrl, openLink, storageSession } from "@pureadmin/utils"; import { isUrl, openLink, storageSession, isAllEmpty } from "@pureadmin/utils";
import remainingRouter from "./modules/remaining"; import remainingRouter from "./modules/remaining";
@ -158,11 +158,22 @@ router.beforeEach((to: toRouteType, _from, next) => {
getTopMenu(true); getTopMenu(true);
// query、params模式路由传参数的标签页不在此处处理 // query、params模式路由传参数的标签页不在此处处理
if (route && route.meta?.title) { if (route && route.meta?.title) {
if (isAllEmpty(route.parentId) && route.meta?.backstage) {
// 此处为动态顶级路由(目录)
const { path, name, meta } = route.children[0];
useMultiTagsStoreHook().handleTags("push", { useMultiTagsStoreHook().handleTags("push", {
path: route.path, path,
name: route.name, name,
meta: route.meta meta
}); });
} else {
const { path, name, meta } = route;
useMultiTagsStoreHook().handleTags("push", {
path,
name,
meta
});
}
} }
} }
router.push(to.fullPath); router.push(to.fullPath);

View File

@ -3,7 +3,7 @@ import { components } from "@/router/enums";
export default { export default {
path: "/components", path: "/components",
redirect: "/components/video", redirect: "/components/dialog",
meta: { meta: {
icon: "menu", icon: "menu",
title: $t("menus.hscomponents"), title: $t("menus.hscomponents"),

View File

@ -54,14 +54,14 @@ export function useColumns() {
} }
}, },
{ {
label: "QQ交流群", label: "精简版",
cellRenderer: () => { cellRenderer: () => {
return ( return (
<a <a
href="https://yiming_chang.gitee.io/pure-admin-doc/pages/support/#qq-%E4%BA%A4%E6%B5%81%E7%BE%A4" href="https://github.com/pure-admin/pure-admin-thin"
target="_blank" target="_blank"
> >
<span style="color: var(--el-color-primary)"></span> <span style="color: var(--el-color-primary)"></span>
</a> </a>
); );
} }

View File

@ -2,9 +2,14 @@
import { useRouter } from "vue-router"; 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 { cloneDeep } from "@pureadmin/utils";
import forms, { type FormProps } from "./form.vue"; import forms, { type FormProps } from "./form.vue";
import { addDialog, closeDialog, closeAllDialog } from "@/components/ReDialog"; import { cloneDeep, debounce } from "@pureadmin/utils";
import {
addDialog,
closeDialog,
updateDialog,
closeAllDialog
} from "@/components/ReDialog";
defineOptions({ defineOptions({
name: "DialogPage" name: "DialogPage"
@ -60,13 +65,16 @@ function onStyleClick() {
}); });
} }
function onoOpenDelayClick() { // 600ms
const onoOpenDelayClick = debounce(
() =>
addDialog({ addDialog({
title: "延时2秒打开弹框", title: "延时2秒打开弹框",
openDelay: 2000, openDelay: 2000 - 600,
contentRenderer: () => <p>弹框内容-延时2秒打开弹框</p> contentRenderer: () => <p>弹框内容-延时2秒打开弹框</p>
}); }),
} 600
);
function onCloseDelayClick() { function onCloseDelayClick() {
addDialog({ addDialog({
@ -240,6 +248,35 @@ function onNestingClick() {
}); });
} }
// contentRenderer
function onUpdateClick() {
const curPage = ref(1);
addDialog({
title: `${curPage.value}`,
contentRenderer: () => (
<>
<el-button
disabled={curPage.value > 1 ? false : true}
onClick={() => {
curPage.value -= 1;
updateDialog(`${curPage.value}`);
}}
>
上一页
</el-button>
<el-button
onClick={() => {
curPage.value += 1;
updateDialog(`${curPage.value}`);
}}
>
下一页
</el-button>
</>
)
});
}
// Form props prop // Form props prop
function onFormOneClick() { function onFormOneClick() {
addDialog({ addDialog({
@ -421,6 +458,7 @@ function onBeforeSureClick() {
<el-button @click="onOpenClick"> 打开后的回调 </el-button> <el-button @click="onOpenClick"> 打开后的回调 </el-button>
<el-button @click="onCloseCallBackClick"> 关闭后的回调 </el-button> <el-button @click="onCloseCallBackClick"> 关闭后的回调 </el-button>
<el-button @click="onNestingClick"> 嵌套的弹框 </el-button> <el-button @click="onNestingClick"> 嵌套的弹框 </el-button>
<el-button @click="onUpdateClick"> 更改弹框自身属性值 </el-button>
</el-space> </el-space>
<el-divider /> <el-divider />
<el-space wrap> <el-space wrap>

View File

@ -0,0 +1,56 @@
<script setup lang="ts">
import "@wangeditor/editor/dist/css/style.css";
import { Editor, Toolbar } from "@wangeditor/editor-for-vue";
import { onBeforeUnmount, ref, shallowRef, onMounted } from "vue";
defineOptions({
name: "BaseEditor"
});
const mode = "default";
// shallowRef
const editorRef = shallowRef();
// HTML
const valueHtml = ref("<p>你好</p>");
// ajax
onMounted(() => {
setTimeout(() => {
valueHtml.value = "<p>我是模拟的异步数据</p>";
}, 1500);
});
const toolbarConfig: any = { excludeKeys: "fullScreen" };
const editorConfig = { placeholder: "请输入内容..." };
const handleCreated = editor => {
// editor
editorRef.value = editor;
};
//
onBeforeUnmount(() => {
const editor = editorRef.value;
if (editor == null) return;
editor.destroy();
});
</script>
<template>
<div class="wangeditor">
<Toolbar
:editor="editorRef"
:defaultConfig="toolbarConfig"
:mode="mode"
style="border-bottom: 1px solid #ccc"
/>
<Editor
v-model="valueHtml"
:defaultConfig="editorConfig"
:mode="mode"
style="height: 500px; overflow-y: hidden"
@onCreated="handleCreated"
/>
</div>
</template>

View File

@ -0,0 +1,9 @@
import base from "./base.vue";
import multi from "./multi.vue";
import picUpload from "./picUpload.vue";
const Base = base;
const Multi = multi;
const PicUpload = picUpload;
export { Base, Multi, PicUpload };

View File

@ -0,0 +1,76 @@
<script setup lang="ts">
import ReCol from "@/components/ReCol";
import { onBeforeUnmount, ref, shallowRef } from "vue";
import "@wangeditor/editor/dist/css/style.css";
import { Editor, Toolbar } from "@wangeditor/editor-for-vue";
defineOptions({
name: "MultiEditor"
});
//
const endEditorList = [
{
value: "<p>测试一</p>"
},
{
value: "<p>测试二</p>"
},
{
value: "<p>测试三</p>"
},
{
value: "<p>测试四</p>"
}
];
// Toolbar editor shallowRef
const editorList = ref([]);
endEditorList.forEach(edit => {
editorList.value.push({
value: edit.value,
// shallowRef
editorRef: shallowRef()
});
});
const mode = "default";
const toolbarConfig: any = { excludeKeys: "fullScreen" };
const editorConfig = { placeholder: "请输入内容..." };
const handleCreated = (editor, index) => {
// editor
editorList.value[index].editorRef = editor;
};
//
onBeforeUnmount(() => {
return editorList.value.map(edit => {
if (edit.editorRef == null) return;
edit.editorRef.destroy();
});
});
</script>
<template>
<el-row :gutter="30" justify="space-around">
<re-col :value="11" v-for="(edit, index) in editorList" :key="index">
<div class="wangeditor">
<Toolbar
:editor="edit.editorRef"
:defaultConfig="toolbarConfig"
:mode="mode"
style="border-bottom: 1px solid #ccc"
/>
<Editor
v-model="edit.value"
:defaultConfig="editorConfig"
:mode="mode"
style="height: 300px; overflow-y: hidden"
@onCreated="editor => handleCreated(editor, index)"
/>
</div>
</re-col>
</el-row>
</template>

View File

@ -0,0 +1,70 @@
<script setup lang="ts">
import { onBeforeUnmount, ref, shallowRef } from "vue";
import "@wangeditor/editor/dist/css/style.css";
import { Editor, Toolbar } from "@wangeditor/editor-for-vue";
defineOptions({
name: "picUpload"
});
const mode = "default";
// shallowRef
const editorRef = shallowRef();
// HTML
const valueHtml = ref(
"<p>仅提供代码参考,暂不可上传图片,可根据实际业务改写</p>"
);
const toolbarConfig: any = { excludeKeys: "fullScreen" };
const editorConfig = { placeholder: "请输入内容...", MENU_CONF: {} };
// https://www.wangeditor.com/v5/menu-config.html#%E4%B8%8A%E4%BC%A0%E5%9B%BE%E7%89%87
editorConfig.MENU_CONF["uploadImage"] = {
//
server: "",
// form-data fieldName
fieldName: "file",
//
allowedFileTypes: ["image/png", "image/jpg", "image/jpeg"],
//
customInsert(res: any, insertFn) {
// res.data.url
if (res.data.url) {
setTimeout(() => {
// insertFn
insertFn(res.data.url);
}, 2000);
}
}
};
const handleCreated = editor => {
// editor
editorRef.value = editor;
};
//
onBeforeUnmount(() => {
const editor = editorRef.value;
if (editor == null) return;
editor.destroy();
});
</script>
<template>
<div class="wangeditor">
<Toolbar
:editor="editorRef"
:defaultConfig="toolbarConfig"
:mode="mode"
style="border-bottom: 1px solid #ccc"
/>
<Editor
v-model="valueHtml"
:defaultConfig="editorConfig"
:mode="mode"
style="height: 500px; overflow-y: hidden"
@onCreated="handleCreated"
/>
</div>
</template>

View File

@ -1,41 +1,12 @@
<script setup lang="ts"> <script setup lang="ts">
import "@wangeditor/editor/dist/css/style.css"; // css import { ref } from "vue";
import { Editor, Toolbar } from "@wangeditor/editor-for-vue"; import { Base, Multi, PicUpload } from "./components";
import { useRenderIcon } from "@/components/ReIcon/src/hooks";
import { onBeforeUnmount, ref, shallowRef, onMounted } from "vue";
import Edit from "@iconify-icons/ep/edit";
defineOptions({ defineOptions({
name: "Editor" name: "Editor"
}); });
const mode = "default"; const activeNames = ref(["1"]);
// shallowRef
const editorRef = shallowRef();
// HTML
const valueHtml = ref("<p>hello</p>");
// ajax
onMounted(() => {
setTimeout(() => {
valueHtml.value = "<p>模拟 Ajax 异步设置内容</p>";
}, 1500);
});
const toolbarConfig: any = { excludeKeys: "fullScreen" };
const editorConfig = { placeholder: "请输入内容..." };
//
onBeforeUnmount(() => {
const editor = editorRef.value;
if (editor == null) return;
editor.destroy();
});
const handleCreated = editor => {
editorRef.value = editor; // editor
};
</script> </script>
<template> <template>
@ -47,7 +18,6 @@ const handleCreated = editor => {
<el-link <el-link
href="https://www.wangeditor.com" href="https://www.wangeditor.com"
target="_blank" target="_blank"
:icon="useRenderIcon(Edit)"
style="margin: 0 4px 5px; font-size: 16px" style="margin: 0 4px 5px; font-size: 16px"
> >
Wangeditor Wangeditor
@ -55,20 +25,22 @@ const handleCreated = editor => {
</span> </span>
</div> </div>
</template> </template>
<div class="wangeditor"> <el-collapse v-model="activeNames" accordion>
<Toolbar <el-collapse-item title="基础用法" name="1">
style="border-bottom: 1px solid #ccc" <Base />
:editor="editorRef" </el-collapse-item>
:defaultConfig="toolbarConfig" <el-collapse-item title="多个富文本" name="2">
:mode="mode" <Multi />
/> </el-collapse-item>
<Editor <el-collapse-item title="自定义图片上传" name="3">
style="height: 500px; overflow-y: hidden" <PicUpload />
v-model="valueHtml" </el-collapse-item>
:defaultConfig="editorConfig" </el-collapse>
:mode="mode"
@onCreated="handleCreated"
/>
</div>
</el-card> </el-card>
</template> </template>
<style lang="scss" scoped>
:deep(.el-collapse-item__header) {
padding-left: 10px;
}
</style>