最近做項(xiàng)目的時(shí)候,發(fā)現(xiàn)自定義loading組件逐虚,發(fā)現(xiàn)網(wǎng)上的loading組件主要有兩種情況:
1.是組件開發(fā)聋溜,這樣開發(fā)需要在引用的地方都要引入一遍,感覺比較麻煩叭爱。
<template>
<div class="loading">
<img width="24" height="24" src="./loading.gif">
<p class="desc">{{title}}</p>
</div>
</template>
<script type="text/ecmascript-6">
export default {
props: {
title: {
type: String,
default: '正在載入...'
}
}
}
</script>
<style scoped>
.loading{
width: 100%;
text-align: center;
}
.desc{
line-height: 20px;
font-size: 12px;
color: white;
}
</style>
這樣每次使用的時(shí)候
<template>
<div class="music-list">
<loading></loading>
</div>
</template>
<script type="text/ecmascript-6">
import Loading from 'base/loading/loading'
export default {
components: {
Loading
}
}
</script>
2.是使用install注冊(cè)組件(Vue.use()來使用)
import './index.css'
let Loading = {}
// 避免重復(fù)install撮躁,設(shè)立flag
Loading.installed = false
Loading.install = function (Vue) {
if (Loading.installed) return
Vue.prototype.$loading = {}
Vue.prototype.$loading.show = () => {
// 如果頁(yè)面有l(wèi)oading則不繼續(xù)執(zhí)行
if (document.querySelector('#vue-loading')) return
// 1、創(chuàng)建構(gòu)造器买雾,定義loading模板
let LoadingTip = Vue.extend({
template: `<div id="vue-loading">
<div class="loader"></div>
</div>`
})
// 2把曼、創(chuàng)建實(shí)例,掛載到文檔以后的地方
let tpl = new LoadingTip().$mount().$el
// 3漓穿、把創(chuàng)建的實(shí)例添加到body中
document.body.appendChild(tpl)
// 阻止遮罩滑動(dòng)
document.querySelector('#vue-loading').addEventListener('touchmove', function (e) {
e.stopPropagation()
e.preventDefault()
})
Loading.installed = true
}
Vue.prototype.$loading.hide = () => {
let tpl = document.querySelector('#vue-loading')
document.body.removeChild(tpl)
}
}
export default Loading
將該組件導(dǎo)出嗤军,這里就存在一個(gè)關(guān)鍵點(diǎn):install, 只有使用install了晃危,我們?cè)趍ain.js中叙赚,才能夠直接use該組件,而install函數(shù)默認(rèn)自帶一個(gè)參數(shù)Vue僚饭,也就是我們正在使用的Vue對(duì)象纠俭,然后定義loading這一組件,使用$mount()給組件手動(dòng)掛載參數(shù)浪慌,然后將組件插入頁(yè)面中冤荆。
index.css
#vue-loading{
width: 100%;
height: 100%;
position: absolute;
left: 0;
top: 0;
}
#vue-loading .loader{}
position: absolute;
width: 2.5em;
height: 2.5em;
top: calc(50% - 1.25em);
left: calc(50% - 1.25em);
transform: rotate(165deg);
}
#vue-loading .loader:before, #vue-loading .loader:after{
content: '';
position: absolute;
top: 50%;
left: 50%;
display: block;
width: 0.5em;
height: 0.5em;
border-radius: 0.25em;
transform: translate(-50%, -50%);
}
#vue-loading .loader:before{
animation: before 2s infinite;
}
#vue-loading .loader:after{
animation: after 2s infinite;
}
.loading-context{
position: absolute;
width: 100%;
top: calc(50% + 2.25em);
text-align: center;
height: 30px;
line-height: 30px;
}
@keyframes before {
0% {
width: 0.5em;
box-shadow: 1em -0.5em rgba(225, 20, 98, 0.75), -1em 0.5em rgba(111, 202, 220, 0.75);
}
35% {
width: 2.5em;
box-shadow: 0 -0.5em rgba(225, 20, 98, 0.75), 0 0.5em rgba(111, 202, 220, 0.75);
}
70% {
width: 0.5em;
box-shadow: -1em -0.5em rgba(225, 20, 98, 0.75), 1em 0.5em rgba(111, 202, 220, 0.75);
}
100% {
box-shadow: 1em -0.5em rgba(225, 20, 98, 0.75), -1em 0.5em rgba(111, 202, 220, 0.75);
}
}
@keyframes after {
0% {
height: 0.5em;
box-shadow: 0.5em 1em rgba(61, 184, 143, 0.75), -0.5em -1em rgba(233, 169, 32, 0.75);
}
35% {
height: 2.5em;
box-shadow: 0.5em 0 rgba(61, 184, 143, 0.75), -0.5em 0 rgba(233, 169, 32, 0.75);
}
70% {
height: 0.5em;
box-shadow: 0.5em -1em rgba(61, 184, 143, 0.75), -0.5em 1em rgba(233, 169, 32, 0.75);
}
100% {
box-shadow: 0.5em 1em rgba(61, 184, 143, 0.75), -0.5em -1em rgba(233, 169, 32, 0.75);
}
}
使用:
// 在main.js中引入
import loading from "@/base/loading"
// 然后通過 USE方法全局注冊(cè)
Vue.use(Loading)
// 全局調(diào)用
this.$loading.show(options)
this.$loading.hide(options)
但是這種方法,只能在vue實(shí)例存在的頁(yè)面中使用权纤,比如重新封裝ajax钓简,在ajax里添加loading乌妒,這個(gè)時(shí)候往往ajax都是封裝在單獨(dú)的js文件中,此時(shí)外邓,vue實(shí)例不存在撤蚊,就無法使用。故在上面的基礎(chǔ)上改進(jìn)如下版本:
import './index.css'
let installed = false
// 避免重復(fù)install损话,設(shè)立flag
const loading = {
show(context = '') {
if (installed) return
// 如果頁(yè)面有l(wèi)oading則不繼續(xù)執(zhí)行
if (document.querySelector('#vue-loading')) return
// 1侦啸、創(chuàng)建構(gòu)造器,定義loading模板
let divWrapper = document.createElement('div')
divWrapper.setAttribute("id","vue-loading")
let div = document.createElement('div')
div.setAttribute('class','loader')
let span = document.createElement('span')
span.className = 'loading-context'
span.innerHTML = context
divWrapper.appendChild(div)
divWrapper.appendChild(span)
// 3丧枪、把創(chuàng)建的實(shí)例添加到body中
document.body.appendChild(divWrapper)
// 阻止遮罩滑動(dòng)
document.querySelector('#vue-loading').addEventListener('touchmove', function (e) {
e.stopPropagation()
e.preventDefault()
})
installed = true
},
hide() {
let tpl = document.querySelector('#vue-loading')
if(!tpl) return
document.body.removeChild(tpl)
}
}
export default loading
index.css
#vue-loading{
width: 100%;
height: 100%;
position: absolute;
left: 0;
top: 0;
}
#vue-loading .loader{}
position: absolute;
width: 2.5em;
height: 2.5em;
top: calc(50% - 1.25em);
left: calc(50% - 1.25em);
transform: rotate(165deg);
}
#vue-loading .loader:before, #vue-loading .loader:after{
content: '';
position: absolute;
top: 50%;
left: 50%;
display: block;
width: 0.5em;
height: 0.5em;
border-radius: 0.25em;
transform: translate(-50%, -50%);
}
#vue-loading .loader:before{
animation: before 2s infinite;
}
#vue-loading .loader:after{
animation: after 2s infinite;
}
.loading-context{
position: absolute;
width: 100%;
top: calc(50% + 2.25em);
text-align: center;
height: 30px;
line-height: 30px;
}
@keyframes before {
0% {
width: 0.5em;
box-shadow: 1em -0.5em rgba(225, 20, 98, 0.75), -1em 0.5em rgba(111, 202, 220, 0.75);
}
35% {
width: 2.5em;
box-shadow: 0 -0.5em rgba(225, 20, 98, 0.75), 0 0.5em rgba(111, 202, 220, 0.75);
}
70% {
width: 0.5em;
box-shadow: -1em -0.5em rgba(225, 20, 98, 0.75), 1em 0.5em rgba(111, 202, 220, 0.75);
}
100% {
box-shadow: 1em -0.5em rgba(225, 20, 98, 0.75), -1em 0.5em rgba(111, 202, 220, 0.75);
}
}
@keyframes after {
0% {
height: 0.5em;
box-shadow: 0.5em 1em rgba(61, 184, 143, 0.75), -0.5em -1em rgba(233, 169, 32, 0.75);
}
35% {
height: 2.5em;
box-shadow: 0.5em 0 rgba(61, 184, 143, 0.75), -0.5em 0 rgba(233, 169, 32, 0.75);
}
70% {
height: 0.5em;
box-shadow: 0.5em -1em rgba(61, 184, 143, 0.75), -0.5em 1em rgba(233, 169, 32, 0.75);
}
100% {
box-shadow: 0.5em 1em rgba(61, 184, 143, 0.75), -0.5em -1em rgba(233, 169, 32, 0.75);
}
}
使用:
// 在使用的頁(yè)面中引入
import loading from "@/base/loading"
// 使用
loading.show()
loading.hide()
// 也可以在main.js將組將掛載到vue實(shí)例中
Vue.prototype.loading = loading
// 使用
this.$loading.show()
this.$loading.hide()