尧图建网站 尧图建网站 YAOTU WEB BUILD 免费咨询
ARTICLE DETAIL

资讯详情

深耕网站建设与建站编程的一线实战洞察。

Vue3加载中(Spin)

Vue3加载中(Spin) Vue2加载中Spin可自定义设置以下属性是否为加载中状态spinning类型boolean默认 true加载中尺寸size类型small | middle | large默认 middle描述文案tip类型string | slot默认 undefined加载指示符indicator类型dot | spin-dot | spin-line | ring-circle | ring-rail | dynamic-circle | magic-ring默认 dot指示符颜色color类型string默认 undefined当 indicator: magic-ring 时为外环颜色圆环宽度spinCircleWidth单位是加载指示符宽度的百分比类型number默认 12仅当 indicator: ring-circle | ring-rail 时生效圆环长度百分比 (0100)spinCirclePercent单位是圆环周长的百分比类型number默认 33仅当 indicator: ring-circle | ring-rail 时生效圆环轨道颜色ringRailColor类型string默认 rgba(0, 0, 0, 0.12)仅当 indicator: ring-rail 时生效内环颜色magicRingColor仅当 indicator: magic-ring 时生效类型string默认 undefinedspin-dot 或 spin-line 初始是否旋转rotate类型boolean默认false仅当 indicator: spin-dot | spin-line 时生效spin-dot 或 spin-line 渐变旋转的动画速度speed类型number单位 ms默认 800仅当 indicator: spin-dot | spin-line 时生效效果如下图在线预览①创建加载中组件Spin.vue其中引入使用了以下工具函数监听插槽存在 useSlotsExist获取依赖注入 useInjectscript setup langts import { computed } from vue import { useSlotsExist, useInject } from components/utils export interface Props { spinning?: boolean // 是否为加载中状态 size?: small | middle | large // 加载中尺寸 tip?: string // 描述文案 string | slot indicator?: dot | spin-dot | spin-line | ring-circle | ring-rail | dynamic-circle | magic-ring // 加载指示符 color?: string // 指示符颜色当 indicator: magic-ring 时为外环颜色 spinCircleWidth?: number // 圆环宽度单位是加载指示符宽度的百分比仅当 indicator: ring-circle | ring-rail 时生效 spinCirclePercent?: number // 圆环长度百分比 (0100)单位是圆环周长的百分比仅当 indicator: ring-circle | ring-rail 时生效 ringRailColor?: string // 圆环轨道颜色仅当 indicator: ring-rail 时生效 magicRingColor?: string // 内环颜色仅当 indicator: magic-ring 时生效 rotate?: boolean // spin-dot 或 spin-line 初始是否旋转仅当 indicator: spin-dot | spin-line 时生效 speed?: number // spin-dot 或 spin-line 渐变旋转的动画速度单位 ms仅当 indicator: spin-dot | spin-line 时生效 } const props withDefaults(definePropsProps(), { spinning: true, size: middle, tip: undefined, indicator: dot, color: undefined, spinCircleWidth: 12, spinCirclePercent: 33, ringRailColor: rgba(0, 0, 0, 0.12), magicRingColor: undefined, rotate: false, speed: 800 }) const { colorPalettes } useInject(Spin) // 主题色注入 const slotsExist useSlotsExist([tip]) // 圆环周长 const circlePerimeter computed(() { return (100 - props.spinCircleWidth) * Math.PI }) // 圆环轨道路径指令 const circlePath computed(() { const long 100 - props.spinCircleWidth return M 50,50 m 0,-${long / 2} a ${long / 2},${long / 2} 0 1 1 0,${long} a ${long / 2},${long / 2} 0 1 1 0,-${long} }) const primaryColor computed(() { if (props.color undefined) { return colorPalettes.value[5] } else { return props.color } }) const magicRingColorComputed computed(() { if (props.magicRingColor undefined) { return colorPalettes.value[4] } else { return props.magicRingColor } }) const showTip computed(() { return slotsExist.tip || props.tip }) /script template div :classspin-wrap spin-${size} :style --spin-primary-color: ${primaryColor}; --spin-ring-rail-color: ${ringRailColor}; --spin-magic-ring-color: ${magicRingColorComputed}; --spin-circle-width: ${spinCircleWidth}; --spin-speed: ${speed}ms; div classspin-container v-showspinning div classspin-box div v-ifindicator dot classspin-loading-dot span classdot-item/span span classdot-item/span span classdot-item/span span classdot-item/span /div div v-ifindicator spin-dot classspin-container-box :class{ spin-box-rotate: rotate } div classspin-dot-items span classdot-item/span span classdot-item/span span classdot-item/span span classdot-item/span /div div classspin-dot-items spin-rotate :class{ has-tip: tip } span classdot-item/span span classdot-item/span span classdot-item/span span classdot-item/span /div /div div v-ifindicator spin-line classspin-container-box :class{ spin-box-rotate: rotate } div classspin-line-items span classline-item/span span classline-item/span span classline-item/span span classline-item/span /div div classspin-line-items spin-rotate :class{ has-tip: tip } span classline-item/span span classline-item/span span classline-item/span span classline-item/span /div /div div v-ifindicator ring-circle classspin-ring-circle svg classcircle viewBox0 0 100 100 path :dcirclePath stroke-linecapround classpath :stylestroke-dasharray: ${(spinCirclePercent / 100) * circlePerimeter}px, ${circlePerimeter}px; fill-opacity0 /path /svg /div div v-ifindicator ring-rail classspin-ring-rail svg classcircle viewBox0 0 100 100 path :dcirclePath :strokeringRailColor stroke-linecapround classtrail :stylestroke-dasharray: ${circlePerimeter}px, ${circlePerimeter}px; fill-opacity0 /path path :dcirclePath stroke-linecapround classpath :stylestroke-dasharray: ${(spinCirclePercent / 100) * circlePerimeter}px, ${circlePerimeter}px; fill-opacity0 /path /svg /div div v-ifindicator dynamic-circle classspin-dynamic-circle svg classcircle viewBox0 0 50 50 circle classpath cx25 cy25 r20 fillnone/circle /svg /div div v-ifindicator magic-ring classspin-magic-ring div classouter-ring/div div classinner-ring/div /div div v-ifshowTip classspin-tip :class{ dot-tip: [dot, spin-dot].includes(indicator) } slot nametip{{ tip }}/slot /div /div /div div classspin-content :class{ spin-blur: spinning } slot/slot /div /div /template style langless scoped .spin-wrap { position: relative; height: 100%; width: 100%; display: flex; align-items: center; justify-content: center; .spin-container { position: absolute; top: 0; left: 0; width: 100%; height: 100%; display: flex; align-items: center; justify-content: center; z-index: 9; .spin-box { text-align: center; line-height: 0; .spin-loading-dot { position: relative; display: inline-block; transform: rotate(45deg); animation: loadingDot 1.2s linear infinite; -webkit-animation: loadingDot 1.2s linear infinite; keyframes loadingDot { 100% { transform: rotate(405deg); } } .dot-item { // 单个圆点样式 position: absolute; background: var(--spin-primary-color); border-radius: 50%; opacity: 0.3; animation: loadingDotColor 1s linear infinite alternate; -webkit-animation: loadingDotColor 1s linear infinite alternate; keyframes loadingDotColor { 100% { opacity: 1; } } } .dot-item:first-child { top: 0; left: 0; } .dot-item:nth-child(2) { top: 0; right: 0; animation-delay: 0.4s; -webkit-animation-delay: 0.4s; } .dot-item:nth-child(3) { bottom: 0; right: 0; animation-delay: 0.8s; -webkit-animation-delay: 0.8s; } .dot-item:last-child { bottom: 0; left: 0; animation-delay: 1.2s; -webkit-animation-delay: 1.2s; } } .spin-box-rotate { animation: spinCircle 2.4s ease-in-out; -webkit-animation: spinCircle 2.4s ease-in-out; } .spin-container-box { text-align: center; line-height: 0; position: relative; .spin-dot-items { position: relative; display: inline-block; .dot-item { position: absolute; background: var(--spin-primary-color); border-radius: 50%; } .dot-item:first-child { top: 0; left: 0; opacity: 0.3; animation: spinColor1 var(--spin-speed) linear infinite; -webkit-animation: spinColor1 var(--spin-speed) linear infinite; } .dot-item:nth-child(2) { top: 0; right: 0; opacity: 0.5; animation: spinColor3 var(--spin-speed) linear infinite; -webkit-animation: spinColor3 var(--spin-speed) linear infinite; } .dot-item:nth-child(3) { bottom: 0; right: 0; opacity: 0.7; animation: spinColor5 var(--spin-speed) linear infinite; -webkit-animation: spinColor5 var(--spin-speed) linear infinite; } .dot-item:last-child { bottom: 0; left: 0; opacity: 0.9; animation: spinColor7 var(--spin-speed) linear infinite; -webkit-animation: spinColor7 var(--spin-speed) linear infinite; } } .spin-line-items { position: relative; display: inline-block; .line-item { position: absolute; top: 0; left: 50%; transform: translateX(-50%); background-color: var(--spin-primary-color); } .line-item:first-child { opacity: 0.3; animation: spinColor1 var(--spin-speed) linear infinite; -webkit-animation: spinColor1 var(--spin-speed) linear infinite; } .line-item:nth-child(2) { opacity: 0.5; transform: translateX(-50%) rotate(90deg); animation: spinColor3 var(--spin-speed) linear infinite; -webkit-animation: spinColor3 var(--spin-speed) linear infinite; } .line-item:nth-child(3) { opacity: 0.7; transform: translateX(-50%) rotate(180deg); animation: spinColor5 var(--spin-speed) linear infinite; -webkit-animation: spinColor5 var(--spin-speed) linear infinite; } .line-item:last-child { opacity: 0.9; transform: translateX(-50%) rotate(270deg); animation: spinColor7 var(--spin-speed) linear infinite; -webkit-animation: spinColor7 var(--spin-speed) linear infinite; } } .spin-rotate { position: absolute; left: 0; transform: rotate(45deg); .dot-item, .line-item { :first-child { opacity: 0.4; animation: spinColor2 var(--spin-speed) linear infinite; -webkit-animation: spinColor2 var(--spin-speed) linear infinite; } :nth-child(2) { opacity: 0.6; animation: spinColor4 var(--spin-speed) linear infinite; -webkit-animation: spinColor4 var(--spin-speed) linear infinite; } :nth-child(3) { opacity: 0.8; animation: spinColor6 var(--spin-speed) linear infinite; -webkit-animation: spinColor6 var(--spin-speed) linear infinite; } :last-child { opacity: 1; animation: spinColor8 var(--spin-speed) linear infinite; -webkit-animation: spinColor8 var(--spin-speed) linear infinite; } } } .has-tip { left: 50%; transform: translateX(-50%) rotate(45deg); } keyframes spinColor1 { 0% { opacity: 0.3; } 14.3% { opacity: 1; } 100% { opacity: 0.4; } } keyframes spinColor2 { 0% { opacity: 0.4; } 14.3% { opacity: 0.3; } 28.6% { opacity: 1; } 100% { opacity: 0.5; } } keyframes spinColor3 { 0% { opacity: 0.5; } 28.6% { opacity: 0.3; } 42.8% { opacity: 1; } 100% { opacity: 0.6; } } keyframes spinColor4 { 0% { opacity: 0.6; } 42.8% { opacity: 0.3; } 57.1% { opacity: 1; } 100% { opacity: 0.7; } } keyframes spinColor5 { 0% { opacity: 0.7; } 57.1% { opacity: 0.3; } 71.4% { opacity: 1; } 100% { opacity: 0.8; } } keyframes spinColor6 { 0% { opacity: 0.8; } 71.4% { opacity: 0.3; } 85.7% { opacity: 1; } 100% { opacity: 0.9; } } keyframes spinColor7 { 0% { opacity: 0.9; } 85.7% { opacity: 0.3; } 100% { opacity: 1; } } keyframes spinColor8 { 0% { opacity: 1; } 100% { opacity: 0.3; } } } .spin-ring-circle, .spin-ring-rail { display: inline-block; overflow: hidden; animation: spinCircle 0.8s linear infinite; -webkit-animation: spinCircle 0.8s linear infinite; } .circle { .trail { stroke-width: var(--spin-circle-width); stroke-dashoffset: 0; } .path { stroke: var(--spin-primary-color); stroke-width: var(--spin-circle-width); stroke-dashoffset: 0; } } .spin-dynamic-circle { display: inline-block; animation: spinCircle 2s linear infinite; -webkit-animation: spinCircle 2s linear infinite; .circle { .path { stroke-width: 5; stroke-dasharray: 90, 150; stroke-dashoffset: 0; stroke: var(--spin-primary-color); stroke-linecap: round; animation: loadingDash 1.5s ease-in-out infinite; -webkit-animation: loadingDash 1.5s ease-in-out infinite; keyframes loadingDash { 0% { stroke-dasharray: 1, 200; stroke-dashoffset: 0; } 50% { stroke-dasharray: 90, 150; stroke-dashoffset: -40px; } 100% { stroke-dasharray: 90, 150; stroke-dashoffset: -124px; } } } } } keyframes spinCircle { 100% { transform: rotate(360deg); } } .spin-magic-ring { display: inline-block; position: relative; transform: rotate(45deg); animation: spinRotate 2.5s linear infinite; -webkit-animation: spinRotate 2.5s linear infinite; keyframes spinRotate { 100% { transform: rotate(405deg); } } .outer-ring { position: absolute; width: 100%; height: 100%; border-style: solid; border-color: var(--spin-primary-color); border-radius: 50%; animation: spinOuterRing 1.5s linear infinite; -webkit-animation: spinOuterRing 1.5s linear infinite; keyframes spinOuterRing { 100% { transform: rotateY(360deg); } } } .inner-ring { position: absolute; border-style: solid; border-color: var(--spin-magic-ring-color); border-radius: 50%; animation: spinInnerRing 1.5s linear infinite; -webkit-animation: spinInnerRing 1.5s linear infinite; keyframes spinInnerRing { 0% { transform: rotateY(45deg); } 100% { transform: rotateY(405deg); } } } } .spin-tip { color: var(--spin-primary-color); text-align: center; } } } .spin-content { width: 100%; height: 100%; transition: opacity 0.3s; } .spin-blur { opacity: 0.5; user-select: none; pointer-events: none; } } .spin-small { .spin-container .spin-box { .spin-loading-dot { width: 20px; height: 20px; .dot-item { width: 8px; height: 8px; } } .spin-dot-items { width: 20px; height: 20px; .dot-item { width: 6px; height: 6px; } } .spin-line-items { --line-length: 8px; width: calc(var(--line-length) * 3); height: calc(var(--line-length) * 3); .line-item { transform-origin: 50% calc(var(--line-length) * 1.5); border-radius: var(--line-length); width: calc(var(--line-length) / 2.5); height: var(--line-length); } } .spin-ring-circle, .spin-ring-rail { width: 24px; height: 24px; } .spin-dynamic-circle { width: 26px; height: 26px; } .spin-magic-ring { width: 24px; height: 24px; .outer-ring, .inner-ring { border-width: 3px; } .inner-ring { top: 3px; left: 3px; width: calc(100% - 6px); height: calc(100% - 6px); } } .spin-tip { font-size: 14px; font-weight: 400; line-height: 16px; margin-top: 8px; } .dot-tip { margin-top: 12px; } } } .spin-middle { .spin-container .spin-box { .spin-loading-dot { width: 30px; height: 30px; .dot-item { width: 11px; height: 11px; } } .spin-dot-items { width: 30px; height: 30px; .dot-item { width: 9px; height: 9px; } } .spin-line-items { --line-length: 12px; width: calc(var(--line-length) * 3); height: calc(var(--line-length) * 3); .line-item { transform-origin: 50% calc(var(--line-length) * 1.5); border-radius: var(--line-length); width: calc(var(--line-length) / 3); height: var(--line-length); } } .spin-ring-circle, .spin-ring-rail { width: 36px; height: 36px; } .spin-dynamic-circle { width: 38px; height: 38px; } .spin-magic-ring { width: 36px; height: 36px; .outer-ring, .inner-ring { border-width: 5px; } .inner-ring { top: 5px; left: 5px; width: calc(100% - 10px); height: calc(100% - 10px); } } .spin-tip { font-size: 14px; font-weight: 500; line-height: 18px; margin-top: 12px; } .dot-tip { margin-top: 16px; } } } .spin-large { .spin-container .spin-box { .spin-loading-dot { width: 40px; height: 40px; .dot-item { width: 15px; height: 15px; } } .spin-dot-items { width: 40px; height: 40px; .dot-item { width: 12px; height: 12px; } } .spin-line-items { --line-length: 16px; width: calc(var(--line-length) * 3); height: calc(var(--line-length) * 3); .line-item { transform-origin: 50% calc(var(--line-length) * 1.5); border-radius: var(--line-length); width: calc(var(--line-length) / 3); height: var(--line-length); } } .spin-ring-circle, .spin-ring-rail { width: 48px; height: 48px; } .spin-dynamic-circle { width: 50px; height: 50px; } .spin-magic-ring { width: 48px; height: 48px; .outer-ring, .inner-ring { border-width: 6px; } .inner-ring { top: 6px; left: 6px; width: calc(100% - 12px); height: calc(100% - 12px); } } .spin-tip { font-size: 16px; font-weight: 500; line-height: 20px; margin-top: 16px; } .dot-tip { margin-top: 22px; } } } /style②在要使用的页面引入其中引入使用了以下组件Vue3间距SpaceVue3单选框Radioscript setup langts import Spin from ./Spin.vue import { ref } from vue const spinning ref(true) const sizeOptions [ { label: small, value: small }, { label: middle, value: middle }, { label: large, value: large } ] const size ref(middle) /script template div h1{{ $route.name }} {{ $route.meta.title }}/h1 h2 classmt30 mb10基本使用/h2 Flex aligncenter Loading state:Switch v-modelspinning / /Flex br / Spin stylewidth: 800px :spinningspinning p classspin-content 当 spinning 为 false 时不显示 loading 状态当 spinning 为 true 时显示 loading 效果如果不设置 tip 描述文案时则只有 loading 效果水平垂直居中如果设置了 tip 描述文案则 loading 效果和 tip 描述文案一起水平垂直居中。 /p /Spin h2 classmt30 mb10旋转的点/h2 Spin stylewidth: 800px :spinningspinning indicatorspin-dot p classspin-content 当 spinning 为 false 时不显示 loading 状态当 spinning 为 true 时显示 loading 效果如果不设置 tip 描述文案时则只有 loading 效果水平垂直居中如果设置了 tip 描述文案则 loading 效果和 tip 描述文案一起水平垂直居中。 /p /Spin h2 classmt30 mb10旋转的线/h2 Spin stylewidth: 800px :spinningspinning indicatorspin-line p classspin-content 当 spinning 为 false 时不显示 loading 状态当 spinning 为 true 时显示 loading 效果如果不设置 tip 描述文案时则只有 loading 效果水平垂直居中如果设置了 tip 描述文案则 loading 效果和 tip 描述文案一起水平垂直居中。 /p /Spin h2 classmt30 mb10圆环指示符/h2 Spin stylewidth: 800px :spinningspinning indicatorring-circle p classspin-content 当 spinning 为 false 时不显示 loading 状态当 spinning 为 true 时显示 loading 效果如果不设置 tip 描述文案时则只有 loading 效果水平垂直居中如果设置了 tip 描述文案则 loading 效果和 tip 描述文案一起水平垂直居中。 /p /Spin h2 classmt30 mb10圆环轨道指示符/h2 Spin stylewidth: 800px :spinningspinning indicatorring-rail p classspin-content 当 spinning 为 false 时不显示 loading 状态当 spinning 为 true 时显示 loading 效果如果不设置 tip 描述文案时则只有 loading 效果水平垂直居中如果设置了 tip 描述文案则 loading 效果和 tip 描述文案一起水平垂直居中。 /p /Spin h2 classmt30 mb10动态圆环指示符/h2 Spin stylewidth: 800px :spinningspinning indicatordynamic-circle p classspin-content 当 spinning 为 false 时不显示 loading 状态当 spinning 为 true 时显示 loading 效果如果不设置 tip 描述文案时则只有 loading 效果水平垂直居中如果设置了 tip 描述文案则 loading 效果和 tip 描述文案一起水平垂直居中。 /p /Spin h2 classmt30 mb10双圆环指示符/h2 Spin stylewidth: 800px :spinningspinning indicatormagic-ring p classspin-content 当 spinning 为 false 时不显示 loading 状态当 spinning 为 true 时显示 loading 效果如果不设置 tip 描述文案时则只有 loading 效果水平垂直居中如果设置了 tip 描述文案则 loading 效果和 tip 描述文案一起水平垂直居中。 /p /Spin h2 classmt30 mb10各种大小/h2 Space vertical Space Spin classspin-size :spinningspinning sizesmall / Spin classspin-size :spinningspinning / Spin classspin-size :spinningspinning sizelarge / Spin classspin-size :spinningspinning sizesmall indicatorspin-dot / Spin classspin-size :spinningspinning indicatorspin-dot / Spin classspin-size :spinningspinning sizelarge indicatorspin-dot / Spin classspin-size :spinningspinning sizesmall indicatorspin-line / Spin classspin-size :spinningspinning indicatorspin-line / Spin classspin-size :spinningspinning sizelarge indicatorspin-line / /Space Space Spin classspin-size :spinningspinning sizesmall indicatorring-circle / Spin classspin-size :spinningspinning indicatorring-circle / Spin classspin-size :spinningspinning sizelarge indicatorring-circle / Spin classspin-size :spinningspinning sizesmall indicatorring-rail / Spin classspin-size :spinningspinning indicatorring-rail / Spin classspin-size :spinningspinning sizelarge indicatorring-rail / Spin classspin-size :spinningspinning sizesmall indicatordynamic-circle / Spin classspin-size :spinningspinning indicatordynamic-circle / Spin classspin-size :spinningspinning sizelarge indicatordynamic-circle / /Space Space Spin classspin-size :spinningspinning sizesmall indicatormagic-ring / Spin classspin-size :spinningspinning indicatormagic-ring / Spin classspin-size :spinningspinning sizelarge indicatormagic-ring / /Space /Space h2 classmt30 mb10自定义描述文案/h2 Space vertical Radio :optionssizeOptions v-model:valuesize button button-stylesolid / Space Spin classspin-item :sizesize tip加载中... :spinningspinning / Spin classspin-item :sizesize tip加载中... :spinningspinning indicatorspin-dot / Spin classspin-item :sizesize tip加载中... :spinningspinning indicatorspin-line / Spin classspin-item :sizesize tip加载中... :spinningspinning indicatorring-circle / Spin classspin-item :sizesize tip加载中... :spinningspinning indicatorring-rail / Spin classspin-item :sizesize tip加载中... :spinningspinning indicatordynamic-circle / Spin classspin-item :sizesize :spinningspinning indicatormagic-ring template #tip加载中.../template /Spin /Space /Space h2 classmt30 mb10自定义样式/h2 Space vertical Radio :optionssizeOptions v-model:valuesize button button-stylesolid / Space Spin classspin-item :sizesize color#fadb14 :spinningspinning / Spin classspin-item :sizesize color#fadb14 :spinningspinning indicatorspin-dot / Spin classspin-item :sizesize color#fadb14 :spinningspinning indicatorspin-line / Spin classspin-item :sizesize color#fadb14 :spinningspinning :spin-circle-percent50 indicatorring-circle / Spin classspin-item :sizesize color#fadb14 :spin-circle-percent50 ring-rail-colorrgba(212, 136, 6, 0.6) :spinningspinning indicatorring-rail / Spin classspin-item :sizesize color#fadb14 :spinningspinning indicatordynamic-circle / Spin classspin-item :sizesize color#fadb14 magic-ring-color#ffe58f :spinningspinning indicatormagic-ring / /Space /Space /div /template style langless scoped .spin-content { display: inline-block; border: 1px solid #91d5ff; background-color: #e6f7ff; padding: 30px; } .spin-item { width: 100px; height: 100px; } .spin-size { width: 80px; height: 80px; } /style
返回列表