mirror of
https://github.com/vbenjs/vue-vben-admin.git
synced 2025-08-26 16:46:19 +08:00
refactor: add loading component and demo
This commit is contained in:
@@ -3,7 +3,7 @@
|
|||||||
## (破坏性更新) Breaking changes
|
## (破坏性更新) Breaking changes
|
||||||
|
|
||||||
- The ClickOutSide component import method is changed from `import ClickOutSide from'/@/components/ClickOutSide/index.vue'` to `import {ClickOutSide} from'/@/components/ClickOutSide'`
|
- The ClickOutSide component import method is changed from `import ClickOutSide from'/@/components/ClickOutSide/index.vue'` to `import {ClickOutSide} from'/@/components/ClickOutSide'`
|
||||||
- Button component import method changed from `import ClickOutSide from'/@/components/Button/index.vue'` to `import {Button} from'/@/components/Button'`
|
- Button component import method changed from `import Button from'/@/components/Button/index.vue'` to `import {Button} from'/@/components/Button'`
|
||||||
- StrengthMeter component import method is changed from `import StrengthMeter from'/@/components/StrengthMeter'` to `import {StrengthMeter} from'/@/components/StrengthMeter'`
|
- StrengthMeter component import method is changed from `import StrengthMeter from'/@/components/StrengthMeter'` to `import {StrengthMeter} from'/@/components/StrengthMeter'`
|
||||||
- In addition to the examples, the global internationalization function is added, supporting Chinese and English
|
- In addition to the examples, the global internationalization function is added, supporting Chinese and English
|
||||||
|
|
||||||
|
@@ -1,9 +1,19 @@
|
|||||||
|
## Wip
|
||||||
|
|
||||||
|
### ✨ Features
|
||||||
|
|
||||||
|
- 还原 antdv 默认 loading,重构 `Loading` 组件,增加`useLoading`和`v-loading`指令。并增加示例
|
||||||
|
|
||||||
|
### 🎫 Chores
|
||||||
|
|
||||||
|
- 首屏 loading 修改
|
||||||
|
|
||||||
## 2.0.0-rc.12 (2020-11-30)
|
## 2.0.0-rc.12 (2020-11-30)
|
||||||
|
|
||||||
## (破坏性更新) Breaking changes
|
## (破坏性更新) Breaking changes
|
||||||
|
|
||||||
- ClickOutSide 组件引入方式由 `import ClickOutSide from '/@/components/ClickOutSide/index.vue'`变更为`import { ClickOutSide } from '/@/components/ClickOutSide'`
|
- ClickOutSide 组件引入方式由 `import ClickOutSide from '/@/components/ClickOutSide/index.vue'`变更为`import { ClickOutSide } from '/@/components/ClickOutSide'`
|
||||||
- Button 组件引入方式由 `import ClickOutSide from '/@/components/Button/index.vue'`变更为`import { Button } from '/@/components/Button'`
|
- Button 组件引入方式由 `import Button from '/@/components/Button/index.vue'`变更为`import { Button } from '/@/components/Button'`
|
||||||
- StrengthMeter 组件引入方式由 `import StrengthMeter from '/@/components/StrengthMeter'`变更为`import { StrengthMeter } from '/@/components/StrengthMeter'`
|
- StrengthMeter 组件引入方式由 `import StrengthMeter from '/@/components/StrengthMeter'`变更为`import { StrengthMeter } from '/@/components/StrengthMeter'`
|
||||||
- 除示例外加入全局国际化功能,支持中文与英文
|
- 除示例外加入全局国际化功能,支持中文与英文
|
||||||
|
|
||||||
|
@@ -2,6 +2,7 @@
|
|||||||
* less global variable
|
* less global variable
|
||||||
*/
|
*/
|
||||||
const primaryColor = '#018ffb';
|
const primaryColor = '#018ffb';
|
||||||
|
// const primaryColor = '#0065cc';
|
||||||
//{
|
//{
|
||||||
const modifyVars = {
|
const modifyVars = {
|
||||||
'primary-color': primaryColor, // Global dominant color
|
'primary-color': primaryColor, // Global dominant color
|
||||||
|
142
index.html
142
index.html
@@ -13,68 +13,136 @@
|
|||||||
<title></title>
|
<title></title>
|
||||||
<link rel="icon" href="/favicon.ico" />
|
<link rel="icon" href="/favicon.ico" />
|
||||||
<%= viteHtmlPluginOptions.injectConfig %>
|
<%= viteHtmlPluginOptions.injectConfig %>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div id="app">
|
||||||
<style>
|
<style>
|
||||||
@keyframes load {
|
|
||||||
0% {
|
|
||||||
-webkit-transform: rotate(-360deg);
|
|
||||||
transform: rotate(-360deg);
|
|
||||||
}
|
|
||||||
|
|
||||||
100% {
|
|
||||||
-webkit-transform: rotate(0);
|
|
||||||
transform: rotate(0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.app-loading {
|
.app-loading {
|
||||||
|
display: flex;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
background: #f0f2f5;
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
flex-direction: column;
|
||||||
}
|
}
|
||||||
|
|
||||||
.app-loading .app-loading-wrap {
|
.app-loading .app-loading-wrap {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 50%;
|
top: 50%;
|
||||||
left: 50%;
|
left: 50%;
|
||||||
|
display: flex;
|
||||||
-webkit-transform: translate3d(-50%, -50%, 0);
|
-webkit-transform: translate3d(-50%, -50%, 0);
|
||||||
transform: translate3d(-50%, -50%, 0);
|
transform: translate3d(-50%, -50%, 0);
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
flex-direction: column;
|
||||||
}
|
}
|
||||||
|
|
||||||
.app-loading .g-loading {
|
.app-loading .dots {
|
||||||
display: block;
|
display: flex;
|
||||||
width: 48px;
|
padding: 98px;
|
||||||
margin: 30px auto;
|
justify-content: center;
|
||||||
-webkit-animation: load 1.2s linear infinite;
|
align-items: center;
|
||||||
animation: load 1.2s linear infinite;
|
|
||||||
-webkit-transform-origin: center center;
|
|
||||||
transform-origin: center center;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.app-loading .app-loading-wrap img.logo {
|
.app-loading .app-loading-title {
|
||||||
|
display: flex;
|
||||||
|
margin-top: 30px;
|
||||||
|
font-size: 30px;
|
||||||
|
color: rgba(0, 0, 0, 0.85);
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.app-loading .app-loading-logo {
|
||||||
display: block;
|
display: block;
|
||||||
width: 90px;
|
width: 90px;
|
||||||
margin: 0 auto;
|
margin: 0 auto;
|
||||||
margin-bottom: 20px;
|
margin-bottom: 20px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.app-loading .app-loading-wrap .app-loading__tip {
|
.dot {
|
||||||
|
position: relative;
|
||||||
|
display: inline-block;
|
||||||
|
width: 48px;
|
||||||
|
height: 48px;
|
||||||
|
margin-top: 30px;
|
||||||
|
font-size: 32px;
|
||||||
|
transform: rotate(45deg);
|
||||||
|
box-sizing: border-box;
|
||||||
|
animation: antRotate 1.2s infinite linear;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dot i {
|
||||||
|
position: absolute;
|
||||||
display: block;
|
display: block;
|
||||||
margin: 20px auto 0 0;
|
width: 20px;
|
||||||
font-size: 30px;
|
height: 20px;
|
||||||
color: rgba(0, 0, 0, 0.85);
|
background-color: #0065cc;
|
||||||
|
border-radius: 100%;
|
||||||
|
opacity: 0.3;
|
||||||
|
transform: scale(0.75);
|
||||||
|
animation: antSpinMove 1s infinite linear alternate;
|
||||||
|
transform-origin: 50% 50%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dot i:nth-child(1) {
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dot i:nth-child(2) {
|
||||||
|
top: 0;
|
||||||
|
right: 0;
|
||||||
|
-webkit-animation-delay: 0.4s;
|
||||||
|
animation-delay: 0.4s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dot i:nth-child(3) {
|
||||||
|
right: 0;
|
||||||
|
bottom: 0;
|
||||||
|
-webkit-animation-delay: 0.8s;
|
||||||
|
animation-delay: 0.8s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dot i:nth-child(4) {
|
||||||
|
bottom: 0;
|
||||||
|
left: 0;
|
||||||
|
-webkit-animation-delay: 1.2s;
|
||||||
|
animation-delay: 1.2s;
|
||||||
|
}
|
||||||
|
@keyframes antRotate {
|
||||||
|
to {
|
||||||
|
-webkit-transform: rotate(405deg);
|
||||||
|
transform: rotate(405deg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@-webkit-keyframes antRotate {
|
||||||
|
to {
|
||||||
|
-webkit-transform: rotate(405deg);
|
||||||
|
transform: rotate(405deg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@keyframes antSpinMove {
|
||||||
|
to {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@-webkit-keyframes antSpinMove {
|
||||||
|
to {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
</head>
|
<div class="app-loading">
|
||||||
<body>
|
<div class="app-loading-wrap">
|
||||||
<div id="app">
|
<img src="./resource/img/logo.png" class="app-loading-logo" alt="Logo" />
|
||||||
<section class="app-loading">
|
<div class="app-loading-dots">
|
||||||
<section class="app-loading-wrap">
|
<span class="dot dot-spin"><i></i><i></i><i></i><i></i></span>
|
||||||
<img src="./resource/img/logo.png" class="logo" alt="Logo" />
|
</div>
|
||||||
<img src="./resource/img/loading.svg" alt="" class="g-loading" />
|
<div class="app-loading-title"><%= viteHtmlPluginOptions.title %></div>
|
||||||
<h1 class="app-loading__tip"><%= viteHtmlPluginOptions.title %></h1>
|
</div>
|
||||||
</section>
|
</div>
|
||||||
</section>
|
|
||||||
</div>
|
</div>
|
||||||
<script type="module" src="/src/main.ts"></script>
|
<script type="module" src="/src/main.ts"></script>
|
||||||
</body>
|
</body>
|
||||||
|
@@ -22,7 +22,7 @@
|
|||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@iconify/iconify": "^2.0.0-rc.2",
|
"@iconify/iconify": "^2.0.0-rc.2",
|
||||||
"ant-design-vue": "2.0.0-rc.2",
|
"ant-design-vue": "^2.0.0-rc.2",
|
||||||
"apexcharts": "3.22.0",
|
"apexcharts": "3.22.0",
|
||||||
"axios": "^0.21.0",
|
"axios": "^0.21.0",
|
||||||
"crypto-es": "^1.2.6",
|
"crypto-es": "^1.2.6",
|
||||||
|
@@ -1,49 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
|
||||||
<svg viewBox="0 0 200 200" version="1.1"
|
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
|
||||||
xmlns:xlink="http://www.w3.org/1999/xlink">
|
|
||||||
<style type="text/css">
|
|
||||||
.left-linear {
|
|
||||||
fill: url(#left-linear);
|
|
||||||
}
|
|
||||||
|
|
||||||
.right-linear {
|
|
||||||
fill: url(#right-linear);
|
|
||||||
}
|
|
||||||
|
|
||||||
.top {
|
|
||||||
fill: #64acff;
|
|
||||||
}
|
|
||||||
|
|
||||||
.bottom {
|
|
||||||
fill: #9dbfe4;
|
|
||||||
}
|
|
||||||
svg {
|
|
||||||
display: block;
|
|
||||||
}
|
|
||||||
|
|
||||||
.tip {
|
|
||||||
display: block;
|
|
||||||
min-width: 100px;
|
|
||||||
margin-top: 4px;
|
|
||||||
font-size: 13px;
|
|
||||||
color: rgba(0, 0, 0, 0.85);;
|
|
||||||
text-align: left;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
<circle cx="97" cy="97" r="81" stroke-width="16" stroke="#327fd8" fill="none"></circle>
|
|
||||||
<g class="load">
|
|
||||||
<linearGradient id="left-linear" gradientUnits="userSpaceOnUse" x1="50" y1="0" x2="100" y2="180">
|
|
||||||
<stop offset="0" style="stop-color: #64acff;" />
|
|
||||||
<stop offset="1" style="stop-color: #9DBFE4;" />
|
|
||||||
</linearGradient>
|
|
||||||
<path class="left-linear" d="M20,100c0-44.1,35.9-80,80-80V0C44.8,0,0,44.8,0,100s44.8,100,100,100v-20C55.9,180,20,144.1,20,100z" />
|
|
||||||
<circle class="bottom" cx="100" cy="190" r="10" />
|
|
||||||
<linearGradient id="right-linear" gradientUnits="userSpaceOnUse" x1="100" y1="120" x2="100" y2="180">
|
|
||||||
<stop offset="0" style="stop-color: transparent;" />
|
|
||||||
<stop offset="1" style="stop-color: transparent;" />
|
|
||||||
</linearGradient>
|
|
||||||
<path class="right-linear" d="M100,0v20c44.1,0,80,35.9,80,80c0,44.1-35.9,80-80,80v20c55.2,0,100-44.8,100-100S155.2,0,100,0z" />
|
|
||||||
<circle class="top" cx="100" cy="10" r="10" />
|
|
||||||
</g>
|
|
||||||
</svg>
|
|
Before Width: | Height: | Size: 1.6 KiB |
@@ -1,67 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
|
||||||
<svg viewBox="0 0 200 200" version="1.1"
|
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
|
||||||
xmlns:xlink="http://www.w3.org/1999/xlink">
|
|
||||||
<style type="text/css">
|
|
||||||
.left-linear {
|
|
||||||
fill: url(#left-linear);
|
|
||||||
}
|
|
||||||
|
|
||||||
.right-linear {
|
|
||||||
fill: url(#right-linear);
|
|
||||||
}
|
|
||||||
|
|
||||||
.top {
|
|
||||||
fill: #64acff;
|
|
||||||
}
|
|
||||||
|
|
||||||
.bottom {
|
|
||||||
fill: #9dbfe4;
|
|
||||||
}
|
|
||||||
@keyframes load {
|
|
||||||
0% {
|
|
||||||
transform: rotate(-360deg);
|
|
||||||
}
|
|
||||||
|
|
||||||
100% {
|
|
||||||
transform: rotate(0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.load {
|
|
||||||
animation: load 1.4s linear infinite;
|
|
||||||
transform-origin: center center;
|
|
||||||
}
|
|
||||||
|
|
||||||
svg {
|
|
||||||
display: block;
|
|
||||||
}
|
|
||||||
|
|
||||||
.tip {
|
|
||||||
display: block;
|
|
||||||
min-width: 100px;
|
|
||||||
margin-top: 4px;
|
|
||||||
font-size: 13px;
|
|
||||||
color: #303133;
|
|
||||||
text-align: left;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
<circle cx="97" cy="97" r="81" stroke-width="16" stroke="#327fd8" fill="none"></circle>
|
|
||||||
<g class="load">
|
|
||||||
<!--右半圆环-->
|
|
||||||
<linearGradient id="left-linear" gradientUnits="userSpaceOnUse" x1="50" y1="0" x2="100" y2="180">
|
|
||||||
<stop offset="0" style="stop-color: #64acff;" />
|
|
||||||
<stop offset="1" style="stop-color: #9DBFE4;" />
|
|
||||||
</linearGradient>
|
|
||||||
<path class="left-linear" d="M20,100c0-44.1,35.9-80,80-80V0C44.8,0,0,44.8,0,100s44.8,100,100,100v-20C55.9,180,20,144.1,20,100z" />
|
|
||||||
<!--左半圆环-->
|
|
||||||
<circle class="bottom" cx="100" cy="190" r="10" />
|
|
||||||
<linearGradient id="right-linear" gradientUnits="userSpaceOnUse" x1="100" y1="120" x2="100" y2="180">
|
|
||||||
<stop offset="0" style="stop-color: transparent;" />
|
|
||||||
<stop offset="1" style="stop-color: transparent;" />
|
|
||||||
</linearGradient>
|
|
||||||
<path class="right-linear" d="M100,0v20c44.1,0,80,35.9,80,80c0,44.1-35.9,80-80,80v20c55.2,0,100-44.8,100-100S155.2,0,100,0z" />
|
|
||||||
<!--左半圆环-->
|
|
||||||
<circle class="top" cx="100" cy="10" r="10" />
|
|
||||||
</g>
|
|
||||||
</svg>
|
|
Before Width: | Height: | Size: 2.0 KiB |
@@ -1,3 +1,7 @@
|
|||||||
|
<!--
|
||||||
|
* @Author: Vben
|
||||||
|
* @Description: Multi-language switching component
|
||||||
|
-->
|
||||||
<template>
|
<template>
|
||||||
<Dropdown
|
<Dropdown
|
||||||
:trigger="['click']"
|
:trigger="['click']"
|
||||||
|
@@ -1,3 +1,7 @@
|
|||||||
|
<!--
|
||||||
|
* @Author: Vben
|
||||||
|
* @Description: logo component
|
||||||
|
-->
|
||||||
<template>
|
<template>
|
||||||
<div
|
<div
|
||||||
class="app-logo anticon"
|
class="app-logo anticon"
|
||||||
|
@@ -7,7 +7,7 @@ import { defineComponent, ref, computed, watchEffect, watch, unref, nextTick, to
|
|||||||
import { Drawer, Row, Col, Button } from 'ant-design-vue';
|
import { Drawer, Row, Col, Button } from 'ant-design-vue';
|
||||||
|
|
||||||
import { BasicTitle } from '/@/components/Basic';
|
import { BasicTitle } from '/@/components/Basic';
|
||||||
import { FullLoading } from '/@/components/Loading/index';
|
import { Loading } from '/@/components/Loading';
|
||||||
import { LeftOutlined } from '@ant-design/icons-vue';
|
import { LeftOutlined } from '@ant-design/icons-vue';
|
||||||
|
|
||||||
import { useI18n } from '/@/hooks/web/useI18n';
|
import { useI18n } from '/@/hooks/web/useI18n';
|
||||||
@@ -97,9 +97,7 @@ export default defineComponent({
|
|||||||
);
|
);
|
||||||
|
|
||||||
const getLoading = computed(() => {
|
const getLoading = computed(() => {
|
||||||
return {
|
return !!unref(getProps)?.loading;
|
||||||
hidden: !unref(getProps).loading,
|
|
||||||
};
|
|
||||||
});
|
});
|
||||||
|
|
||||||
watchEffect(() => {
|
watchEffect(() => {
|
||||||
@@ -230,7 +228,7 @@ export default defineComponent({
|
|||||||
default: () => (
|
default: () => (
|
||||||
<>
|
<>
|
||||||
<div ref={scrollRef} style={unref(getScrollContentStyle)}>
|
<div ref={scrollRef} style={unref(getScrollContentStyle)}>
|
||||||
<FullLoading absolute tip={t('loadingText')} class={unref(getLoading)} />
|
<Loading absolute tip={t('loadingText')} loading={unref(getLoading)} />
|
||||||
{getSlot(slots)}
|
{getSlot(slots)}
|
||||||
</div>
|
</div>
|
||||||
{renderFooter()}
|
{renderFooter()}
|
||||||
|
@@ -1,55 +0,0 @@
|
|||||||
<template>
|
|
||||||
<section class="basic-loading">
|
|
||||||
<img
|
|
||||||
src="/@/assets/images/loading.svg"
|
|
||||||
alt=""
|
|
||||||
:height="getLoadingIconSize"
|
|
||||||
:width="getLoadingIconSize"
|
|
||||||
/>
|
|
||||||
<span class="mt-4" v-if="tip"> {{ tip }}</span>
|
|
||||||
</section>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script lang="ts">
|
|
||||||
import type { PropType } from 'vue';
|
|
||||||
// components
|
|
||||||
import { defineComponent, computed } from 'vue';
|
|
||||||
|
|
||||||
import { SizeEnum, sizeMap } from '/@/enums/sizeEnum';
|
|
||||||
|
|
||||||
import { BasicLoadingProps } from './type';
|
|
||||||
|
|
||||||
export default defineComponent({
|
|
||||||
inheritAttrs: false,
|
|
||||||
name: 'BasicLoading',
|
|
||||||
props: {
|
|
||||||
tip: {
|
|
||||||
type: String as PropType<string>,
|
|
||||||
default: '',
|
|
||||||
},
|
|
||||||
size: {
|
|
||||||
type: String as PropType<SizeEnum>,
|
|
||||||
default: SizeEnum.DEFAULT,
|
|
||||||
validator: (v: SizeEnum): boolean => {
|
|
||||||
return [SizeEnum.DEFAULT, SizeEnum.SMALL, SizeEnum.LARGE].includes(v);
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
setup(props: BasicLoadingProps) {
|
|
||||||
const getLoadingIconSize = computed(() => {
|
|
||||||
const { size } = props;
|
|
||||||
return sizeMap.get(size);
|
|
||||||
});
|
|
||||||
|
|
||||||
return { getLoadingIconSize };
|
|
||||||
},
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
<style lang="less" scoped>
|
|
||||||
.basic-loading {
|
|
||||||
display: flex;
|
|
||||||
justify-content: center;
|
|
||||||
align-items: center;
|
|
||||||
flex-direction: column;
|
|
||||||
}
|
|
||||||
</style>
|
|
@@ -1,50 +0,0 @@
|
|||||||
<template>
|
|
||||||
<section class="full-loading" :style="getStyle">
|
|
||||||
<BasicLoading :tip="tip" :size="SizeEnum.DEFAULT" />
|
|
||||||
</section>
|
|
||||||
</template>
|
|
||||||
<script lang="ts">
|
|
||||||
import type { PropType } from 'vue';
|
|
||||||
import { defineComponent, computed } from 'vue';
|
|
||||||
import BasicLoading from './BasicLoading.vue';
|
|
||||||
|
|
||||||
import { SizeEnum } from '/@/enums/sizeEnum';
|
|
||||||
|
|
||||||
export default defineComponent({
|
|
||||||
name: 'FullLoading',
|
|
||||||
components: { BasicLoading },
|
|
||||||
props: {
|
|
||||||
tip: {
|
|
||||||
type: String as PropType<string>,
|
|
||||||
default: '',
|
|
||||||
},
|
|
||||||
absolute: Boolean as PropType<boolean>,
|
|
||||||
},
|
|
||||||
setup(props) {
|
|
||||||
const getStyle = computed((): any => {
|
|
||||||
return props.absolute
|
|
||||||
? {
|
|
||||||
position: 'absolute',
|
|
||||||
left: 0,
|
|
||||||
top: 0,
|
|
||||||
'z-index': 1,
|
|
||||||
}
|
|
||||||
: {};
|
|
||||||
});
|
|
||||||
|
|
||||||
return { getStyle, SizeEnum };
|
|
||||||
},
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
<style lang="less" scoped>
|
|
||||||
.full-loading {
|
|
||||||
display: flex;
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
// background: rgba(255, 255, 255, 0.3);
|
|
||||||
// background: #f0f2f5;
|
|
||||||
background: rgba(240, 242, 245, 0.5);
|
|
||||||
justify-content: center;
|
|
||||||
align-items: center;
|
|
||||||
}
|
|
||||||
</style>
|
|
@@ -1,2 +1,8 @@
|
|||||||
export { default as BasicLoading } from './BasicLoading.vue';
|
import './src/indicator';
|
||||||
export { default as FullLoading } from './FullLoading.vue';
|
import LoadingLib from './src/index.vue';
|
||||||
|
import { withInstall } from '../util';
|
||||||
|
|
||||||
|
export { useLoading } from './src/useLoading';
|
||||||
|
export { createLoading } from './src/createLoading';
|
||||||
|
|
||||||
|
export const Loading = withInstall(LoadingLib);
|
||||||
|
60
src/components/Loading/src/createLoading.ts
Normal file
60
src/components/Loading/src/createLoading.ts
Normal file
@@ -0,0 +1,60 @@
|
|||||||
|
import { VNode, defineComponent } from 'vue';
|
||||||
|
import type { LoadingProps } from './types';
|
||||||
|
|
||||||
|
import { createVNode, render, reactive, h } from 'vue';
|
||||||
|
import Loading from './index.vue';
|
||||||
|
|
||||||
|
export function createLoading(props?: Partial<LoadingProps>, target?: HTMLElement) {
|
||||||
|
let vm: Nullable<VNode> = null;
|
||||||
|
const data = reactive({
|
||||||
|
tip: '',
|
||||||
|
loading: true,
|
||||||
|
...props,
|
||||||
|
});
|
||||||
|
|
||||||
|
const LoadingWrap = defineComponent({
|
||||||
|
setup() {
|
||||||
|
return () => {
|
||||||
|
return h(Loading, { ...data });
|
||||||
|
};
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
vm = createVNode(LoadingWrap);
|
||||||
|
|
||||||
|
render(vm, document.createElement('div'));
|
||||||
|
|
||||||
|
function close() {
|
||||||
|
if (vm?.el && vm.el.parentNode) {
|
||||||
|
vm.el.parentNode.removeChild(vm.el);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function open(target: HTMLElement = document.body) {
|
||||||
|
if (!vm || !vm.el) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
target.appendChild(vm.el as HTMLElement);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (target) {
|
||||||
|
open(target);
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
vm,
|
||||||
|
close,
|
||||||
|
open,
|
||||||
|
setTip: (tip: string) => {
|
||||||
|
data.tip = tip;
|
||||||
|
},
|
||||||
|
setLoading: (loading: boolean) => {
|
||||||
|
data.loading = loading;
|
||||||
|
},
|
||||||
|
get loading() {
|
||||||
|
return data.loading;
|
||||||
|
},
|
||||||
|
get $el() {
|
||||||
|
return vm?.el as HTMLElement;
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
82
src/components/Loading/src/index.vue
Normal file
82
src/components/Loading/src/index.vue
Normal file
@@ -0,0 +1,82 @@
|
|||||||
|
<template>
|
||||||
|
<section class="full-loading" :class="{ absolute }" v-show="loading" :style="getStyle">
|
||||||
|
<Spin v-bind="$attrs" :tip="tip" :size="size" :spinning="loading" />
|
||||||
|
</section>
|
||||||
|
</template>
|
||||||
|
<script lang="ts">
|
||||||
|
import { computed, CSSProperties, PropType } from 'vue';
|
||||||
|
|
||||||
|
import { defineComponent } from 'vue';
|
||||||
|
import { Spin } from 'ant-design-vue';
|
||||||
|
|
||||||
|
import { SizeEnum } from '/@/enums/sizeEnum';
|
||||||
|
import { ThemeEnum } from '/@/enums/appEnum';
|
||||||
|
|
||||||
|
export default defineComponent({
|
||||||
|
name: 'Loading',
|
||||||
|
components: { Spin },
|
||||||
|
props: {
|
||||||
|
tip: {
|
||||||
|
type: String as PropType<string>,
|
||||||
|
default: '',
|
||||||
|
},
|
||||||
|
size: {
|
||||||
|
type: String as PropType<SizeEnum>,
|
||||||
|
default: SizeEnum.LARGE,
|
||||||
|
validator: (v: SizeEnum): boolean => {
|
||||||
|
return [SizeEnum.DEFAULT, SizeEnum.SMALL, SizeEnum.LARGE].includes(v);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
absolute: {
|
||||||
|
type: Boolean as PropType<boolean>,
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
|
loading: {
|
||||||
|
type: Boolean as PropType<boolean>,
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
|
background: {
|
||||||
|
type: String as PropType<string>,
|
||||||
|
},
|
||||||
|
theme: {
|
||||||
|
type: String as PropType<'dark' | 'light'>,
|
||||||
|
default: 'light',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
setup(props) {
|
||||||
|
const getStyle = computed(
|
||||||
|
(): CSSProperties => {
|
||||||
|
const { background, theme } = props;
|
||||||
|
const bgColor = background
|
||||||
|
? background
|
||||||
|
: theme === ThemeEnum.DARK
|
||||||
|
? 'rgba(0, 0, 0, 0.2)'
|
||||||
|
: 'rgba(240, 242, 245, 0.4)';
|
||||||
|
return { background: bgColor };
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
return { getStyle };
|
||||||
|
},
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
<style lang="less" scoped>
|
||||||
|
.full-loading {
|
||||||
|
position: fixed;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
z-index: 200;
|
||||||
|
display: flex;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
|
&.absolute {
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
z-index: 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
9
src/components/Loading/src/indicator.tsx
Normal file
9
src/components/Loading/src/indicator.tsx
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
// If you need to modify the default icon, you can open the comment and modify it here
|
||||||
|
|
||||||
|
// import { Spin } from 'ant-design-vue';
|
||||||
|
// import { LoadingOutlined } from '@ant-design/icons-vue';
|
||||||
|
// Spin.setDefaultIndicator({
|
||||||
|
// indicator: () => {
|
||||||
|
// return <LoadingOutlined spin />;
|
||||||
|
// },
|
||||||
|
// });
|
10
src/components/Loading/src/types.ts
Normal file
10
src/components/Loading/src/types.ts
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
import { SizeEnum } from '/@/enums/sizeEnum';
|
||||||
|
|
||||||
|
export interface LoadingProps {
|
||||||
|
tip: string;
|
||||||
|
size: SizeEnum;
|
||||||
|
absolute: boolean;
|
||||||
|
loading: boolean;
|
||||||
|
background: string;
|
||||||
|
theme: 'dark' | 'light';
|
||||||
|
}
|
39
src/components/Loading/src/useLoading.ts
Normal file
39
src/components/Loading/src/useLoading.ts
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
import { unref } from 'vue';
|
||||||
|
import { createLoading } from './createLoading';
|
||||||
|
import type { LoadingProps } from './types';
|
||||||
|
import type { Ref } from 'vue';
|
||||||
|
|
||||||
|
export interface UseLoadingOptions {
|
||||||
|
target?: HTMLElement | Ref<ElRef>;
|
||||||
|
props?: Partial<LoadingProps>;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function useLoading(props: Partial<LoadingProps>): [Fn, Fn];
|
||||||
|
export function useLoading(opt: Partial<UseLoadingOptions>): [Fn, Fn];
|
||||||
|
|
||||||
|
export function useLoading(opt: Partial<LoadingProps> | Partial<UseLoadingOptions>): [Fn, Fn] {
|
||||||
|
let props: Partial<LoadingProps>;
|
||||||
|
let target: HTMLElement | Ref<ElRef> = document.body;
|
||||||
|
|
||||||
|
if (Reflect.has(opt, 'target') || Reflect.has(opt, 'props')) {
|
||||||
|
const options = opt as Partial<UseLoadingOptions>;
|
||||||
|
props = options.props || {};
|
||||||
|
target = options.target || document.body;
|
||||||
|
} else {
|
||||||
|
props = opt as Partial<LoadingProps>;
|
||||||
|
}
|
||||||
|
|
||||||
|
const instance = createLoading(props);
|
||||||
|
|
||||||
|
const open = (): void => {
|
||||||
|
const t = unref(target);
|
||||||
|
if (!t) return;
|
||||||
|
instance.open(t);
|
||||||
|
};
|
||||||
|
|
||||||
|
const close = (): void => {
|
||||||
|
instance.close();
|
||||||
|
};
|
||||||
|
|
||||||
|
return [open, close];
|
||||||
|
}
|
@@ -1,8 +0,0 @@
|
|||||||
import { SizeEnum } from '/@/enums/sizeEnum';
|
|
||||||
|
|
||||||
export interface BasicLoadingProps {
|
|
||||||
// 提示语
|
|
||||||
tip: string;
|
|
||||||
|
|
||||||
size: SizeEnum;
|
|
||||||
}
|
|
@@ -1,16 +1,17 @@
|
|||||||
|
import './index.less';
|
||||||
|
|
||||||
import { defineComponent, ref, unref, computed, reactive, watchEffect } from 'vue';
|
import { defineComponent, ref, unref, computed, reactive, watchEffect } from 'vue';
|
||||||
|
|
||||||
import { basicProps } from './props';
|
import { basicProps } from './props';
|
||||||
import { Props } from './types';
|
import { Props } from './types';
|
||||||
import './index.less';
|
|
||||||
|
|
||||||
import { CloseOutlined, LeftOutlined, RightOutlined } from '@ant-design/icons-vue';
|
import { CloseOutlined, LeftOutlined, RightOutlined, LoadingOutlined } from '@ant-design/icons-vue';
|
||||||
|
import { Spin } from 'ant-design-vue';
|
||||||
|
|
||||||
import resumeSvg from '/@/assets/svg/preview/resume.svg';
|
import resumeSvg from '/@/assets/svg/preview/resume.svg';
|
||||||
import rotateSvg from '/@/assets/svg/preview/p-rotate.svg';
|
import rotateSvg from '/@/assets/svg/preview/p-rotate.svg';
|
||||||
import scaleSvg from '/@/assets/svg/preview/scale.svg';
|
import scaleSvg from '/@/assets/svg/preview/scale.svg';
|
||||||
import unScaleSvg from '/@/assets/svg/preview/unscale.svg';
|
import unScaleSvg from '/@/assets/svg/preview/unscale.svg';
|
||||||
import loadingSvg from '/@/assets/images/loading.svg';
|
|
||||||
import unRotateSvg from '/@/assets/svg/preview/unrotate.svg';
|
import unRotateSvg from '/@/assets/svg/preview/unrotate.svg';
|
||||||
enum StatueEnum {
|
enum StatueEnum {
|
||||||
LOADING,
|
LOADING,
|
||||||
@@ -271,12 +272,14 @@ export default defineComponent({
|
|||||||
imgState.show && (
|
imgState.show && (
|
||||||
<div class={prefixCls} ref={wrapElRef} onMouseup={handleMouseUp}>
|
<div class={prefixCls} ref={wrapElRef} onMouseup={handleMouseUp}>
|
||||||
<div class={`${prefixCls}-content`}>
|
<div class={`${prefixCls}-content`}>
|
||||||
<img
|
<Spin
|
||||||
width="32"
|
indicator={<LoadingOutlined style="font-size: 24px" spin />}
|
||||||
src={loadingSvg}
|
spinning={true}
|
||||||
class={[
|
class={[
|
||||||
`${prefixCls}-image`,
|
`${prefixCls}-image`,
|
||||||
imgState.status === StatueEnum.LOADING ? '' : 'hidden',
|
{
|
||||||
|
hidden: imgState.status !== StatueEnum.LOADING,
|
||||||
|
},
|
||||||
]}
|
]}
|
||||||
/>
|
/>
|
||||||
<img
|
<img
|
||||||
|
@@ -3,11 +3,6 @@
|
|||||||
height: 100%;
|
height: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.app-svg-loading {
|
|
||||||
position: relative;
|
|
||||||
width: auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
// =================================
|
// =================================
|
||||||
// ==============scrollbar==========
|
// ==============scrollbar==========
|
||||||
// =================================
|
// =================================
|
||||||
|
@@ -26,6 +26,7 @@ export function useI18n(namespace?: string) {
|
|||||||
return {
|
return {
|
||||||
...methods,
|
...methods,
|
||||||
t: (key: string, ...arg: Parameters<typeof t>) => {
|
t: (key: string, ...arg: Parameters<typeof t>) => {
|
||||||
|
if (!key) return '';
|
||||||
return t(getKey(key), ...arg);
|
return t(getKey(key), ...arg);
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
@@ -14,10 +14,6 @@
|
|||||||
position: absolute;
|
position: absolute;
|
||||||
z-index: @page-loading-z-index;
|
z-index: @page-loading-z-index;
|
||||||
|
|
||||||
&.fill {
|
|
||||||
background: rgba(240, 242, 245) !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
> .basic-loading {
|
> .basic-loading {
|
||||||
margin-bottom: 15%;
|
margin-bottom: 15%;
|
||||||
}
|
}
|
||||||
|
@@ -1,31 +1,25 @@
|
|||||||
import './index.less';
|
import './index.less';
|
||||||
|
|
||||||
import { defineComponent, unref, computed } from 'vue';
|
import { defineComponent, unref } from 'vue';
|
||||||
import { FullLoading } from '/@/components/Loading/index';
|
import { Loading } from '/@/components/Loading';
|
||||||
|
|
||||||
import { RouterView } from 'vue-router';
|
import { RouterView } from 'vue-router';
|
||||||
|
|
||||||
import { useRootSetting } from '/@/hooks/setting/useRootSetting';
|
import { useRootSetting } from '/@/hooks/setting/useRootSetting';
|
||||||
import { useTransitionSetting } from '/@/hooks/setting/useTransitionSetting';
|
import { useTransitionSetting } from '/@/hooks/setting/useTransitionSetting';
|
||||||
import { useMultipleTabSetting } from '/@/hooks/setting/useMultipleTabSetting';
|
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
name: 'LayoutContent',
|
name: 'LayoutContent',
|
||||||
setup() {
|
setup() {
|
||||||
const { getOpenPageLoading } = useTransitionSetting();
|
const { getOpenPageLoading } = useTransitionSetting();
|
||||||
const { getShowMultipleTab } = useMultipleTabSetting();
|
|
||||||
const { getLayoutContentMode, getPageLoading } = useRootSetting();
|
const { getLayoutContentMode, getPageLoading } = useRootSetting();
|
||||||
|
|
||||||
const getLoadingClass = computed(() => {
|
|
||||||
return [
|
|
||||||
`layout-content__loading`,
|
|
||||||
{ fill: unref(getShowMultipleTab), hidden: !unref(getPageLoading) },
|
|
||||||
];
|
|
||||||
});
|
|
||||||
return () => {
|
return () => {
|
||||||
return (
|
return (
|
||||||
<div class={['layout-content', unref(getLayoutContentMode)]}>
|
<div class={['layout-content', unref(getLayoutContentMode)]}>
|
||||||
{unref(getOpenPageLoading) && <FullLoading class={unref(getLoadingClass)} />}
|
{unref(getOpenPageLoading) && (
|
||||||
|
<Loading loading={unref(getPageLoading)} absolute class="layout-content__loading" />
|
||||||
|
)}
|
||||||
<RouterView />
|
<RouterView />
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
@@ -22,6 +22,7 @@ export default defineComponent({
|
|||||||
name: 'PageLayout',
|
name: 'PageLayout',
|
||||||
setup() {
|
setup() {
|
||||||
const { getShowMenu } = useMenuSetting();
|
const { getShowMenu } = useMenuSetting();
|
||||||
|
|
||||||
const { getOpenKeepAlive, getCanEmbedIFramePage } = useRootSetting();
|
const { getOpenKeepAlive, getCanEmbedIFramePage } = useRootSetting();
|
||||||
|
|
||||||
const { getBasicTransition, getEnableTransition } = useTransitionSetting();
|
const { getBasicTransition, getEnableTransition } = useTransitionSetting();
|
||||||
|
@@ -24,4 +24,6 @@ export default {
|
|||||||
qrcode: 'QR code',
|
qrcode: 'QR code',
|
||||||
strength: 'Password strength',
|
strength: 'Password strength',
|
||||||
upload: 'Upload',
|
upload: 'Upload',
|
||||||
|
|
||||||
|
loading: 'Loading',
|
||||||
};
|
};
|
||||||
|
@@ -24,4 +24,6 @@ export default {
|
|||||||
qrcode: '二维码组件',
|
qrcode: '二维码组件',
|
||||||
strength: '密码强度组件',
|
strength: '密码强度组件',
|
||||||
upload: '上传组件',
|
upload: '上传组件',
|
||||||
|
|
||||||
|
loading: 'Loading',
|
||||||
};
|
};
|
||||||
|
@@ -44,6 +44,10 @@ const menu: MenuModule = {
|
|||||||
path: 'upload',
|
path: 'upload',
|
||||||
name: 'routes.demo.comp.upload',
|
name: 'routes.demo.comp.upload',
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
path: 'loading',
|
||||||
|
name: 'routes.demo.comp.loading',
|
||||||
|
},
|
||||||
{
|
{
|
||||||
path: 'scroll',
|
path: 'scroll',
|
||||||
name: 'routes.demo.comp.scroll',
|
name: 'routes.demo.comp.scroll',
|
||||||
|
@@ -178,6 +178,14 @@ const comp: AppRouteModule = {
|
|||||||
title: 'routes.demo.comp.upload',
|
title: 'routes.demo.comp.upload',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
path: '/loading',
|
||||||
|
name: 'LoadingDemo',
|
||||||
|
component: () => import('/@/views/demo/comp/loading/index.vue'),
|
||||||
|
meta: {
|
||||||
|
title: 'routes.demo.comp.loading',
|
||||||
|
},
|
||||||
|
},
|
||||||
],
|
],
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@@ -12,8 +12,6 @@ import {
|
|||||||
} from 'ant-design-vue';
|
} from 'ant-design-vue';
|
||||||
import 'ant-design-vue/dist/antd.css';
|
import 'ant-design-vue/dist/antd.css';
|
||||||
|
|
||||||
import './spin';
|
|
||||||
|
|
||||||
export function setupAntd(app: App<Element>) {
|
export function setupAntd(app: App<Element>) {
|
||||||
// need
|
// need
|
||||||
// Here are the components required before registering and logging in
|
// Here are the components required before registering and logging in
|
||||||
|
@@ -1,12 +0,0 @@
|
|||||||
import { Spin } from 'ant-design-vue';
|
|
||||||
import svgImg from '/@/assets/images/loading.svg';
|
|
||||||
|
|
||||||
Spin.setDefaultIndicator({
|
|
||||||
indicator: () => {
|
|
||||||
return (
|
|
||||||
<div class="app-svg-loading">
|
|
||||||
<img src={svgImg} alt="" height="32" width="32" />
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
},
|
|
||||||
});
|
|
@@ -3,7 +3,9 @@
|
|||||||
*/
|
*/
|
||||||
import type { App } from 'vue';
|
import type { App } from 'vue';
|
||||||
import { setupPermissionDirective } from './permission';
|
import { setupPermissionDirective } from './permission';
|
||||||
|
import { setupLoadingDirective } from './loading';
|
||||||
|
|
||||||
export function setupGlobDirectives(app: App) {
|
export function setupGlobDirectives(app: App) {
|
||||||
setupPermissionDirective(app);
|
setupPermissionDirective(app);
|
||||||
|
setupLoadingDirective(app);
|
||||||
}
|
}
|
||||||
|
43
src/setup/directives/loading.ts
Normal file
43
src/setup/directives/loading.ts
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
import { createLoading } from '/@/components/Loading';
|
||||||
|
import type { Directive, App } from 'vue';
|
||||||
|
|
||||||
|
const loadingDirective: Directive = {
|
||||||
|
mounted(el, binding) {
|
||||||
|
const tip = el.getAttribute('loading-tip');
|
||||||
|
const background = el.getAttribute('loading-background');
|
||||||
|
const theme = el.getAttribute('loading-theme');
|
||||||
|
const size = el.getAttribute('loading-size');
|
||||||
|
const fullscreen = !!binding.modifiers.fullscreen;
|
||||||
|
const instance = createLoading(
|
||||||
|
{
|
||||||
|
tip,
|
||||||
|
background,
|
||||||
|
theme,
|
||||||
|
size: size || 'large',
|
||||||
|
loading: !!binding.value,
|
||||||
|
absolute: !fullscreen,
|
||||||
|
},
|
||||||
|
fullscreen ? document.body : el
|
||||||
|
);
|
||||||
|
el.instance = instance;
|
||||||
|
},
|
||||||
|
updated(el, binding) {
|
||||||
|
const instance = el.instance;
|
||||||
|
if (!instance) return;
|
||||||
|
instance.setTip(el.getAttribute('loading-tip'));
|
||||||
|
if (binding.oldValue !== binding.value) {
|
||||||
|
if (binding.oldValue !== binding.value) {
|
||||||
|
instance.setLoading?.(binding.value && !instance.loading);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
unmounted(el) {
|
||||||
|
el?.instance?.close();
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
export function setupLoadingDirective(app: App) {
|
||||||
|
app.directive('loading', loadingDirective);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default loadingDirective;
|
@@ -15,7 +15,8 @@ const localeData: I18nOptions = {
|
|||||||
messages: localeMessages,
|
messages: localeMessages,
|
||||||
availableLocales: availableLocales,
|
availableLocales: availableLocales,
|
||||||
sync: true, //If you don’t want to inherit locale from global scope, you need to set sync of i18n component option to false.
|
sync: true, //If you don’t want to inherit locale from global scope, you need to set sync of i18n component option to false.
|
||||||
silentTranslationWarn: false, // true - warning off
|
silentTranslationWarn: true, // true - warning off
|
||||||
|
missingWarn: false,
|
||||||
silentFallbackWarn: true,
|
silentFallbackWarn: true,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
96
src/views/demo/comp/loading/index.vue
Normal file
96
src/views/demo/comp/loading/index.vue
Normal file
@@ -0,0 +1,96 @@
|
|||||||
|
<template>
|
||||||
|
<div class="p-5" ref="wrapEl" v-loading="loadingRef" loading-tip="加载中...">
|
||||||
|
<a-alert message="组件方式" />
|
||||||
|
<a-button class="my-4 mr-4" type="primary" @click="openCompFullLoading">全屏 Loading</a-button>
|
||||||
|
<a-button class="my-4" type="primary" @click="openCompAbsolute">容器内 Loading</a-button>
|
||||||
|
<Loading :loading="loading" :absolute="absolute" :tip="tip" />
|
||||||
|
|
||||||
|
<a-alert message="函数方式" />
|
||||||
|
|
||||||
|
<a-button class="my-4 mr-4" type="primary" @click="openFnFullLoading">全屏 Loading</a-button>
|
||||||
|
<a-button class="my-4" type="primary" @click="openFnWrapLoading">容器内 Loading</a-button>
|
||||||
|
|
||||||
|
<a-alert message="指令方式" />
|
||||||
|
<a-button class="my-4 mr-4" type="primary" @click="openDirectiveLoading">
|
||||||
|
打开指令Loading
|
||||||
|
</a-button>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<script lang="ts">
|
||||||
|
import { defineComponent, reactive, toRefs, ref } from 'vue';
|
||||||
|
import { Loading, useLoading } from '/@/components/Loading';
|
||||||
|
export default defineComponent({
|
||||||
|
components: { Loading },
|
||||||
|
setup() {
|
||||||
|
const wrapEl = ref<ElRef>(null);
|
||||||
|
|
||||||
|
const loadingRef = ref(false);
|
||||||
|
const compState = reactive({
|
||||||
|
absolute: false,
|
||||||
|
loading: false,
|
||||||
|
tip: '加载中...',
|
||||||
|
});
|
||||||
|
const [openFullLoading, closeFullLoading] = useLoading({
|
||||||
|
tip: '加载中...',
|
||||||
|
});
|
||||||
|
|
||||||
|
const [openWrapLoading, closeWrapLoading] = useLoading({
|
||||||
|
target: wrapEl,
|
||||||
|
props: {
|
||||||
|
tip: '加载中...',
|
||||||
|
absolute: true,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
function openLoading(absolute: boolean) {
|
||||||
|
compState.absolute = absolute;
|
||||||
|
compState.loading = true;
|
||||||
|
setTimeout(() => {
|
||||||
|
compState.loading = false;
|
||||||
|
}, 2000);
|
||||||
|
}
|
||||||
|
|
||||||
|
function openCompFullLoading() {
|
||||||
|
openLoading(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
function openCompAbsolute() {
|
||||||
|
openLoading(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
function openFnFullLoading() {
|
||||||
|
openFullLoading();
|
||||||
|
|
||||||
|
setTimeout(() => {
|
||||||
|
closeFullLoading();
|
||||||
|
}, 2000);
|
||||||
|
}
|
||||||
|
|
||||||
|
function openFnWrapLoading() {
|
||||||
|
openWrapLoading();
|
||||||
|
|
||||||
|
setTimeout(() => {
|
||||||
|
closeWrapLoading();
|
||||||
|
}, 2000);
|
||||||
|
}
|
||||||
|
|
||||||
|
function openDirectiveLoading() {
|
||||||
|
loadingRef.value = true;
|
||||||
|
setTimeout(() => {
|
||||||
|
loadingRef.value = false;
|
||||||
|
}, 2000);
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
openCompFullLoading,
|
||||||
|
openFnFullLoading,
|
||||||
|
openFnWrapLoading,
|
||||||
|
openCompAbsolute,
|
||||||
|
wrapEl,
|
||||||
|
loadingRef,
|
||||||
|
openDirectiveLoading,
|
||||||
|
...toRefs(compState),
|
||||||
|
};
|
||||||
|
},
|
||||||
|
});
|
||||||
|
</script>
|
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"compilerOptions": {
|
"compilerOptions": {
|
||||||
"target": "esnext",
|
"target": "es2016",
|
||||||
"module": "esnext",
|
"module": "esnext",
|
||||||
"moduleResolution": "node",
|
"moduleResolution": "node",
|
||||||
"strict": true,
|
"strict": true,
|
||||||
|
@@ -8,7 +8,7 @@ import { createProxy } from './build/vite/proxy';
|
|||||||
import globbyTransform from './build/vite/plugin/transform/globby';
|
import globbyTransform from './build/vite/plugin/transform/globby';
|
||||||
import dynamicImportTransform from './build/vite/plugin/transform/dynamic-import';
|
import dynamicImportTransform from './build/vite/plugin/transform/dynamic-import';
|
||||||
|
|
||||||
import { isDevFn, loadEnv } from './build/utils';
|
import { loadEnv } from './build/utils';
|
||||||
|
|
||||||
import { createRollupPlugin, createVitePlugins } from './build/vite/plugin';
|
import { createRollupPlugin, createVitePlugins } from './build/vite/plugin';
|
||||||
|
|
||||||
@@ -55,7 +55,7 @@ const viteConfig: UserConfig = {
|
|||||||
* Available options are 'terser' or 'esbuild'.
|
* Available options are 'terser' or 'esbuild'.
|
||||||
* @default 'terser'
|
* @default 'terser'
|
||||||
*/
|
*/
|
||||||
minify: isDevFn() ? false : 'terser',
|
minify: 'terser',
|
||||||
/**
|
/**
|
||||||
* Base public path when served in production.
|
* Base public path when served in production.
|
||||||
* @default '/'
|
* @default '/'
|
||||||
|
11
yarn.lock
11
yarn.lock
@@ -25,13 +25,14 @@
|
|||||||
integrity sha512-Fi03PfuUqRs76aI3UWYpP864lkrfPo0hluwGqh7NJdLhvH4iRDc3jbJqZIvRDLHKbXrvAfPPV3+zjUccfFvWOQ==
|
integrity sha512-Fi03PfuUqRs76aI3UWYpP864lkrfPo0hluwGqh7NJdLhvH4iRDc3jbJqZIvRDLHKbXrvAfPPV3+zjUccfFvWOQ==
|
||||||
|
|
||||||
"@ant-design/icons-vue@^5.1.6":
|
"@ant-design/icons-vue@^5.1.6":
|
||||||
version "5.1.6"
|
version "5.1.7"
|
||||||
resolved "https://registry.npmjs.org/@ant-design/icons-vue/-/icons-vue-5.1.6.tgz#af15cbf2375d95199e90166adce4c9f6ad1c17f1"
|
resolved "https://registry.npmjs.org/@ant-design/icons-vue/-/icons-vue-5.1.7.tgz#5f8e26b547c3ecc16c0820152b935e8a44b5fad3"
|
||||||
integrity sha512-1KY04c/0iDM88ICdu6EW2/ZPOrH+FyL0uvR350XnVqvnDiLijdcrRaLzkZgCdBcy7cy5t5+onXKocymndCOdRA==
|
integrity sha512-6UN/FydLs/bHC0WZxgSpdk0Ct8Ejzr7gdOx5sAIULpSprkxoHWiUbzTy8BMmUduImL42YY1L/qtZYJD6pIzmcQ==
|
||||||
dependencies:
|
dependencies:
|
||||||
"@ant-design/colors" "^5.0.0"
|
"@ant-design/colors" "^5.0.0"
|
||||||
"@ant-design/icons-svg" "^4.0.0"
|
"@ant-design/icons-svg" "^4.0.0"
|
||||||
"@babel/runtime" "^7.10.4"
|
"@babel/runtime" "^7.10.4"
|
||||||
|
"@types/lodash" "^4.14.165"
|
||||||
lodash "^4.17.15"
|
lodash "^4.17.15"
|
||||||
|
|
||||||
"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.10.4", "@babel/code-frame@^7.5.5", "@babel/code-frame@^7.8.3":
|
"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.10.4", "@babel/code-frame@^7.5.5", "@babel/code-frame@^7.8.3":
|
||||||
@@ -1420,7 +1421,7 @@
|
|||||||
dependencies:
|
dependencies:
|
||||||
"@types/lodash" "*"
|
"@types/lodash" "*"
|
||||||
|
|
||||||
"@types/lodash@*":
|
"@types/lodash@*", "@types/lodash@^4.14.165":
|
||||||
version "4.14.165"
|
version "4.14.165"
|
||||||
resolved "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.165.tgz#74d55d947452e2de0742bad65270433b63a8c30f"
|
resolved "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.165.tgz#74d55d947452e2de0742bad65270433b63a8c30f"
|
||||||
integrity sha512-tjSSOTHhI5mCHTy/OOXYIhi2Wt1qcbHmuXD1Ha7q70CgI/I71afO4XtLb/cVexki1oVYchpul/TOuu3Arcdxrg==
|
integrity sha512-tjSSOTHhI5mCHTy/OOXYIhi2Wt1qcbHmuXD1Ha7q70CgI/I71afO4XtLb/cVexki1oVYchpul/TOuu3Arcdxrg==
|
||||||
@@ -1959,7 +1960,7 @@ ansi-styles@^4.0.0, ansi-styles@^4.1.0:
|
|||||||
dependencies:
|
dependencies:
|
||||||
color-convert "^2.0.1"
|
color-convert "^2.0.1"
|
||||||
|
|
||||||
ant-design-vue@2.0.0-rc.2:
|
ant-design-vue@^2.0.0-rc.2:
|
||||||
version "2.0.0-rc.2"
|
version "2.0.0-rc.2"
|
||||||
resolved "https://registry.npmjs.org/ant-design-vue/-/ant-design-vue-2.0.0-rc.2.tgz#fd3b4a5a64fccbb53ed488a194317a040de2223e"
|
resolved "https://registry.npmjs.org/ant-design-vue/-/ant-design-vue-2.0.0-rc.2.tgz#fd3b4a5a64fccbb53ed488a194317a040de2223e"
|
||||||
integrity sha512-XA7X/7HHIveiTh41bZWGfoQ2Rys/rqWknK2zzdHwVnfw9ST3v+ciMKH0Uegyn7m14QL/EdUkC8zGsXpiSXqKNQ==
|
integrity sha512-XA7X/7HHIveiTh41bZWGfoQ2Rys/rqWknK2zzdHwVnfw9ST3v+ciMKH0Uegyn7m14QL/EdUkC8zGsXpiSXqKNQ==
|
||||||
|
Reference in New Issue
Block a user