-
Notifications
You must be signed in to change notification settings - Fork 83
feat: add Loading component for vue
#330
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
adaex
wants to merge
2
commits into
epic-vue
Choose a base branch
from
feat-vue-loading
base: epic-vue
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
2 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,19 +1,22 @@ | ||
| import badgeDefault from './badge'; | ||
| import cellDefault from './cell'; | ||
| import contextProviderDefault from './context-provider'; | ||
| import loadingDefault from './loading'; | ||
| import notifyDefault from './notify'; | ||
| import transitionDefault from './transition'; | ||
|
|
||
| export * from './badge'; | ||
| export * from './cell'; | ||
| export * from './context-provider'; | ||
| export * from './loading'; | ||
| export * from './notify'; | ||
| export * from './transition'; | ||
|
|
||
| export const allCompInstall = [ | ||
| badgeDefault.install, | ||
| cellDefault.install, | ||
| contextProviderDefault.install, | ||
| loadingDefault.install, | ||
| notifyDefault.install, | ||
| transitionDefault.install, | ||
| ]; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,258 @@ | ||||||||||||||||||||||||||||||||
| <!-- Note: Generated by AI, needs verification --> | ||||||||||||||||||||||||||||||||
| <script lang="ts" setup> | ||||||||||||||||||||||||||||||||
| import { computed, onMounted, onUnmounted, ref, watch } from 'vue'; | ||||||||||||||||||||||||||||||||
| import { isOneOf } from '@arco-design/mobile-utils'; | ||||||||||||||||||||||||||||||||
| import { getPrefixCls } from '../context-provider'; | ||||||||||||||||||||||||||||||||
| import { LoadingProps } from './type'; | ||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
| defineOptions({ | ||||||||||||||||||||||||||||||||
| name: 'Loading', | ||||||||||||||||||||||||||||||||
| }); | ||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
| const props = withDefaults(defineProps<LoadingProps>(), { | ||||||||||||||||||||||||||||||||
| type: 'dot', | ||||||||||||||||||||||||||||||||
| duration: 1000, | ||||||||||||||||||||||||||||||||
| radius: 9, | ||||||||||||||||||||||||||||||||
| stroke: 2, | ||||||||||||||||||||||||||||||||
| filleted: true, | ||||||||||||||||||||||||||||||||
| svgKey: '', | ||||||||||||||||||||||||||||||||
| }); | ||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
| const prefix = getPrefixCls('loading'); | ||||||||||||||||||||||||||||||||
| const statusList = ref<number[]>([]); | ||||||||||||||||||||||||||||||||
| const timerId = ref<number>(-1); | ||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
| // 计算属性 | ||||||||||||||||||||||||||||||||
| const halfCircle = computed(() => Math.PI * props.radius); | ||||||||||||||||||||||||||||||||
| const circlePos = computed(() => 0.5 * props.stroke + props.radius); | ||||||||||||||||||||||||||||||||
| const circleSize = computed(() => props.radius * 2 + props.stroke); | ||||||||||||||||||||||||||||||||
| const actualSvgKey = computed(() => props.svgKey || `${Date.now()}-${Math.random()}`); | ||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
| // 获取样式与浏览器前缀 | ||||||||||||||||||||||||||||||||
| function getStyleWithVendor(style: Record<string, any>) { | ||||||||||||||||||||||||||||||||
| return style; | ||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
| // 动画逻辑 | ||||||||||||||||||||||||||||||||
| function startAnimation() { | ||||||||||||||||||||||||||||||||
| if (props.type === 'dot' && statusList.value.length) { | ||||||||||||||||||||||||||||||||
| const interval = props.duration / statusList.value.length; | ||||||||||||||||||||||||||||||||
| timerId.value = window.setInterval(() => { | ||||||||||||||||||||||||||||||||
| const newList = [...statusList.value]; | ||||||||||||||||||||||||||||||||
| const item = newList.pop(); | ||||||||||||||||||||||||||||||||
| if (item !== undefined) { | ||||||||||||||||||||||||||||||||
| newList.unshift(item); | ||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||
| statusList.value = newList; | ||||||||||||||||||||||||||||||||
| }, interval); | ||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
| function stopAnimation() { | ||||||||||||||||||||||||||||||||
| if (timerId.value >= 0) { | ||||||||||||||||||||||||||||||||
| clearInterval(timerId.value); | ||||||||||||||||||||||||||||||||
| timerId.value = -1; | ||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
| // 初始化状态列表 | ||||||||||||||||||||||||||||||||
| function initStatusList() { | ||||||||||||||||||||||||||||||||
| let newList: number[]; | ||||||||||||||||||||||||||||||||
| if (props.list && props.list.length) { | ||||||||||||||||||||||||||||||||
| newList = props.list; | ||||||||||||||||||||||||||||||||
| } else { | ||||||||||||||||||||||||||||||||
| switch (props.type) { | ||||||||||||||||||||||||||||||||
| case 'spin': | ||||||||||||||||||||||||||||||||
| newList = [1, 0.1, 0.2286, 0.3572, 0.4858, 0.6144, 0.743, 0.8716]; | ||||||||||||||||||||||||||||||||
| break; | ||||||||||||||||||||||||||||||||
| case 'dot': | ||||||||||||||||||||||||||||||||
| newList = [0.2, 0.6, 1]; | ||||||||||||||||||||||||||||||||
| break; | ||||||||||||||||||||||||||||||||
| default: | ||||||||||||||||||||||||||||||||
| newList = []; | ||||||||||||||||||||||||||||||||
| break; | ||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||
| statusList.value = newList; | ||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
| // 渲染函数 | ||||||||||||||||||||||||||||||||
| const renderSpin = () => { | ||||||||||||||||||||||||||||||||
| const len = statusList.value.length; | ||||||||||||||||||||||||||||||||
| return statusList.value.map((opacity, index) => ({ | ||||||||||||||||||||||||||||||||
| opacity, | ||||||||||||||||||||||||||||||||
| transform: `rotate(${index / len}turn)`, | ||||||||||||||||||||||||||||||||
| width: `${props.stroke}px`, | ||||||||||||||||||||||||||||||||
| backgroundColor: props.color, | ||||||||||||||||||||||||||||||||
| borderRadius: props.filleted ? `${props.stroke}px` : undefined, | ||||||||||||||||||||||||||||||||
| })); | ||||||||||||||||||||||||||||||||
| }; | ||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
| const renderDot = () => { | ||||||||||||||||||||||||||||||||
| return statusList.value.map(opacity => ({ | ||||||||||||||||||||||||||||||||
| opacity, | ||||||||||||||||||||||||||||||||
| backgroundColor: props.color, | ||||||||||||||||||||||||||||||||
| })); | ||||||||||||||||||||||||||||||||
| }; | ||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
| // 计算样式 | ||||||||||||||||||||||||||||||||
| const loadingStyle = computed(() => { | ||||||||||||||||||||||||||||||||
| const circleStyle = isOneOf(props.type, ['circle', 'arc']) | ||||||||||||||||||||||||||||||||
| ? { | ||||||||||||||||||||||||||||||||
| width: `${circleSize.value}px`, | ||||||||||||||||||||||||||||||||
| height: `${circleSize.value}px`, | ||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||
| : {}; | ||||||||||||||||||||||||||||||||
| return getStyleWithVendor({ | ||||||||||||||||||||||||||||||||
| animationDuration: `${props.duration}ms`, | ||||||||||||||||||||||||||||||||
| ...circleStyle, | ||||||||||||||||||||||||||||||||
| ...(props.style || {}), | ||||||||||||||||||||||||||||||||
| }); | ||||||||||||||||||||||||||||||||
| }); | ||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
| // 生命周期 | ||||||||||||||||||||||||||||||||
| onMounted(() => { | ||||||||||||||||||||||||||||||||
| initStatusList(); | ||||||||||||||||||||||||||||||||
| startAnimation(); | ||||||||||||||||||||||||||||||||
| }); | ||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
| onUnmounted(() => { | ||||||||||||||||||||||||||||||||
| stopAnimation(); | ||||||||||||||||||||||||||||||||
| }); | ||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
| // 监听器 | ||||||||||||||||||||||||||||||||
| watch([() => props.list, () => props.type], () => { | ||||||||||||||||||||||||||||||||
| stopAnimation(); | ||||||||||||||||||||||||||||||||
| initStatusList(); | ||||||||||||||||||||||||||||||||
| startAnimation(); | ||||||||||||||||||||||||||||||||
| }); | ||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
| watch([() => props.type, () => statusList.value, () => props.duration], () => { | ||||||||||||||||||||||||||||||||
| stopAnimation(); | ||||||||||||||||||||||||||||||||
| startAnimation(); | ||||||||||||||||||||||||||||||||
| }); | ||||||||||||||||||||||||||||||||
|
Comment on lines
+124
to
+133
|
||||||||||||||||||||||||||||||||
| watch([() => props.list, () => props.type], () => { | |
| stopAnimation(); | |
| initStatusList(); | |
| startAnimation(); | |
| }); | |
| watch([() => props.type, () => statusList.value, () => props.duration], () => { | |
| stopAnimation(); | |
| startAnimation(); | |
| }); | |
| watch([() => props.list, () => props.type, () => statusList.value, () => props.duration], () => { | |
| stopAnimation(); | |
| initStatusList(); | |
| startAnimation(); | |
| }); |
36 changes: 36 additions & 0 deletions
36
packages/arcodesign-vue/components/loading/README.en-US.md
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,36 @@ | ||
| <!-- Note: Generated by AI, needs verification --> | ||
|
|
||
| ### Feedback | ||
|
|
||
| # Loading | ||
|
|
||
| Loading component, divided into four types, `circle` is a ring, `arc` is an arc `spin` is a rotation, and `dot` is a dot. All types can be customized in color, ring and arc types can be customized with coil radius and thickness, and rotation and dot types can be customized with internal element transparency. | ||
|
|
||
| ====== | ||
|
|
||
| > Props | ||
|
|
||
| | Property | Description | Type | DefaultValue | | ||
| | -------- | -------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------ | ------------ | | ||
| | style | Custom stylesheet | CSSProperties | - | | ||
| | class | Custom classname | string | - | | ||
| | color | The main color, if you want to use css to control the main color, you can use the public mixin \`\.set\-loading\-color(@color)\` | string | - | | ||
| | type | Loading type | "spin" \| "circle" \| "arc" \| "dot" | "dot" | | ||
| | list | Valid when the type is \`dot\` or \`spin\`, defines the transparency of each element inside | number\[\] | - | | ||
| | duration | A loading cycle in millisecond | number | 1000 | | ||
| | svgKey | Distinguish the \`\<def\>\` content of different svg | string | - | | ||
| | radius | Circle radius, available when type is \`circle\` or \`arc\` | number | 9 | | ||
| | stroke | Circle stroke width, available when type is \`circle\` or \`arc\` or \`spin\` | number | 2 | | ||
| | filleted | Whether the edges are rounded | boolean | true | | ||
|
|
||
| > Refs | ||
|
|
||
| | Property | Description | Type | | ||
| | -------- | ------------------------- | -------------- | | ||
| | dom | The outermost element DOM | HTMLDivElement | | ||
|
|
||
| > LoadingType | ||
|
|
||
| ``` | ||
| "spin" | "circle" | "arc" | "dot" | ||
| ``` |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,36 @@ | ||
| <!-- Note: Generated by AI, needs verification --> | ||
|
|
||
| ### 反馈 | ||
|
|
||
| # 加载 Loading | ||
|
|
||
| 加载中组件,分为四种类型,`circle`为环形,`arc`为弧线,`spin`为旋转,`dot`为圆点。所有类型均可定制颜色,环形和弧线类型可定制线圈半径及粗细,旋转和圆点类型可定制内部元素透明度。 | ||
|
|
||
| ====== | ||
|
|
||
| > 属性/Props | ||
|
|
||
| | 参数 | 描述 | 类型 | 默认值 | | ||
| | -------- | ------------------------------------------------------------------------------------- | ------------------------------------ | ------ | | ||
| | style | 自定义样式 | CSSProperties | - | | ||
| | class | 自定义类名 | string | - | | ||
| | color | 主颜色,如果想使用 css 控制主颜色,可使用公共 mixin \`\.set\-loading\-color(@color)\` | string | - | | ||
| | type | loading 类型 | "spin" \| "circle" \| "arc" \| "dot" | "dot" | | ||
| | list | 当类型为\`dot\`或\`spin\`时有效,定义内部各元素的透明度 | number\[\] | - | | ||
| | duration | 一次 loading 周期的毫秒数 | number | 1000 | | ||
| | svgKey | 区分不同 loading 组件间的\`\<def\>\`内容 | string | - | | ||
| | radius | 圆圈半径,类型为\`circle\`或\`arc\`时可用 | number | 9 | | ||
| | stroke | 圆圈描边宽度,类型为\`circle\`或\`arc\`或\`spin\`时可用 | number | 2 | | ||
| | filleted | 边缘是否为圆角 | boolean | true | | ||
|
|
||
| > 引用/Refs | ||
|
|
||
| | 参数 | 描述 | 类型 | | ||
| | ---- | -------------- | -------------- | | ||
| | dom | 最外层元素 DOM | HTMLDivElement | | ||
|
|
||
| > LoadingType | ||
|
|
||
| ``` | ||
| "spin" | "circle" | "arc" | "dot" | ||
| ``` |
27 changes: 27 additions & 0 deletions
27
packages/arcodesign-vue/components/loading/__demo__/custom-color.md
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,27 @@ | ||
| <!-- Note: Generated by AI, needs verification --> | ||
|
|
||
| ## 自定义加载颜色/透明度 @en{Custom loading color/transparent} | ||
|
|
||
| #### 3 | ||
|
|
||
| 旋转和圆点类型可定制内部元素透明度。@en{Inner element transparency of spin and dot types can be customized.} | ||
|
|
||
| ```vue | ||
| <template> | ||
| <div class="loading-demo-basic"> | ||
| <arco-loading type="arc" color="#ff5722" /> | ||
| <arco-loading type="circle" color="#ff5722" /> | ||
| <arco-loading type="spin" color="#ff5722" :list="[1, 0, 0.1, 0.25, 0.4, 0.55, 0.7, 0.85]" /> | ||
| <arco-loading type="dot" color="#606a78" :list="[0.1, 0.3, 0.5]" /> | ||
| </div> | ||
| </template> | ||
| ``` | ||
|
|
||
| ```less | ||
| .loading-demo-basic { | ||
| .@{prefix}-loading { | ||
| .rem(margin-right, 20); | ||
| vertical-align: middle; | ||
| } | ||
| } | ||
| ``` |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The
getStyleWithVendorfunction currently just returns the input style. Either implement vendor-prefix logic here or remove this stub to simplify the code.