first commit

This commit is contained in:
lingxiao865
2026-02-10 08:05:03 +08:00
commit c5af079d8c
1094 changed files with 97530 additions and 0 deletions

View File

@@ -0,0 +1,49 @@
:: BASE_DOC ::
## API
### Loading Props
name | type | default | description | required
-- | -- | -- | -- | --
custom-style | Object | - | CSS(Cascading Style Sheets) | N
delay | Number | 0 | \- | N
duration | Number | 800 | \- | N
fullscreen | Boolean | false | \- | N
indicator | Boolean | true | \- | N
inherit-color | Boolean | false | \- | N
layout | String | horizontal | options: horizontal/vertical | N
loading | Boolean | true | \- | N
pause | Boolean | false | \- | N
progress | Number | - | \- | N
reverse | Boolean | - | \- | N
size | String | '20px' | \- | N
text | String | - | \- | N
theme | String | circular | options: circular/spinner/dots/custom | N
### Loading Slots
name | Description
-- | --
\- | \-
indicator | \-
text | \-
### Loading External Classes
className | Description
-- | --
t-class | \-
t-class-indicator | \-
t-class-text | \-
### CSS Variables
The component provides the following CSS variables, which can be used to customize styles.
Name | Default Value | Description
-- | -- | --
--td-loading-color | @brand-color | -
--td-loading-full-bg-color | rgba(255, 255, 255, 0.6) | -
--td-loading-text-color | @text-color-primary | -
--td-loading-text-font | @font-body-small | -
--td-loading-z-index | 3500 | -

View File

@@ -0,0 +1,96 @@
---
title: Loading 加载
description: 用于表示页面或操作的加载状态,给予用户反馈的同时减缓等待的焦虑感,由一个或一组反馈动效组成。
spline: message
isComponent: true
---
## 引入
可在 `main.ts` 或在需要使用的页面或组件中引入。
```js
import TLoading from '@tdesign/uniapp/loading/loading.vue';
```
### 纯icon
{{ base }}
### icon加文字横向
{{ horizontal }}
### icon加文字竖向
{{ vertical }}
### 纯文字
{{ text }}
### 加载失败
{{ error }}
### 状态
{{ status }}
### 加载速度
{{ duration }}
### 规格
{{ size }}
## API
### Loading Props
名称 | 类型 | 默认值 | 描述 | 必传
-- | -- | -- | -- | --
custom-style | Object | - | 自定义样式 | N
delay | Number | 0 | 延迟显示加载效果的时间,用于防止请求速度过快引起的加载闪烁,单位:毫秒 | N
duration | Number | 800 | 加载动画执行完成一次的时间,单位:毫秒 | N
fullscreen | Boolean | false | 是否显示为全屏加载 | N
indicator | Boolean | true | 加载指示符,值为 true 显示默认指示符,值为 false 则不显示,也可以自定义指示符 | N
inherit-color | Boolean | false | 是否继承父元素颜色 | N
layout | String | horizontal | 对齐方式。可选项horizontal/vertical | N
loading | Boolean | true | 是否处于加载状态 | N
pause | Boolean | false | 是否暂停动画 | N
progress | Number | - | 加载进度 | N
reverse | Boolean | - | 加载动画是否反向 | N
size | String | '20px' | 尺寸示例20px | N
text | String | - | 加载提示文案 | N
theme | String | circular | 加载组件类型。可选项circular/spinner/dots/custom | N
### Loading Slots
名称 | 描述
-- | --
\- | 默认插槽,作用同 `text` 插槽
indicator | 自定义 `indicator` 显示内容
text | 自定义 `text` 显示内容
### Loading External Classes
类名 | 描述
-- | --
t-class | 根节点样式类
t-class-indicator | 指示符样式类
t-class-text | 文本样式类
### CSS Variables
组件提供了下列 CSS 变量,可用于自定义样式。
名称 | 默认值 | 描述
-- | -- | --
--td-loading-color | @brand-color | -
--td-loading-full-bg-color | rgba(255, 255, 255, 0.6) | -
--td-loading-text-color | @text-color-primary | -
--td-loading-text-font | @font-body-small | -
--td-loading-z-index | 3500 | -

View File

@@ -0,0 +1,203 @@
.t-loading {
display: inline-flex;
align-items: center;
justify-content: center;
}
.t-loading--fullscreen {
position: fixed;
display: flex;
align-items: center;
vertical-align: middle;
justify-content: center;
top: 0;
left: 0;
width: 100%;
height: 100%;
z-index: var(--td-loading-z-index, 3500);
background-color: var(--td-loading-full-bg-color, rgba(255, 255, 255, 0.6));
}
.t-loading__spinner {
position: relative;
box-sizing: border-box;
width: 100%;
height: 100%;
max-width: 100%;
max-height: 100%;
animation: rotate 0.8s linear infinite;
color: var(--td-loading-color, var(--td-brand-color, var(--td-primary-color-7, #0052d9)));
}
.t-loading__spinner.reverse {
animation-name: rotateReverse;
}
.t-loading__spinner--spinner {
animation-timing-function: steps(12);
color: var(--td-text-color-primary, var(--td-font-gray-1, rgba(0, 0, 0, 0.9)));
}
.t-loading__spinner--spinner .t-loading__dot {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
}
.t-loading__spinner--spinner .t-loading__dot::before {
display: block;
width: 5rpx;
height: 25%;
margin: 0 auto;
background-color: var(--td-loading-color, var(--td-brand-color, var(--td-primary-color-7, #0052d9)));
border-radius: 40%;
content: ' ';
}
.t-loading__spinner--circular .t-loading__circular {
border-radius: 100%;
width: 100%;
height: 100%;
background: conic-gradient(from 180deg at 50% 50%, rgba(255, 255, 255, 0) 0deg, rgba(255, 255, 255, 0) 60deg, currentColor 330deg, rgba(255, 255, 255, 0) 360deg);
mask: radial-gradient(transparent calc(50% - 1rpx), #fff 50%);
/* stylelint-disable-next-line */
-webkit-mask: radial-gradient(transparent calc(50% - 1rpx), #fff 50%);
}
.t-loading__spinner--dots {
display: flex;
justify-content: space-between;
align-items: center;
animation: none;
}
.t-loading__spinner--dots .t-loading__dot {
width: 20%;
height: 20%;
border-radius: 50%;
background-color: var(--td-loading-color, var(--td-brand-color, var(--td-primary-color-7, #0052d9)));
animation-duration: 1.8s;
animation-name: dotting;
animation-timing-function: linear;
animation-iteration-count: infinite;
animation-fill-mode: both;
}
.t-loading__text {
color: var(--td-loading-text-color, var(--td-text-color-primary, var(--td-font-gray-1, rgba(0, 0, 0, 0.9))));
font: var(--td-loading-text-font, var(--td-font-body-small, 24rpx / 40rpx var(--td-font-family, PingFang SC, Microsoft YaHei, Arial Regular)));
}
.t-loading__text--vertical:not(:first-child):not(:empty) {
margin-top: 12rpx;
}
.t-loading__text--horizontal:not(:first-child):not(:empty) {
margin-left: 16rpx;
}
.t-loading--vertical {
flex-direction: column;
}
.t-loading--horizontal {
flex-direction: row;
vertical-align: top;
}
@keyframes t-bar {
0% {
width: 0;
}
50% {
width: 70%;
}
100% {
width: 80%;
}
}
@keyframes t-bar-loaded {
0% {
height: 6rpx;
opacity: 1;
width: 90%;
}
50% {
height: 6rpx;
opacity: 1;
width: 100%;
}
100% {
height: 0;
opacity: 0;
width: 100%;
}
}
.t-loading__dot-1 {
transform: rotate(30deg);
opacity: 0;
}
.t-loading__dot-2 {
transform: rotate(60deg);
opacity: 0.08333333;
}
.t-loading__dot-3 {
transform: rotate(90deg);
opacity: 0.16666667;
}
.t-loading__dot-4 {
transform: rotate(120deg);
opacity: 0.25;
}
.t-loading__dot-5 {
transform: rotate(150deg);
opacity: 0.33333333;
}
.t-loading__dot-6 {
transform: rotate(180deg);
opacity: 0.41666667;
}
.t-loading__dot-7 {
transform: rotate(210deg);
opacity: 0.5;
}
.t-loading__dot-8 {
transform: rotate(240deg);
opacity: 0.58333333;
}
.t-loading__dot-9 {
transform: rotate(270deg);
opacity: 0.66666667;
}
.t-loading__dot-10 {
transform: rotate(300deg);
opacity: 0.75;
}
.t-loading__dot-11 {
transform: rotate(330deg);
opacity: 0.83333333;
}
.t-loading__dot-12 {
transform: rotate(360deg);
opacity: 0.91666667;
}
@keyframes rotate {
from {
transform: rotate(0deg);
}
to {
transform: rotate(360deg);
}
}
@keyframes rotateReverse {
from {
transform: rotate(360deg);
}
to {
transform: rotate(0deg);
}
}
@keyframes dotting {
0% {
opacity: 0.15;
}
1% {
opacity: 0.8;
}
33% {
opacity: 0.8;
}
34% {
opacity: 0.15;
}
100% {
opacity: 0.15;
}
}

View File

@@ -0,0 +1,157 @@
<template>
<view
:style="tools._style([
customStyle,
show ? '' : 'display: none',
inheritColor ? 'color: inherit' : ''
])"
:class="[
tClass,
classPrefix +
' ' + (classPrefix + '--' + layout) +
' ' + (fullscreen ? classPrefix + '--fullscreen' : '')
]"
>
<view
v-if="indicator"
:class="[
tClassIndicator,
classPrefix + '__spinner ' +
classPrefix + '__spinner--' + theme + ' ' + (reverse ? 'reverse' : '')
]"
:style="
'width: ' +tools.addUnit(size) +
'; height: ' + tools.addUnit(size) +
'; ' + (inheritColor ? 'color: inherit;' : '') +
' ' + (indicator ? '' : 'display: none;') +
' ' + (duration ? 'animation-duration: ' + duration / 1000 + 's;' : '') +
' animation-play-state: ' + (pause ? 'paused' : 'running') +
';'
"
:aria-role="ariaRole || 'img'"
:aria-label="ariaLabel || text || '加载中'"
>
<template
v-if="theme === 'spinner'"
>
<view
v-for="(item, index) in 12"
:key="index"
:class="classPrefix + '__dot ' + classPrefix + '__dot-' + index"
/>
</template>
<view
v-if="theme === 'circular'"
:class="classPrefix + '__circular'"
/>
<block v-if="theme === 'dots'">
<view
:class="classPrefix + '__dot'"
:style="
(duration ? 'animation-duration: ' + duration / 1000 + 's; animation-delay:' + 0 + 's;' : '') +
' animation-play-state: ' +
(pause ? 'paused' : 'running') +
';'
"
/>
<view
:class="classPrefix + '__dot'"
:style="
(duration ? 'animation-duration: ' + duration / 1000 + 's; animation-delay:' + (duration * 1) / 3000 + 's;' : '') +
' animation-play-state: ' +
(pause ? 'paused' : 'running') +
';'
"
/>
<view
:class="classPrefix + '__dot'"
:style="
(duration ? 'animation-duration: ' + duration / 1000 + 's; animation-delay:' + (duration * 2) / 3000 + 's;' : '') +
' animation-play-state: ' +
(pause ? 'paused' : 'running') +
';'
"
/>
</block>
<slot name="indicator" />
</view>
<view
:class="[tools.cls(classPrefix + '__text', [layout]), tClassText]"
:aria-hidden="indicator"
:aria-label="ariaLabel || text"
>
<block v-if="text">
{{ text }}
</block>
<slot name="text" />
<slot />
</view>
</view>
</template>
<script>
import { uniComponent } from '../common/src/index';
import { prefix } from '../common/config';
import props from './props';
import tools from '../common/utils.wxs';
const name = `${prefix}-loading`;
export default uniComponent({
name,
options: {
multipleSlots: true,
styleIsolation: 'shared',
},
externalClasses: [
`${prefix}-class`,
`${prefix}-class-text`,
`${prefix}-class-indicator`,
],
props: {
...props,
},
data() {
return {
prefix,
classPrefix: name,
show: true,
tools,
};
},
watch: {
loading: {
handler(value) {
const {
delay,
} = this;
if (this.timer) {
clearTimeout(this.timer);
}
if (value && delay) {
this.timer = setTimeout(() => {
this.show = value;
this.timer = null;
}, delay);
} else {
this.show = value;
}
},
immediate: true,
},
},
beforeUnMount() {
clearTimeout(this.timer);
},
methods: {
refreshPage() {
this.$emit('reload');
},
},
});
</script>
<style src="./loading.css" scoped>
</style>

View File

@@ -0,0 +1,68 @@
/* eslint-disable */
/**
* 该文件为脚本自动生成文件,请勿随意修改。如需修改请联系 PMC
* */
import type { TdLoadingProps } from './type';
export default {
/** 延迟显示加载效果的时间,用于防止请求速度过快引起的加载闪烁,单位:毫秒 */
delay: {
type: Number,
default: 0,
},
/** 加载动画执行完成一次的时间,单位:毫秒 */
duration: {
type: Number,
default: 800,
},
/** 是否显示为全屏加载 */
fullscreen: Boolean,
/** 加载指示符,值为 true 显示默认指示符,值为 false 则不显示,也可以自定义指示符 */
indicator: {
type: Boolean,
default: true as TdLoadingProps['indicator'],
},
/** 是否继承父元素颜色 */
inheritColor: Boolean,
/** 对齐方式 */
layout: {
type: String,
default: 'horizontal' as TdLoadingProps['layout'],
validator(val: TdLoadingProps['layout']): boolean {
if (!val) return true;
return ['horizontal', 'vertical'].includes(val);
},
},
/** 是否处于加载状态 */
loading: {
type: Boolean,
default: true,
},
/** 是否暂停动画 */
pause: Boolean,
/** 加载进度 */
progress: {
type: Number,
},
/** 加载动画是否反向 */
reverse: Boolean,
/** 尺寸示例20px */
size: {
type: String,
default: '20px',
},
/** 加载提示文案 */
text: {
type: String,
},
/** 加载组件类型 */
theme: {
type: String,
default: 'circular' as TdLoadingProps['theme'],
validator(val: TdLoadingProps['theme']): boolean {
if (!val) return true;
return ['circular', 'spinner', 'dots', 'custom'].includes(val);
},
},
};

View File

@@ -0,0 +1,70 @@
/* eslint-disable */
/**
* 该文件为脚本自动生成文件,请勿随意修改。如需修改请联系 PMC
* */
export interface TdLoadingProps {
/**
* 延迟显示加载效果的时间,用于防止请求速度过快引起的加载闪烁,单位:毫秒
* @default 0
*/
delay?: number;
/**
* 加载动画执行完成一次的时间,单位:毫秒
* @default 800
*/
duration?: number;
/**
* 是否显示为全屏加载
* @default false
*/
fullscreen?: boolean;
/**
* 加载指示符,值为 true 显示默认指示符,值为 false 则不显示,也可以自定义指示符
* @default true
*/
indicator?: boolean;
/**
* 是否继承父元素颜色
* @default false
*/
inheritColor?: boolean;
/**
* 对齐方式
* @default horizontal
*/
layout?: 'horizontal' | 'vertical';
/**
* 是否处于加载状态
* @default true
*/
loading?: boolean;
/**
* 是否暂停动画
* @default false
*/
pause?: boolean;
/**
* 加载进度
*/
progress?: number;
/**
* 加载动画是否反向
*/
reverse?: boolean;
/**
* 尺寸示例20px
* @default '20px'
*/
size?: string;
/**
* 加载提示文案
*/
text?: string;
/**
* 加载组件类型
* @default circular
*/
theme?: 'circular' | 'spinner' | 'dots' | 'custom';
}