vue前端頁面數(shù)據(jù)加載添加loading效果的實現(xiàn)
前端頁面數(shù)據(jù)加載添加loading效果
在前端上傳文件或者加載數(shù)據(jù)的時候會有一段等待時間,如果加上一個loading效果會減輕用戶等待的枯燥,這里就來記錄學(xué)習(xí)一下如何實現(xiàn)loading效果。

效果大致如下,樣式我們是可以自定義的。
具體實現(xiàn)
let thisContent = this;
let loading = thisContent.$loading({
lock: true,
text: '上傳中,請稍候...',
spinner: 'el-icon-loading',
background: 'rgba(0, 0, 0, 0.5)'
})
// 中間進行一系列的操作
// 上傳成功后關(guān)閉loading, 并顯示上傳成功
loading.close();
thisC.$message('上傳文件成功');
這樣一個簡單的loading效果就實現(xiàn)了。
全局loading配置
請求的時候 需要一個全局loading來攔截 若是頁面單獨引用的話 就有點繁瑣了 所以需要再全局封裝一個 此時就要明白 再哪里封裝了 先考慮一下 為什么要用
一方面是為了防止重復(fù)操作
另一方面是為了一個加載的效果能夠更明顯
所以 再請求的時候加 就能聯(lián)想到axios攔截器的位置處理了 話不多說 開始擼代碼 全程copy就行了
1 再src/componennts/Spinner下面建立一個index.vue
<template>
<div class="loading-page bg-opacity" :style="{display:hide?'none':'block'}">
<div class="dark" @dblclick="close">
<div class="la-ball-spin-clockwise la-2x">
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
</div>
</div>
</div>
</template>
<script>
export default {
data() {
return {
hide: true
}
},
methods: {
close() {
document.querySelector('.loading-page').style.display = 'none';
}
}
}
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped lang="scss">
.show {
display: block;
}
.hide {
display: none;
}
.loading-page {
background: rgba(0, 0, 0, .65);
display: none;
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
min-height: 100%;
min-width: 100%;
transition: all 1s;
z-index: 20000;
&.hide {
display: none;
}
&.bg-opacity {
background: rgba(0, 0, 0, 0);
}
.dark {
width: 100px;
height: 100px;
border-radius: 10px;
background: rgba(0, 0, 0, .65);
position: absolute;
top: 40%;
left: 50%;
margin-left: -50px;
text-align: center;
img {
width: 70px;
height: 70px;
margin-top: 15px;
}
}
}
.la-ball-spin-clockwise{
width: 64px;
height: 64px;
margin-top: 18px;
margin-left: 18px;
display: block;
font-size: 0;
color: #fff;
position: relative;
box-sizing: border-box;
animation-play-state: running;
}
.la-ball-spin-clockwise>div{
width: 16px;
height: 16px;
margin-top: -8px;
margin-left: -8px;
position: absolute;
border-radius: 100%;
animation: ball-spin-clockwise 1s infinite ease-in-out;
display: inline-block;
float: none;
background-color: currentColor;
border: 0 solid currentColor;
animation-play-state: running;
}
.la-ball-spin-clockwise>div:nth-child(1){
top: 5%;
left: 50%;
webkit-animation-delay: -.875s;
-moz-animation-delay: -.875s;
-o-animation-delay: -.875s;
animation-delay: -.875s;
}
.la-ball-spin-clockwise>div:nth-child(2) {
top: 18.1801948466%;
left: 81.8198051534%;
-webkit-animation-delay: -.75s;
-moz-animation-delay: -.75s;
-o-animation-delay: -.75s;
animation-delay: -.75s;
}
.la-ball-spin-clockwise>div:nth-child(3) {
top: 50%;
left: 95%;
-webkit-animation-delay: -.625s;
-moz-animation-delay: -.625s;
-o-animation-delay: -.625s;
animation-delay: -.625s;
}
.la-ball-spin-clockwise>div:nth-child(4) {
top: 81.8198051534%;
left: 81.8198051534%;
-webkit-animation-delay: -.5s;
-moz-animation-delay: -.5s;
-o-animation-delay: -.5s;
animation-delay: -.5s;
}
.la-ball-spin-clockwise>div:nth-child(5) {
top: 94.9999999966%;
left: 50.0000000005%;
-webkit-animation-delay: -.375s;
-moz-animation-delay: -.375s;
-o-animation-delay: -.375s;
animation-delay: -.375s;
}
.la-ball-spin-clockwise>div:nth-child(6) {
top: 81.8198046966%;
left: 18.1801949248%;
-webkit-animation-delay: -.25s;
-moz-animation-delay: -.25s;
-o-animation-delay: -.25s;
animation-delay: -.25s;
}
.la-ball-spin-clockwise>div:nth-child(7) {
top: 49.9999750815%;
left: 5.0000051215%;
-webkit-animation-delay: -.125s;
-moz-animation-delay: -.125s;
-o-animation-delay: -.125s;
animation-delay: -.125s;
}
.la-ball-spin-clockwise>div:nth-child(8) {
top: 18.179464974%;
left: 18.1803700518%;
-webkit-animation-delay: 0s;
-moz-animation-delay: 0s;
-o-animation-delay: 0s;
animation-delay: 0s;
}
@-webkit-keyframes ball-spin-clockwise{
0%,100%{
opacity:1;
-webkit-transform:scale(1);
transform:scale(1)}
20%{
opacity:1
}
80%{
opacity:0;
-webkit-transform:scale(0);
transform:scale(0)
}
}
@-moz-keyframes ball-spin-clockwise{
0%,100%{
opacity:1;
-moz-transform:scale(1);
transform:scale(1)
}
20%{
opacity:1
}
80%{
opacity:0;
-moz-transform:scale(0);
transform:scale(0)
}
}
@-o-keyframes ball-spin-clockwise{
0%,100%{
opacity:1;
-o-transform:scale(1);
transform:scale(1)
}
20%{
opacity:1
}
80%{
opacity:0;
-o-transform:scale(0);
transform:scale(0)
}
}
@keyframes ball-spin-clockwise{
0%,100%{
opacity:1;
-webkit-transform:scale(1);
-moz-transform:scale(1);
-o-transform:scale(1);
transform:scale(1)
}
20%{
opacity:1
}
80%{
opacity:0;
-webkit-transform:scale(0);
-moz-transform:scale(0);
-o-transform:scale(0);transform:scale(0)
}
}
</style>2 再utils下面tools.js
class Msg {
static loading() {
document.querySelector('.loading-page').style.display = 'block';
}
static hideLoading() {
document.querySelector('.loading-page').style.display = 'none';
}
}
export {
Tools,
Msg
}3 再utils下面建議一個request.js 封裝的axios請求
import axios from 'axios'
import qs from 'qs'
import { MessageBox, Message } from 'element-ui'
import store from '@/store'
import { getToken } from '@/utils/auth'
import router from '@/router'
import {Msg} from '@/utils/tools';
import { removeToken } from '@/utils/auth'
var allResquest = 0;
// create an axios instance
const service = axios.create({
baseURL: process.env.VUE_APP_BASE_API, // api 的 base_url
withCredentials: true, // 跨域請求時發(fā)送 cookies
paramsSerializer: params => { // 查詢字符串中的數(shù)組不使用方括號
return qs.stringify(params, { indices: false })
},
timeout: 15000 // request timeout
})
// request interceptor
service.interceptors.request.use(
config => {
if (store.getters.token) {
config.headers['Authorization'] = 'Bearer ' + getToken()
config.headers['filterMode'] = localStorage.getItem('dataType')
}
config.headers['project'] = "csr"
allResquest = allResquest + 1;
if (config.mask !== true) {
Msg.loading()
}
return config
},
error => {
return Promise.reject(error)
}
)
// response interceptor
service.interceptors.response.use(
/**
* If you want to get information such as headers or status
* Please return response => response
*/
/**
* 下面的注釋為通過在response里,自定義code來標示請求狀態(tài)
* 當code返回如下情況則說明權(quán)限有問題,登出并返回到登錄頁
* 如想通過 XMLHttpRequest 來狀態(tài)碼標識 邏輯可寫在下面error中
* 以下代碼均為樣例,請結(jié)合自生需求加以修改,若不需要,則可刪除
*/
response => {
allResquest = allResquest - 1;
const res = response.data;
if (response.status === 200) {
if (allResquest === 0) {
Msg.hideLoading();
}
// 50008 系統(tǒng)無此賬號
// 50010 賬號禁用
// 50012 賬號或密碼錯誤
// 50013 主賬號被禁用,禁止登錄
// 50014 token失效
// 50015 登錄失敗,無操作權(quán)限,請聯(lián)系系統(tǒng)管理員!
// 50016 驗證碼錯誤
// 429 限流 服務(wù)器擁擠,請稍后再試
// -999 未知錯誤
// 403 無權(quán)限
if (res.code === 50008 || res.code === 50010 || res.code === 50012 || res.code === 50013 ||
res.code === 50016 || res.code === 50015 || res.code === 429 || res.code === -999 || res.code === 403 || res.code === 500) {
Message({
message: res.msg || 'error',
type: 'error',
duration: 5 * 1000,
offset: 0
})
return Promise.reject(res.msg || 'error')
} else if (res.code === 50014) {
if (store.getters.token) {
removeToken()
}
MessageBox.alert( res.msg,'錯誤提示', {
confirmButtonText: '確定',
callback: action => {
store.dispatch('logout')
router.push(`/login`)
}
})
return false
}
return res
}
},
error => {
allResquest = allResquest - 1;
Msg.hideLoading();
Message({
message: '服務(wù)擁擠,請稍后重試!',
type: 'error',
duration: 5 * 1000
})
return Promise.reject(error)
}
)
export default service4 修改app.vue
<template> ? <div id="app"> ? ? <router-view /> ? ? <Spinner></Spinner> ? </div> </template>
<script>
import Spinner from '@/components/Spinner'
export default {
? name: 'App',
? components: {
? ? Spinner
? }
}
</script><style> </style>
以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關(guān)文章
Vue設(shè)置提示和警告彈出框?qū)崙?zhàn)案例
頁面中會有很多時候需要彈窗提示,下面這篇文章主要給大家介紹了關(guān)于Vue設(shè)置提示和警告彈出框的相關(guān)資料,文中通過代碼介紹的非常詳細,需要的朋友可以參考下2024-02-02
Vue.$set 失效的坑 問題發(fā)現(xiàn)及解決方案
這篇文章主要介紹了Vue.$set 失效的坑 問題發(fā)現(xiàn)及解決方案,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-07-07
vue生成二維碼QR?Code的簡單實現(xiàn)方法示例
這篇文章主要為大家介紹了vue生成二維碼QR?Code的實現(xiàn)示例詳情,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2022-04-04
vue跳轉(zhuǎn)頁面打開新窗口,并攜帶與接收參數(shù)方式
這篇文章主要介紹了vue跳轉(zhuǎn)頁面打開新窗口,并攜帶與接收參數(shù)方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-04-04

