vue資料未載入完成前顯示loading遮罩
阿新 • • 發佈:2021-01-22
目的
在前後端分離專案中,由於頁面請求和資料請求並非同步,所以導致頁面和資料不能同時渲染,因此在實際過程中往往採用SSR即服務端渲染或者請求資料時採用遮罩(載入中)的方式提升使用者體驗。
下面我將使用loading遮罩的方式實現更加友好的資料載入
參考
https://codepen.io/bartezic/pen/ByqeNq
效果
程式碼
- 在App.vue中新增一個
<div>
<div>
<div id="appLoading">
<div class='lmask'></div>
</div>
<div id="app">
<router-view v-if="isRouterAlive"/>
</div>
</div>
- 以下是CSS樣式
.lmask {
position: absolute;
height: 100%;
width: 100%;
background-color: #000;
bottom: 0;
left: 0;
right: 0;
top: 0;
z-index: 9999;;
opacity: 0.4;
&.fixed {
position: fixed;
}
&:before {
content: '';
background-color: rgba(0,0,0,0);
border: 5px solid rgba(0,183,229,0.9);
opacity: .9;
border-right: 5px solid rgba(0,0,0,0);
border-left: 5px solid rgba(0,0,0,0);
border-radius: 50px;
box-shadow: 0 0 35px #2187e7;
width: 50px;
height: 50px;
-moz-animation: spinPulse 1s infinite ease-in-out;
-webkit-animation: spinPulse 1s infinite linear;
margin: -25px 0 0 -25px;
position: absolute;
top: 50%;
left: 50%;
}
&:after {
content: '';
background-color: rgba(0,0,0,0);
border: 5px solid rgba(0,183,229,0.9);
opacity: .9;
border-left: 5px solid rgba(0,0,0,0);
border-right: 5px solid rgba(0,0,0,0);
border-radius: 50px;
box-shadow: 0 0 15px #2187e7;
width: 30px;
height: 30px;
-moz-animation: spinoffPulse 1s infinite linear;
-webkit-animation: spinoffPulse 1s infinite linear;
margin: -15px 0 0 -15px;
position: absolute;
top: 50%;
left: 50%;
}
}
@-moz-keyframes spinPulse {
0% {
-moz-transform:rotate(160deg);
opacity: 0;
box-shadow: 0 0 1px #2187e7;
}
50% {
-moz-transform: rotate(145deg);
opacity: 1;
}
100% {
-moz-transform: rotate(-320deg);
opacity: 0;
}
}
@-moz-keyframes spinoffPulse {
0% {
-moz-transform: rotate(0deg);
}
100% {
-moz-transform: rotate(360deg);
}
}
@-webkit-keyframes spinPulse {
0% {
-webkit-transform: rotate(160deg);
opacity: 0;
box-shadow: 0 0 1px #2187e7;
}
50% {
-webkit-transform: rotate(145deg);
opacity: 1;
}
100% {
-webkit-transform: rotate(-320deg);
opacity: 0;
}
}
@-webkit-keyframes spinoffPulse {
0% {
-webkit-transform: rotate(0deg);
}
100% {
-webkit-transform: rotate(360deg);
}
}
- 此時遮罩層顯示,我們需要當App載入完成後取消遮罩層,即display: none
document.getElementById('app').style.display = 'block';
document.getElementById('appLoading').style.display = 'none';
- 如何在我們需要的地方呼叫呢
我採用的方法是寫一個loading和loaded函式,在分別在請求資料前和請求資料完成後呼叫,因為該功能可能會重複的使用,所以將其封裝成為一個可以複用的模組
在App.vue中寫兩個方法:
provide() {
return {
loading: this.loading,
loaded: this.loaded
}
},
methods: {
loading() {
document.getElementById('app').style.display = 'block';
document.getElementById('appLoading').style.display = 'block';
},
loaded() {
document.getElementById('app').style.display = 'block';
document.getElementById('appLoading').style.display = 'none';
}
}
上面將這兩個函式給暴露了出來,在我們需要的地方inject就好
5. 在需要使用的地方呼叫
export default {
inject: ['loading', 'loaded'],
name: "index",
created() {
this.getData()
},
methods: {
getData() {
this.loading()
getUserInfo().then(res => {
this.userInfo = res.data
}).finally(() => {
this.loaded()
})
}
}
}
- 完成
總結
實現思路非常簡單,就是請求資料之前將遮罩顯示,載入資料完成後將遮罩隱藏,解決這個問題肯定有非常多的辦法,如果你有更好的方法,請在評論區留言。