mirror of
https://github.com/pure-admin/vue-pure-admin.git
synced 2025-06-08 01:17:23 +08:00
Merge branch 'main' of github.com:pure-admin/vue-pure-admin into gitee
This commit is contained in:
commit
3a488eff38
@ -1,8 +1,8 @@
|
|||||||
import type { Plugin } from "vite";
|
import type { Plugin } from "vite";
|
||||||
|
import picocolors from "picocolors";
|
||||||
import dayjs, { Dayjs } from "dayjs";
|
import dayjs, { Dayjs } from "dayjs";
|
||||||
import utils from "@pureadmin/utils";
|
import { getPackageSize } from "./utils";
|
||||||
import duration from "dayjs/plugin/duration";
|
import duration from "dayjs/plugin/duration";
|
||||||
import { green, blue, bold } from "picocolors";
|
|
||||||
dayjs.extend(duration);
|
dayjs.extend(duration);
|
||||||
|
|
||||||
export function viteBuildInfo(): Plugin {
|
export function viteBuildInfo(): Plugin {
|
||||||
@ -10,6 +10,7 @@ export function viteBuildInfo(): Plugin {
|
|||||||
let startTime: Dayjs;
|
let startTime: Dayjs;
|
||||||
let endTime: Dayjs;
|
let endTime: Dayjs;
|
||||||
let outDir: string;
|
let outDir: string;
|
||||||
|
const { green, blue, bold } = picocolors;
|
||||||
return {
|
return {
|
||||||
name: "vite:buildInfo",
|
name: "vite:buildInfo",
|
||||||
configResolved(resolvedConfig) {
|
configResolved(resolvedConfig) {
|
||||||
@ -33,7 +34,7 @@ export function viteBuildInfo(): Plugin {
|
|||||||
closeBundle() {
|
closeBundle() {
|
||||||
if (config.command === "build") {
|
if (config.command === "build") {
|
||||||
endTime = dayjs(new Date());
|
endTime = dayjs(new Date());
|
||||||
utils.getPackageSize({
|
getPackageSize({
|
||||||
folder: outDir,
|
folder: outDir,
|
||||||
callback: (size: string) => {
|
callback: (size: string) => {
|
||||||
console.log(
|
console.log(
|
||||||
|
@ -8,7 +8,7 @@ import { viteMockServe } from "vite-plugin-mock";
|
|||||||
import { configCompressPlugin } from "./compress";
|
import { configCompressPlugin } from "./compress";
|
||||||
import { visualizer } from "rollup-plugin-visualizer";
|
import { visualizer } from "rollup-plugin-visualizer";
|
||||||
import removeConsole from "vite-plugin-remove-console";
|
import removeConsole from "vite-plugin-remove-console";
|
||||||
import themePreprocessorPlugin from "@pureadmin/theme";
|
import { themePreprocessorPlugin } from "@pureadmin/theme";
|
||||||
import VueI18nPlugin from "@intlify/unplugin-vue-i18n/vite";
|
import VueI18nPlugin from "@intlify/unplugin-vue-i18n/vite";
|
||||||
import { genScssMultipleScopeVars } from "../src/layout/theme";
|
import { genScssMultipleScopeVars } from "../src/layout/theme";
|
||||||
|
|
||||||
|
34
build/utils.ts
Normal file
34
build/utils.ts
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
import { readdir, stat } from "node:fs";
|
||||||
|
import { sum, formatBytes } from "@pureadmin/utils";
|
||||||
|
|
||||||
|
const fileListTotal: number[] = [];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description 获取指定文件夹中所有文件的总大小
|
||||||
|
*/
|
||||||
|
export const getPackageSize = options => {
|
||||||
|
const { folder = "dist", callback, format = true } = options;
|
||||||
|
readdir(folder, (err, files: string[]) => {
|
||||||
|
if (err) throw err;
|
||||||
|
let count = 0;
|
||||||
|
const checkEnd = () => {
|
||||||
|
++count == files.length &&
|
||||||
|
callback(format ? formatBytes(sum(fileListTotal)) : sum(fileListTotal));
|
||||||
|
};
|
||||||
|
files.forEach((item: string) => {
|
||||||
|
stat(`${folder}/${item}`, async (err, stats) => {
|
||||||
|
if (err) throw err;
|
||||||
|
if (stats.isFile()) {
|
||||||
|
fileListTotal.push(stats.size);
|
||||||
|
checkEnd();
|
||||||
|
} else if (stats.isDirectory()) {
|
||||||
|
getPackageSize({
|
||||||
|
folder: `${folder}/${item}/`,
|
||||||
|
callback: checkEnd
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
files.length === 0 && callback(0);
|
||||||
|
});
|
||||||
|
};
|
@ -46,6 +46,7 @@ menus:
|
|||||||
hssplitPane: Split Pane
|
hssplitPane: Split Pane
|
||||||
hsbutton: Button Components
|
hsbutton: Button Components
|
||||||
hscropping: Picture Cropping
|
hscropping: Picture Cropping
|
||||||
|
hsanimatecss: AnimateCss Selector
|
||||||
hscountTo: Digital Animation
|
hscountTo: Digital Animation
|
||||||
hsselector: Selector Components
|
hsselector: Selector Components
|
||||||
hsflowChart: Flow Chart
|
hsflowChart: Flow Chart
|
||||||
|
@ -46,6 +46,7 @@ menus:
|
|||||||
hssplitPane: 切割面板
|
hssplitPane: 切割面板
|
||||||
hsbutton: 按钮组件
|
hsbutton: 按钮组件
|
||||||
hscropping: 图片裁剪
|
hscropping: 图片裁剪
|
||||||
|
hsanimatecss: AnimateCss选择器组件
|
||||||
hscountTo: 数字动画
|
hscountTo: 数字动画
|
||||||
hsselector: 选择器组件
|
hsselector: 选择器组件
|
||||||
hsflowChart: 流程图
|
hsflowChart: 流程图
|
||||||
|
@ -81,7 +81,7 @@
|
|||||||
"qs": "^6.11.2",
|
"qs": "^6.11.2",
|
||||||
"responsive-storage": "^2.2.0",
|
"responsive-storage": "^2.2.0",
|
||||||
"sortablejs": "^1.15.0",
|
"sortablejs": "^1.15.0",
|
||||||
"swiper": "^10.3.1",
|
"swiper": "^11.0.0",
|
||||||
"typeit": "^8.7.1",
|
"typeit": "^8.7.1",
|
||||||
"v-contextmenu": "3.0.0",
|
"v-contextmenu": "3.0.0",
|
||||||
"v3-infinite-loading": "^1.3.1",
|
"v3-infinite-loading": "^1.3.1",
|
||||||
@ -108,7 +108,7 @@
|
|||||||
"@iconify-icons/ri": "^1.2.10",
|
"@iconify-icons/ri": "^1.2.10",
|
||||||
"@iconify/vue": "^4.1.1",
|
"@iconify/vue": "^4.1.1",
|
||||||
"@intlify/unplugin-vue-i18n": "^1.4.0",
|
"@intlify/unplugin-vue-i18n": "^1.4.0",
|
||||||
"@pureadmin/theme": "^3.1.0",
|
"@pureadmin/theme": "^3.2.0",
|
||||||
"@types/intro.js": "^5.1.2",
|
"@types/intro.js": "^5.1.2",
|
||||||
"@types/js-cookie": "^3.0.4",
|
"@types/js-cookie": "^3.0.4",
|
||||||
"@types/mockjs": "^1.0.8",
|
"@types/mockjs": "^1.0.8",
|
||||||
|
16
pnpm-lock.yaml
generated
16
pnpm-lock.yaml
generated
@ -13,7 +13,7 @@ specifiers:
|
|||||||
'@logicflow/extension': ^1.2.16
|
'@logicflow/extension': ^1.2.16
|
||||||
'@pureadmin/descriptions': ^1.1.1
|
'@pureadmin/descriptions': ^1.1.1
|
||||||
'@pureadmin/table': ^2.3.3
|
'@pureadmin/table': ^2.3.3
|
||||||
'@pureadmin/theme': ^3.1.0
|
'@pureadmin/theme': ^3.2.0
|
||||||
'@pureadmin/utils': ^1.9.10
|
'@pureadmin/utils': ^1.9.10
|
||||||
'@types/intro.js': ^5.1.2
|
'@types/intro.js': ^5.1.2
|
||||||
'@types/js-cookie': ^3.0.4
|
'@types/js-cookie': ^3.0.4
|
||||||
@ -88,7 +88,7 @@ specifiers:
|
|||||||
stylelint-prettier: ^4.0.2
|
stylelint-prettier: ^4.0.2
|
||||||
stylelint-scss: ^5.2.1
|
stylelint-scss: ^5.2.1
|
||||||
svgo: ^3.0.2
|
svgo: ^3.0.2
|
||||||
swiper: ^10.3.1
|
swiper: ^11.0.0
|
||||||
tailwindcss: ^3.3.3
|
tailwindcss: ^3.3.3
|
||||||
terser: ^5.21.0
|
terser: ^5.21.0
|
||||||
typeit: ^8.7.1
|
typeit: ^8.7.1
|
||||||
@ -156,7 +156,7 @@ dependencies:
|
|||||||
qs: 6.11.2
|
qs: 6.11.2
|
||||||
responsive-storage: 2.2.0
|
responsive-storage: 2.2.0
|
||||||
sortablejs: 1.15.0
|
sortablejs: 1.15.0
|
||||||
swiper: 10.3.1
|
swiper: 11.0.0
|
||||||
typeit: 8.7.1
|
typeit: 8.7.1
|
||||||
v-contextmenu: 3.0.0_vue@3.3.4
|
v-contextmenu: 3.0.0_vue@3.3.4
|
||||||
v3-infinite-loading: 1.3.1
|
v3-infinite-loading: 1.3.1
|
||||||
@ -183,7 +183,7 @@ devDependencies:
|
|||||||
'@iconify-icons/ri': 1.2.10
|
'@iconify-icons/ri': 1.2.10
|
||||||
'@iconify/vue': 4.1.1_vue@3.3.4
|
'@iconify/vue': 4.1.1_vue@3.3.4
|
||||||
'@intlify/unplugin-vue-i18n': 1.4.0_vue-i18n@9.5.0
|
'@intlify/unplugin-vue-i18n': 1.4.0_vue-i18n@9.5.0
|
||||||
'@pureadmin/theme': 3.1.0
|
'@pureadmin/theme': 3.2.0
|
||||||
'@types/intro.js': 5.1.2
|
'@types/intro.js': 5.1.2
|
||||||
'@types/js-cookie': 3.0.4
|
'@types/js-cookie': 3.0.4
|
||||||
'@types/mockjs': 1.0.8
|
'@types/mockjs': 1.0.8
|
||||||
@ -1654,8 +1654,8 @@ packages:
|
|||||||
vue: 3.3.4
|
vue: 3.3.4
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
/@pureadmin/theme/3.1.0:
|
/@pureadmin/theme/3.2.0:
|
||||||
resolution: {integrity: sha512-3kBbqB6Uua096w91w1SrGna0dM8AYO5HFk/HU8G0DsEaijgRrm+dYIJUrqbv+stLUxlYPNVXpDS/APZjF0cOAg==}
|
resolution: {integrity: sha512-SBlTvEl0rmfqTW/mOJUPftvZe4yF+38CJdlBOvVITpehzCytqlG5i8XKpcs8aAR9SVfhcrLVS5Q6xh7xDVQcJQ==}
|
||||||
dependencies:
|
dependencies:
|
||||||
'@zougt/some-loader-utils': 1.4.3
|
'@zougt/some-loader-utils': 1.4.3
|
||||||
fs-extra: 11.1.1
|
fs-extra: 11.1.1
|
||||||
@ -8228,8 +8228,8 @@ packages:
|
|||||||
picocolors: 1.0.0
|
picocolors: 1.0.0
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
/swiper/10.3.1:
|
/swiper/11.0.0:
|
||||||
resolution: {integrity: sha512-24Wk3YUdZHxjc9faID97GTu6xnLNia+adMt6qMTZG/HgdSUt4fS0REsGUXJOgpTED0Amh/j+gRGQxsLayJUlBQ==}
|
resolution: {integrity: sha512-JHTJDUBVkG5L5bD+ZOw/6GkM0vArxV26b/EnciyCSgUPOa9MvAfVQLJJd+dJjo4dj5Yjp6zQaDYqOj+pF+lgzQ==}
|
||||||
engines: {node: '>= 4.7.0'}
|
engines: {node: '>= 4.7.0'}
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
|
@ -12,7 +12,7 @@
|
|||||||
"Grey": false,
|
"Grey": false,
|
||||||
"Weak": false,
|
"Weak": false,
|
||||||
"HideTabs": false,
|
"HideTabs": false,
|
||||||
"HideFooter": false,
|
"HideFooter": true,
|
||||||
"SidebarStatus": true,
|
"SidebarStatus": true,
|
||||||
"EpThemeColor": "#409EFF",
|
"EpThemeColor": "#409EFF",
|
||||||
"ShowLogo": true,
|
"ShowLogo": true,
|
||||||
|
7
src/components/ReAnimateSelector/index.ts
Normal file
7
src/components/ReAnimateSelector/index.ts
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
import reAnimateSelector from "./src/index.vue";
|
||||||
|
import { withInstall } from "@pureadmin/utils";
|
||||||
|
|
||||||
|
/** [animate.css](https://animate.style/) 选择器组件 */
|
||||||
|
export const ReAnimateSelector = withInstall(reAnimateSelector);
|
||||||
|
|
||||||
|
export default ReAnimateSelector;
|
114
src/components/ReAnimateSelector/src/animate.ts
Normal file
114
src/components/ReAnimateSelector/src/animate.ts
Normal file
@ -0,0 +1,114 @@
|
|||||||
|
export const animates = [
|
||||||
|
/* Attention seekers */
|
||||||
|
"bounce",
|
||||||
|
"flash",
|
||||||
|
"pulse",
|
||||||
|
"rubberBand",
|
||||||
|
"shakeX",
|
||||||
|
"headShake",
|
||||||
|
"swing",
|
||||||
|
"tada",
|
||||||
|
"wobble",
|
||||||
|
"jello",
|
||||||
|
"heartBeat",
|
||||||
|
/* Back entrances */
|
||||||
|
"backInDown",
|
||||||
|
"backInLeft",
|
||||||
|
"backInRight",
|
||||||
|
"backInUp",
|
||||||
|
/* Back exits */
|
||||||
|
"backOutDown",
|
||||||
|
"backOutLeft",
|
||||||
|
"backOutRight",
|
||||||
|
"backOutUp",
|
||||||
|
/* Bouncing entrances */
|
||||||
|
"bounceIn",
|
||||||
|
"bounceInDown",
|
||||||
|
"bounceInLeft",
|
||||||
|
"bounceInRight",
|
||||||
|
"bounceInUp",
|
||||||
|
/* Bouncing exits */
|
||||||
|
"bounceOut",
|
||||||
|
"bounceOutDown",
|
||||||
|
"bounceOutLeft",
|
||||||
|
"bounceOutRight",
|
||||||
|
"bounceOutUp",
|
||||||
|
/* Fading entrances */
|
||||||
|
"fadeIn",
|
||||||
|
"fadeInDown",
|
||||||
|
"fadeInDownBig",
|
||||||
|
"fadeInLeft",
|
||||||
|
"fadeInLeftBig",
|
||||||
|
"fadeInRight",
|
||||||
|
"fadeInRightBig",
|
||||||
|
"fadeInUp",
|
||||||
|
"fadeInUpBig",
|
||||||
|
"fadeInTopLeft",
|
||||||
|
"fadeInTopRight",
|
||||||
|
"fadeInBottomLeft",
|
||||||
|
"fadeInBottomRight",
|
||||||
|
/* Fading exits */
|
||||||
|
"fadeOut",
|
||||||
|
"fadeOutDown",
|
||||||
|
"fadeOutDownBig",
|
||||||
|
"fadeOutLeft",
|
||||||
|
"fadeOutLeftBig",
|
||||||
|
"fadeOutRight",
|
||||||
|
"fadeOutRightBig",
|
||||||
|
"fadeOutUp",
|
||||||
|
"fadeOutUpBig",
|
||||||
|
"fadeOutTopLeft",
|
||||||
|
"fadeOutTopRight",
|
||||||
|
"fadeOutBottomRight",
|
||||||
|
"fadeOutBottomLeft",
|
||||||
|
/* Flippers */
|
||||||
|
"flip",
|
||||||
|
"flipInX",
|
||||||
|
"flipInY",
|
||||||
|
"flipOutX",
|
||||||
|
"flipOutY",
|
||||||
|
/* Lightspeed */
|
||||||
|
"lightSpeedInRight",
|
||||||
|
"lightSpeedInLeft",
|
||||||
|
"lightSpeedOutRight",
|
||||||
|
"lightSpeedOutLeft",
|
||||||
|
/* Rotating entrances */
|
||||||
|
"rotateIn",
|
||||||
|
"rotateInDownLeft",
|
||||||
|
"rotateInDownRight",
|
||||||
|
"rotateInUpLeft",
|
||||||
|
"rotateInUpRight",
|
||||||
|
/* Rotating exits */
|
||||||
|
"rotateOut",
|
||||||
|
"rotateOutDownLeft",
|
||||||
|
"rotateOutDownRight",
|
||||||
|
"rotateOutUpLeft",
|
||||||
|
"rotateOutUpRight",
|
||||||
|
/* Specials */
|
||||||
|
"hinge",
|
||||||
|
"jackInTheBox",
|
||||||
|
"rollIn",
|
||||||
|
"rollOut",
|
||||||
|
/* Zooming entrances */
|
||||||
|
"zoomIn",
|
||||||
|
"zoomInDown",
|
||||||
|
"zoomInLeft",
|
||||||
|
"zoomInRight",
|
||||||
|
"zoomInUp",
|
||||||
|
/* Zooming exits */
|
||||||
|
"zoomOut",
|
||||||
|
"zoomOutDown",
|
||||||
|
"zoomOutLeft",
|
||||||
|
"zoomOutRight",
|
||||||
|
"zoomOutUp",
|
||||||
|
/* Sliding entrances */
|
||||||
|
"slideInDown",
|
||||||
|
"slideInLeft",
|
||||||
|
"slideInRight",
|
||||||
|
"slideInUp",
|
||||||
|
/* Sliding exits */
|
||||||
|
"slideOutDown",
|
||||||
|
"slideOutLeft",
|
||||||
|
"slideOutRight",
|
||||||
|
"slideOutUp"
|
||||||
|
];
|
127
src/components/ReAnimateSelector/src/index.vue
Normal file
127
src/components/ReAnimateSelector/src/index.vue
Normal file
@ -0,0 +1,127 @@
|
|||||||
|
<script setup lang="ts">
|
||||||
|
import { animates } from "./animate";
|
||||||
|
import { ref, computed, toRef } from "vue";
|
||||||
|
import { cloneDeep } from "@pureadmin/utils";
|
||||||
|
|
||||||
|
defineOptions({
|
||||||
|
name: "ReAnimateSelector"
|
||||||
|
});
|
||||||
|
|
||||||
|
const props = defineProps({
|
||||||
|
modelValue: {
|
||||||
|
require: false,
|
||||||
|
type: String
|
||||||
|
}
|
||||||
|
});
|
||||||
|
const emit = defineEmits<{ (e: "update:modelValue", v: string) }>();
|
||||||
|
|
||||||
|
const inputValue = toRef(props, "modelValue");
|
||||||
|
const animatesList = ref(animates);
|
||||||
|
const copyAnimatesList = cloneDeep(animatesList);
|
||||||
|
|
||||||
|
const animateClass = computed(() => {
|
||||||
|
return [
|
||||||
|
"mt-1",
|
||||||
|
"flex",
|
||||||
|
"border",
|
||||||
|
"w-[130px]",
|
||||||
|
"h-[100px]",
|
||||||
|
"items-center",
|
||||||
|
"cursor-pointer",
|
||||||
|
"transition-all",
|
||||||
|
"justify-center",
|
||||||
|
"border-[#e5e7eb]",
|
||||||
|
"hover:text-primary",
|
||||||
|
"hover:duration-[700ms]"
|
||||||
|
];
|
||||||
|
});
|
||||||
|
|
||||||
|
const animateStyle = computed(
|
||||||
|
() => (i: string) =>
|
||||||
|
inputValue.value === i
|
||||||
|
? {
|
||||||
|
borderColor: "var(--el-color-primary)",
|
||||||
|
color: "var(--el-color-primary)"
|
||||||
|
}
|
||||||
|
: ""
|
||||||
|
);
|
||||||
|
|
||||||
|
function onChangeIcon(animate: string) {
|
||||||
|
emit("update:modelValue", animate);
|
||||||
|
}
|
||||||
|
|
||||||
|
function onClear() {
|
||||||
|
emit("update:modelValue", "");
|
||||||
|
}
|
||||||
|
|
||||||
|
function filterMethod(value: any) {
|
||||||
|
animatesList.value = copyAnimatesList.value.filter((i: string | any[]) =>
|
||||||
|
i.includes(value)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const animateMap = ref({});
|
||||||
|
function onMouseEnter(index: string | number) {
|
||||||
|
animateMap.value[index] = animateMap.value[index]?.loading
|
||||||
|
? Object.assign({}, animateMap.value[index], {
|
||||||
|
loading: false
|
||||||
|
})
|
||||||
|
: Object.assign({}, animateMap.value[index], {
|
||||||
|
loading: true
|
||||||
|
});
|
||||||
|
}
|
||||||
|
function onMouseleave() {
|
||||||
|
animateMap.value = {};
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<el-select
|
||||||
|
:model-value="inputValue"
|
||||||
|
placeholder="请选择动画"
|
||||||
|
clearable
|
||||||
|
filterable
|
||||||
|
@clear="onClear"
|
||||||
|
:filter-method="filterMethod"
|
||||||
|
>
|
||||||
|
<template #empty>
|
||||||
|
<div class="w-[280px]">
|
||||||
|
<el-scrollbar
|
||||||
|
noresize
|
||||||
|
height="212px"
|
||||||
|
:view-style="{ overflow: 'hidden' }"
|
||||||
|
class="border-t border-[#e5e7eb]"
|
||||||
|
>
|
||||||
|
<ul class="flex flex-wrap justify-around mb-1">
|
||||||
|
<li
|
||||||
|
v-for="(animate, index) in animatesList"
|
||||||
|
:key="index"
|
||||||
|
:class="animateClass"
|
||||||
|
:style="animateStyle(animate)"
|
||||||
|
@mouseenter.prevent="onMouseEnter(index)"
|
||||||
|
@mouseleave.prevent="onMouseleave"
|
||||||
|
@click="onChangeIcon(animate)"
|
||||||
|
>
|
||||||
|
<h4
|
||||||
|
:class="[
|
||||||
|
`animate__animated animate__${
|
||||||
|
animateMap[index]?.loading
|
||||||
|
? animate + ' animate__infinite'
|
||||||
|
: ''
|
||||||
|
} `
|
||||||
|
]"
|
||||||
|
>
|
||||||
|
{{ animate }}
|
||||||
|
</h4>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
<el-empty
|
||||||
|
v-show="animatesList.length === 0"
|
||||||
|
description="暂无动画"
|
||||||
|
:image-size="60"
|
||||||
|
/>
|
||||||
|
</el-scrollbar>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</el-select>
|
||||||
|
</template>
|
@ -2,31 +2,33 @@ import "./index.css";
|
|||||||
import {
|
import {
|
||||||
h,
|
h,
|
||||||
ref,
|
ref,
|
||||||
|
toRef,
|
||||||
watch,
|
watch,
|
||||||
nextTick,
|
nextTick,
|
||||||
defineComponent,
|
defineComponent,
|
||||||
getCurrentInstance
|
getCurrentInstance
|
||||||
} from "vue";
|
} from "vue";
|
||||||
import type { OptionsType } from "./type";
|
import type { OptionsType } from "./type";
|
||||||
import { isFunction, useDark } from "@pureadmin/utils";
|
|
||||||
import { useRenderIcon } from "@/components/ReIcon/src/hooks";
|
import { useRenderIcon } from "@/components/ReIcon/src/hooks";
|
||||||
|
import { isFunction, isNumber, useDark } from "@pureadmin/utils";
|
||||||
|
|
||||||
const props = {
|
const props = {
|
||||||
options: {
|
options: {
|
||||||
type: Array<OptionsType>,
|
type: Array<OptionsType>,
|
||||||
default: () => []
|
default: () => []
|
||||||
},
|
},
|
||||||
/** 默认选中,按照第一个索引为 `0` 的模式 */
|
/** 默认选中,按照第一个索引为 `0` 的模式,可选(`modelValue`只有传`number`类型时才为响应式) */
|
||||||
defaultValue: {
|
modelValue: {
|
||||||
type: Number,
|
type: undefined,
|
||||||
default: 0
|
require: false,
|
||||||
|
default: "0"
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
name: "ReSegmented",
|
name: "ReSegmented",
|
||||||
props,
|
props,
|
||||||
emits: ["change"],
|
emits: ["change", "update:modelValue"],
|
||||||
setup(props, { emit }) {
|
setup(props, { emit }) {
|
||||||
const width = ref(0);
|
const width = ref(0);
|
||||||
const translateX = ref(0);
|
const translateX = ref(0);
|
||||||
@ -35,12 +37,16 @@ export default defineComponent({
|
|||||||
const curMouseActive = ref(-1);
|
const curMouseActive = ref(-1);
|
||||||
const segmentedItembg = ref("");
|
const segmentedItembg = ref("");
|
||||||
const instance = getCurrentInstance()!;
|
const instance = getCurrentInstance()!;
|
||||||
const curIndex = ref(props.defaultValue);
|
const curIndex = isNumber(props.modelValue)
|
||||||
|
? toRef(props, "modelValue")
|
||||||
|
: ref(0);
|
||||||
|
|
||||||
function handleChange({ option, index }, event: Event) {
|
function handleChange({ option, index }, event: Event) {
|
||||||
if (option.disabled) return;
|
if (option.disabled) return;
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
curIndex.value = index;
|
isNumber(props.modelValue)
|
||||||
|
? emit("update:modelValue", index)
|
||||||
|
: (curIndex.value = index);
|
||||||
segmentedItembg.value = "";
|
segmentedItembg.value = "";
|
||||||
emit("change", { index, option });
|
emit("change", { index, option });
|
||||||
}
|
}
|
||||||
|
@ -21,6 +21,7 @@ const {
|
|||||||
logout,
|
logout,
|
||||||
backTopMenu,
|
backTopMenu,
|
||||||
onPanel,
|
onPanel,
|
||||||
|
getLogo,
|
||||||
username,
|
username,
|
||||||
userAvatar,
|
userAvatar,
|
||||||
avatarsStyle,
|
avatarsStyle,
|
||||||
@ -43,7 +44,7 @@ nextTick(() => {
|
|||||||
class="horizontal-header"
|
class="horizontal-header"
|
||||||
>
|
>
|
||||||
<div class="horizontal-header-left" @click="backTopMenu">
|
<div class="horizontal-header-left" @click="backTopMenu">
|
||||||
<img src="/logo.svg" alt="logo" />
|
<img :src="getLogo()" alt="logo" />
|
||||||
<span>{{ title }}</span>
|
<span>{{ title }}</span>
|
||||||
</div>
|
</div>
|
||||||
<el-menu
|
<el-menu
|
||||||
|
@ -6,7 +6,7 @@ const props = defineProps({
|
|||||||
collapse: Boolean
|
collapse: Boolean
|
||||||
});
|
});
|
||||||
|
|
||||||
const { title } = useNav();
|
const { title, getLogo } = useNav();
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
@ -19,7 +19,7 @@ const { title } = useNav();
|
|||||||
class="sidebar-logo-link"
|
class="sidebar-logo-link"
|
||||||
:to="getTopMenu()?.path ?? '/'"
|
:to="getTopMenu()?.path ?? '/'"
|
||||||
>
|
>
|
||||||
<img src="/logo.svg" alt="logo" />
|
<img :src="getLogo()" alt="logo" />
|
||||||
<span class="sidebar-title">{{ title }}</span>
|
<span class="sidebar-title">{{ title }}</span>
|
||||||
</router-link>
|
</router-link>
|
||||||
<router-link
|
<router-link
|
||||||
@ -29,7 +29,7 @@ const { title } = useNav();
|
|||||||
class="sidebar-logo-link"
|
class="sidebar-logo-link"
|
||||||
:to="getTopMenu()?.path ?? '/'"
|
:to="getTopMenu()?.path ?? '/'"
|
||||||
>
|
>
|
||||||
<img src="/logo.svg" alt="logo" />
|
<img :src="getLogo()" alt="logo" />
|
||||||
<span class="sidebar-title">{{ title }}</span>
|
<span class="sidebar-title">{{ title }}</span>
|
||||||
</router-link>
|
</router-link>
|
||||||
</transition>
|
</transition>
|
||||||
|
@ -6,10 +6,10 @@ import { useTags } from "../../hooks/useTag";
|
|||||||
import { routerArrays } from "@/layout/types";
|
import { routerArrays } from "@/layout/types";
|
||||||
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 { useResizeObserver, useFullscreen } from "@vueuse/core";
|
|
||||||
import { isEqual, isAllEmpty, debounce } from "@pureadmin/utils";
|
import { isEqual, isAllEmpty, debounce } from "@pureadmin/utils";
|
||||||
import { useMultiTagsStoreHook } from "@/store/modules/multiTags";
|
import { useMultiTagsStoreHook } from "@/store/modules/multiTags";
|
||||||
import { ref, watch, unref, toRaw, nextTick, onBeforeUnmount } from "vue";
|
import { ref, watch, unref, toRaw, nextTick, onBeforeUnmount } from "vue";
|
||||||
|
import { useResizeObserver, useFullscreen, onClickOutside } from "@vueuse/core";
|
||||||
|
|
||||||
import ExitFullscreen from "@iconify-icons/ri/fullscreen-exit-fill";
|
import ExitFullscreen from "@iconify-icons/ri/fullscreen-exit-fill";
|
||||||
import Fullscreen from "@iconify-icons/ri/fullscreen-fill";
|
import Fullscreen from "@iconify-icons/ri/fullscreen-fill";
|
||||||
@ -49,6 +49,7 @@ const {
|
|||||||
const tabDom = ref();
|
const tabDom = ref();
|
||||||
const containerDom = ref();
|
const containerDom = ref();
|
||||||
const scrollbarDom = ref();
|
const scrollbarDom = ref();
|
||||||
|
const contextmenuRef = ref();
|
||||||
const isShowArrow = ref(false);
|
const isShowArrow = ref(false);
|
||||||
const topPath = getTopMenu()?.path;
|
const topPath = getTopMenu()?.path;
|
||||||
const { VITE_HIDE_HOME } = import.meta.env;
|
const { VITE_HIDE_HOME } = import.meta.env;
|
||||||
@ -328,6 +329,7 @@ function handleCommand(command: any) {
|
|||||||
|
|
||||||
/** 触发右键中菜单的点击事件 */
|
/** 触发右键中菜单的点击事件 */
|
||||||
function selectTag(key, item) {
|
function selectTag(key, item) {
|
||||||
|
closeMenu();
|
||||||
onClickDrop(key, item, currentSelect.value);
|
onClickDrop(key, item, currentSelect.value);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -462,6 +464,10 @@ function tagOnClick(item) {
|
|||||||
// showMenuModel(item?.path, item?.query);
|
// showMenuModel(item?.path, item?.query);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
onClickOutside(contextmenuRef, closeMenu, {
|
||||||
|
detectIframe: true
|
||||||
|
});
|
||||||
|
|
||||||
watch(route, () => {
|
watch(route, () => {
|
||||||
activeIndex.value = -1;
|
activeIndex.value = -1;
|
||||||
dynamicTagView();
|
dynamicTagView();
|
||||||
@ -558,6 +564,7 @@ onBeforeUnmount(() => {
|
|||||||
<transition name="el-zoom-in-top">
|
<transition name="el-zoom-in-top">
|
||||||
<ul
|
<ul
|
||||||
v-show="visible"
|
v-show="visible"
|
||||||
|
ref="contextmenuRef"
|
||||||
:key="Math.random()"
|
:key="Math.random()"
|
||||||
:style="getContextMenuStyle"
|
:style="getContextMenuStyle"
|
||||||
class="contextmenu"
|
class="contextmenu"
|
||||||
|
@ -58,7 +58,6 @@ onMounted(() => {
|
|||||||
.frame {
|
.frame {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
inset: 0;
|
inset: 0;
|
||||||
z-index: 998;
|
|
||||||
|
|
||||||
.frame-iframe {
|
.frame-iframe {
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
|
@ -36,7 +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,
|
hideFooter: $config.HideFooter ?? true,
|
||||||
showLogo: $config?.ShowLogo ?? true,
|
showLogo: $config?.ShowLogo ?? true,
|
||||||
showModel: $config?.ShowModel ?? "smart",
|
showModel: $config?.ShowModel ?? "smart",
|
||||||
multiTagsCache: $config?.MultiTagsCache ?? false
|
multiTagsCache: $config?.MultiTagsCache ?? false
|
||||||
|
@ -124,6 +124,11 @@ export function useNav() {
|
|||||||
return remainingPaths.includes(path);
|
return remainingPaths.includes(path);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** 获取`logo` */
|
||||||
|
function getLogo() {
|
||||||
|
return new URL("/logo.svg", import.meta.url).href;
|
||||||
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
title,
|
title,
|
||||||
device,
|
device,
|
||||||
@ -139,6 +144,7 @@ export function useNav() {
|
|||||||
menuSelect,
|
menuSelect,
|
||||||
handleResize,
|
handleResize,
|
||||||
resolvePath,
|
resolvePath,
|
||||||
|
getLogo,
|
||||||
isCollapse,
|
isCollapse,
|
||||||
pureApp,
|
pureApp,
|
||||||
username,
|
username,
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
import {
|
import {
|
||||||
ref,
|
ref,
|
||||||
unref,
|
unref,
|
||||||
watch,
|
|
||||||
computed,
|
computed,
|
||||||
reactive,
|
reactive,
|
||||||
onMounted,
|
onMounted,
|
||||||
@ -9,7 +8,6 @@ import {
|
|||||||
getCurrentInstance
|
getCurrentInstance
|
||||||
} from "vue";
|
} from "vue";
|
||||||
import { tagsViewsType } from "../types";
|
import { tagsViewsType } from "../types";
|
||||||
import { useEventListener } from "@vueuse/core";
|
|
||||||
import { useRoute, useRouter } from "vue-router";
|
import { useRoute, useRouter } from "vue-router";
|
||||||
import { transformI18n, $t } from "@/plugins/i18n";
|
import { transformI18n, $t } from "@/plugins/i18n";
|
||||||
import { responsiveStorageNameSpace } from "@/config";
|
import { responsiveStorageNameSpace } from "@/config";
|
||||||
@ -215,13 +213,6 @@ export function useTags() {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
watch(
|
|
||||||
() => visible.value,
|
|
||||||
() => {
|
|
||||||
useEventListener(document, "click", closeMenu);
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
route,
|
route,
|
||||||
router,
|
router,
|
||||||
|
@ -105,6 +105,15 @@ export default {
|
|||||||
title: $t("menus.hscropping")
|
title: $t("menus.hscropping")
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
path: "/components/animatecss",
|
||||||
|
name: "AnimateCss",
|
||||||
|
component: () => import("@/views/components/animatecss/index.vue"),
|
||||||
|
meta: {
|
||||||
|
title: $t("menus.hsanimatecss"),
|
||||||
|
extraIcon: "IF-pure-iconfont-new svg"
|
||||||
|
}
|
||||||
|
},
|
||||||
{
|
{
|
||||||
path: "/components/countTo",
|
path: "/components/countTo",
|
||||||
name: "CountTo",
|
name: "CountTo",
|
||||||
|
@ -73,7 +73,7 @@ class PureHttp {
|
|||||||
return config;
|
return config;
|
||||||
}
|
}
|
||||||
/** 请求白名单,放置一些不需要token的接口(通过设置请求白名单,防止token过期后再请求造成的死循环问题) */
|
/** 请求白名单,放置一些不需要token的接口(通过设置请求白名单,防止token过期后再请求造成的死循环问题) */
|
||||||
const whiteList = ["/refreshToken", "/login"];
|
const whiteList = ["/refresh-token", "/login"];
|
||||||
return whiteList.find(url => url === config.url)
|
return whiteList.find(url => url === config.url)
|
||||||
? config
|
? config
|
||||||
: new Promise(resolve => {
|
: new Promise(resolve => {
|
||||||
|
@ -24,7 +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,
|
hideFooter: config.HideFooter ?? true,
|
||||||
showLogo: config.ShowLogo ?? true,
|
showLogo: config.ShowLogo ?? true,
|
||||||
showModel: config.ShowModel ?? "smart",
|
showModel: config.ShowModel ?? "smart",
|
||||||
multiTagsCache: config.MultiTagsCache ?? false
|
multiTagsCache: config.MultiTagsCache ?? false
|
||||||
|
34
src/views/components/animatecss/index.vue
Normal file
34
src/views/components/animatecss/index.vue
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
<script setup lang="ts">
|
||||||
|
import { ref, watch } from "vue";
|
||||||
|
import ReAnimateSelector from "@/components/ReAnimateSelector";
|
||||||
|
|
||||||
|
defineOptions({
|
||||||
|
name: "AnimateCss"
|
||||||
|
});
|
||||||
|
|
||||||
|
const icon = ref("");
|
||||||
|
|
||||||
|
watch(icon, () => {
|
||||||
|
console.log("icon", icon.value);
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<el-card shadow="never">
|
||||||
|
<template #header>
|
||||||
|
<div class="card-header">
|
||||||
|
<span class="font-medium">
|
||||||
|
<el-link
|
||||||
|
href="https://animate.style/"
|
||||||
|
target="_blank"
|
||||||
|
style="margin: 0 4px 5px; font-size: 16px"
|
||||||
|
>
|
||||||
|
animate.css
|
||||||
|
</el-link>
|
||||||
|
选择器组件
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<ReAnimateSelector v-model="icon" />
|
||||||
|
</el-card>
|
||||||
|
</template>
|
@ -1,5 +1,5 @@
|
|||||||
<script setup lang="tsx">
|
<script setup lang="tsx">
|
||||||
import { h } from "vue";
|
import { h, ref } from "vue";
|
||||||
import { message } from "@/utils/message";
|
import { message } from "@/utils/message";
|
||||||
import HomeFilled from "@iconify-icons/ep/home-filled";
|
import HomeFilled from "@iconify-icons/ep/home-filled";
|
||||||
import { useRenderIcon } from "@/components/ReIcon/src/hooks";
|
import { useRenderIcon } from "@/components/ReIcon/src/hooks";
|
||||||
@ -10,51 +10,43 @@ defineOptions({
|
|||||||
});
|
});
|
||||||
|
|
||||||
/** 基础用法 */
|
/** 基础用法 */
|
||||||
|
const value = ref(4); // 必须为number类型
|
||||||
|
|
||||||
const optionsBasis: Array<OptionsType> = [
|
const optionsBasis: Array<OptionsType> = [
|
||||||
{
|
{
|
||||||
label: "周一",
|
label: "周一"
|
||||||
value: 1
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: "周二",
|
label: "周二"
|
||||||
value: 2
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: "周三",
|
label: "周三"
|
||||||
value: 3
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: "周四",
|
label: "周四"
|
||||||
value: 4
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: "周五",
|
label: "周五"
|
||||||
value: 5
|
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
/** 禁用 */
|
/** 禁用 */
|
||||||
const optionsDisabled: Array<OptionsType> = [
|
const optionsDisabled: Array<OptionsType> = [
|
||||||
{
|
{
|
||||||
label: "周一",
|
label: "周一"
|
||||||
value: 1
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: "周二",
|
label: "周二"
|
||||||
value: 2
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: "周三",
|
label: "周三",
|
||||||
value: 3,
|
|
||||||
disabled: true
|
disabled: true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: "周四",
|
label: "周四"
|
||||||
value: 4
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: "周五",
|
label: "周五",
|
||||||
value: 5,
|
|
||||||
disabled: true
|
disabled: true
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
@ -63,26 +55,21 @@ const optionsDisabled: Array<OptionsType> = [
|
|||||||
const optionsIcon: Array<OptionsType> = [
|
const optionsIcon: Array<OptionsType> = [
|
||||||
{
|
{
|
||||||
label: "周一",
|
label: "周一",
|
||||||
value: 1,
|
|
||||||
icon: HomeFilled
|
icon: HomeFilled
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: "周二",
|
label: "周二"
|
||||||
value: 2
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: "周三",
|
label: "周三",
|
||||||
value: 3,
|
|
||||||
icon: "terminalWindowLine"
|
icon: "terminalWindowLine"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: "周四",
|
label: "周四",
|
||||||
value: 4,
|
|
||||||
icon: "streamline-emojis:airplane"
|
icon: "streamline-emojis:airplane"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: "周五",
|
label: "周五",
|
||||||
value: 5,
|
|
||||||
icon: "streamline-emojis:2"
|
icon: "streamline-emojis:2"
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
@ -90,23 +77,18 @@ const optionsIcon: Array<OptionsType> = [
|
|||||||
/** 只设置图标 */
|
/** 只设置图标 */
|
||||||
const optionsOnlyIcon: Array<OptionsType> = [
|
const optionsOnlyIcon: Array<OptionsType> = [
|
||||||
{
|
{
|
||||||
value: 1,
|
|
||||||
icon: HomeFilled
|
icon: HomeFilled
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
value: 2,
|
|
||||||
icon: "terminalWindowLine"
|
icon: "terminalWindowLine"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
value: 3,
|
|
||||||
icon: "streamline-emojis:cow-face"
|
icon: "streamline-emojis:cow-face"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
value: 4,
|
|
||||||
icon: "streamline-emojis:airplane"
|
icon: "streamline-emojis:airplane"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
value: 5,
|
|
||||||
icon: "streamline-emojis:2"
|
icon: "streamline-emojis:2"
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
@ -121,8 +103,7 @@ const optionsLabel: Array<OptionsType> = [
|
|||||||
})}
|
})}
|
||||||
<p>周一</p>
|
<p>周一</p>
|
||||||
</div>
|
</div>
|
||||||
),
|
)
|
||||||
value: 1
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: () => (
|
label: () => (
|
||||||
@ -132,8 +113,7 @@ const optionsLabel: Array<OptionsType> = [
|
|||||||
})}
|
})}
|
||||||
<p>周二</p>
|
<p>周二</p>
|
||||||
</div>
|
</div>
|
||||||
),
|
)
|
||||||
value: 2
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: () => (
|
label: () => (
|
||||||
@ -143,8 +123,7 @@ const optionsLabel: Array<OptionsType> = [
|
|||||||
})}
|
})}
|
||||||
<p>周三</p>
|
<p>周三</p>
|
||||||
</div>
|
</div>
|
||||||
),
|
)
|
||||||
value: 3
|
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
@ -179,11 +158,15 @@ function onChange({ index, option }) {
|
|||||||
<span class="font-medium">分段控制器</span>
|
<span class="font-medium">分段控制器</span>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<p class="mb-2">基础用法</p>
|
<p class="mb-2">
|
||||||
<Segmented :options="optionsBasis" />
|
基础用法(v-model)<span class="text-primary">
|
||||||
|
{{ optionsBasis[value].label }}
|
||||||
|
</span>
|
||||||
|
</p>
|
||||||
|
<Segmented :options="optionsBasis" v-model="value" />
|
||||||
<el-divider />
|
<el-divider />
|
||||||
<p class="mb-2">默认选中和禁用</p>
|
<p class="mb-2">禁用</p>
|
||||||
<Segmented :options="optionsDisabled" :defaultValue="2" />
|
<Segmented :options="optionsDisabled" />
|
||||||
<el-divider />
|
<el-divider />
|
||||||
<p class="mb-2">设置图标</p>
|
<p class="mb-2">设置图标</p>
|
||||||
<Segmented :options="optionsIcon" />
|
<Segmented :options="optionsIcon" />
|
||||||
|
Loading…
x
Reference in New Issue
Block a user