页面loading效果
下午做功能,做了2个loading
一个是条形的loading
一个是转圈的loading
组件内代码
<!--
* @Descripttion: loading集合
* @Author: wangxi
* @Date: 2020-05-08 15:05:54
* @LastEditors: wangxi
* @LastEditTime: 2020-05-08 18:23:50
-->
<template>
<div class="progressbar-loading-wrapper" :class="{active: loading}" :style="{background: bgColor}">
<div v-if="type === 'primary'" class="progressbar"></div>
<div v-else-if="type === 'logo'">
<img class="logo" :src="webLogo" alt height="75" />
<svg viewBox="25 25 50 50" class="circular">
<circle
cx="50"
cy="50"
r="20"
fill="none"
stroke-width="2"
stroke-miterlimit="10"
class="path"
/>
</svg>
</div>
</div>
</template>
<script>
import weblogo from "@/assets/logo-loading.png";
export default {
props: {
type: {
type: String,
default: "primary"
},
loading: {
type: Boolean,
default: false
},
bgColor: {
type: String,
default: "#111113"
}
},
data() {
return {
webLogo: weblogo
};
}
};
</script>
<style lang="scss" scoped>
.progressbar-loading-wrapper {
background-color: $trade-block-color;
position: absolute;
top: 0;
left: 0;
100%;
height: 100%;
z-index: 9;
opacity: 0;
filter: alpha(opacity=0);
pointer-events: none;
transition: opacity 0.2s;
&.active {
pointer-events: all;
opacity: 1;
filter: none;
.progressbar {
transform: scale(1);
opacity: 1;
filter: none;
}
.circular {
opacity: 1;
}
}
.progressbar {
position: absolute;
top: 50%;
left: 50%;
margin: -5px 0 0 -75px;
height: 10px;
150px;
transform: scale(0);
opacity: 0;
filter: alpha(opacity=0);
animation-timing-function: linear;
animation-name: wait-bg;
animation-iteration-count: infinite;
animation-duration: 0.45s;
background-repeat: repeat;
background-position: 0 0;
background-image: url(data:image/png;base64,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TUw6Y29tLmFkb2JlLnhtcAAAAAAAPHg6eG1wbWV0YSB4bWxuczp4PSJhZG9iZTpuczptZXRhLyIgeDp4bXB0az0iWE1QIENvcmUgNS40LjAiPgogICA8cmRmOlJERiB4bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiPgogICAgICA8cmRmOkRlc2NyaXB0aW9uIHJkZjphYm91dD0iIgogICAgICAgICAgICB4bWxuczp0aWZmPSJodHRwOi8vbnMuYWRvYmUuY29tL3RpZmYvMS4wLyIKICAgICAgICAgICAgeG1sbnM6ZXhpZj0iaHR0cDovL25zLmFkb2JlLmNvbS9leGlmLzEuMC8iCiAgICAgICAgICAgIHhtbG5zOmRjPSJodHRwOi8vcHVybC5vcmcvZGMvZWxlbWVudHMvMS4xLyIKICAgICAgICAgICAgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIj4KICAgICAgICAgPHRpZmY6UmVzb2x1dGlvblVuaXQ+MTwvdGlmZjpSZXNvbHV0aW9uVW5pdD4KICAgICAgICAgPHRpZmY6Q29tcHJlc3Npb24+NTwvdGlmZjpDb21wcmVzc2lvbj4KICAgICAgICAgPHRpZmY6WFJlc29sdXRpb24+NzI8L3RpZmY6WFJlc29sdXRpb24+CiAgICAgICAgIDx0aWZmOk9yaWVudGF0aW9uPjE8L3RpZmY6T3JpZW50YXRpb24+CiAgICAgICAgIDx0aWZmOllSZXNvbHV0aW9uPjcyPC90aWZmOllSZXNvbHV0aW9uPgogICAgICAgICA8ZXhpZjpQaXhlbFhEaW1lbnNpb24+NTA8L2V4aWY6UGl4ZWxYRGltZW5zaW9uPgogICAgICAgICA8ZXhpZjpDb2xvclNwYWNlPjE8L2V4aWY6Q29sb3JTcGFjZT4KICAgICAgICAgPGV4aWY6UGl4ZWxZRGltZW5zaW9uPjUwPC9leGlmOlBpeGVsWURpbWVuc2lvbj4KICAgICAgICAgPGRjOnN1YmplY3Q+CiAgICAgICAgICAgIDxyZGY6QmFnLz4KICAgICAgICAgPC9kYzpzdWJqZWN0PgogICAgICAgICA8eG1wOk1vZGlmeURhdGU+MjAxNC0xMS0wNlQwMDoxMToyNTwveG1wOk1vZGlmeURhdGU+CiAgICAgICAgIDx4bXA6Q3JlYXRvclRvb2w+UGl4ZWxtYXRvciAzLjIuMTwveG1wOkNyZWF0b3JUb29sPgogICAgICA8L3JkZjpEZXNjcmlwdGlvbj4KICAgPC9yZGY6UkRGPgo8L3g6eG1wbWV0YT4KpNNNcQAAAPdJREFUaAXd2EsOw0AIA9BMT9X7r3qraZCqSFF+88FglwVb9GRWLrXW9wKeUsoHfGJ5oQ9EICwMKCQKYWHAIJEIGCQaAYFkINwhWQhXSCbCDZKNcIEwIKYhLIgpCBNiGMKGGIIwIrohrIguCDOiGcKOaIIoIB4hKohbiBLiEqKGOIUoIg4QVcQOoozYIOoIgxRb6AkpAf8CsTaZ0ERCkvjVsTBIJMK+CgKJRkAgGQh3SBbCFZKJcINkI1wgDIhpCAtiCsKEGIawIYYgjIhuCCuiC8KMaIawI5ogCohHiAriFqKEuISoIU4hiogDRBWxgygjNog6wiBf8vfHgJj+rHIAAAAASUVORK5CYII=);
border-radius: 10px;
background-color: $primary-color;
transition-delay: 0.2s;
transition: transform 0.3s cubic-bezier(0.18, 0.89, 0.32, 1.28),
opacity 0.3s;
box-shadow: 0 2px 15px rgba(0, 0, 0, 0.2);
pointer-events: none;
}
.logo {
position: absolute;
height: 75px;
75px;
top: 50%;
left: 50%;
margin: -37.5px 0 0 -37.5px;
}
.circular {
animation: rotate 2s linear infinite;
height: 150px;
150px;
top: 50%;
left: 50%;
margin: -75px 0 0 -75px;
transform-origin: center center;
position: absolute;
opacity: 0;
.path {
stroke-dasharray: 1, 200;
stroke-dashoffset: 0;
animation: dash 1.5s ease-in-out infinite;
stroke-linecap: round;
stroke: $primary-color;
}
}
@keyframes rotate {
100% {
transform: rotate(360deg);
}
}
@keyframes dash {
0% {
stroke-dasharray: 1, 200;
stroke-dashoffset: 0;
}
50% {
stroke-dasharray: 89, 200;
stroke-dashoffset: -35px;
}
100% {
stroke-dasharray: 89, 200;
stroke-dashoffset: -124px;
}
}
@keyframes wait-bg {
0% {
background-position: 0 0;
}
to {
background-position: 50px 0;
}
}
}
</style>
使用
注意:需要在使用组件的外层添加
position:relative
的class
//默认开启,ajax回调后设置为false,如果觉得时间太短,可以稍作延迟
holdingloading: true
setTimeout(() => {
this.holdingloading = false
}, 500)
实现Promise
昨天看到的那篇实现Promise
的更全一些,明天看那篇,今天跟着神三元的文章实现了一个基础版的,算是热身了。
小试牛刀
初步实现Promise:
1.实现三种状态:pending
, fulfilled
, rejected
2.能够实现then
方法两种回调函数的处理
//promise.js
class Promise{
//传一个异步函数进来
constructor(excutorCallBack){
this.status = 'pending';
this.value = undefined;
this.fulfillAry = [];
this.rejectedAry = [];
//=>执行Excutor
let resolveFn = result => {
if(this.status !== 'pending') return;
let timer = setTimeout(() => {
this.status = 'fulfilled';
this.value = result;
this.fulfillAry.forEach(item => item(this.value));
}, 0);
};
let rejectFn = reason => {
if(this.status !== 'pending')return;
let timer = setTimeout(() => {
this.status = 'rejected';
this.value = reason;
this.rejectedAry.forEach(item => item(this.value))
})
};
try{
//执行这个异步函数
excutorCallBack(resolveFn, rejectFn);
} catch(err) {
//=>有异常信息按照rejected状态处理
rejectFn(err);
}
}
then(fulfilledCallBack, rejectedCallBack) {
//resolve和reject函数其实一个作为微任务
//因此他们不是立即执行,而是等then调用完成后执行
this.fulfillAry.push(fulfilledCallBack);
this.rejectedAry.push(rejectedCallBack);
//一顿push过后他们被执行
}
}
module.exports = Promise;
测试如下:
let Promise = require('./promise');
//new Promise传入一个方法,参数是resolveFn和rejectFn
//然后执行then,将传入的方法丢到fulfillAry和rejectedAry里
//最后,等待resolve或reject时,执行resolveFn或rejectFn方法,改变状态,循环执行数组里的方法,并返回value
let p1 = new Promise((resolve, reject) => {
setTimeout(() => {
Math.random()<0.5?resolve(100):reject(-100);
}, 1000)
}).then(res => {
console.log(res);
}, err => {
console.log(err);
})
完成链式效果
最大的难点在于链式调用的实现,具体来说就是then
方法的实现。
//then传进两个函数
then(fulfilledCallBack, rejectedCallBack) {
//保证两者为函数
typeof fulfilledCallBack !== 'function' ? fulfilledCallBack = result => result:null;
typeof rejectedCallBack !== 'function' ? rejectedCallBack = reason => {
throw new Error(reason instanceof Error? reason.message:reason);
} : null
//返回新的Promise对象,后面称它为“新Promise”
return new Promise((resolve, reject) => {
//注意这个this指向目前的Promise对象,而不是新的Promise
//再强调一遍,很重要:
//目前的Promise(不是这里return的新Promise)的resolve和reject函数其实一个作为微任务
//因此他们不是立即执行,而是等then调用完成后执行
this.fulfillAry.push(() => {
try {
//把then里面的方法拿过来执行
//执行的目的已经达到
let x = fulfilledCallBack(this.value);
//下面执行之后的下一步,也就是记录执行的状态,决定新Promise如何表现
//如果返回值x是一个Promise对象,就执行then操作
//如果不是Promise,直接调用新Promise的resolve函数,
//新Promise的fulfilAry现在为空,在新Promise的then操作后.新Promise的resolve执行
x instanceof Promise ? x.then(resolve, reject):resolve(x);
}catch(err){
reject(err)
}
});
//以下同理
this.rejectedAry.push(() => {
try {
let x = this.rejectedCallBack(this.value);
x instanceof Promise ? x.then(resolve, reject):resolve(x);
}catch(err){
reject(err)
}
})
}) ;
}
测试用例:
let p1 = new Promise((resolve, reject) => {
setTimeout(() => {
Math.random()<0.5?resolve(100):reject(-100);
}, 1000)
})
let p2 = p1.then(result => {
//执行then返回的是一个新的Promise
return result + 100;
})
let p3 = p2.then(result => {
console.log(result);
}, reason => {
console.log(reason)
})
链式调用的内部流程:
Promise.race(iterable)
race
函数返回一个Promise
,它将与第一个传递的promise
相同的完成方式被完成。它可以是完成(resolves
),也可以是失败(rejects
),这要取决于第一个完成的方式是两个中的哪个。
大白话说就是返回第一个promise的返回结果。
js大数字
今天发现一个问题,明天找下原因,使用bigInt
也不行