Vue
by WILLIAM CORREA
HTML
<div id="app">
<button @click="showLoading">Loading</button>
<vue-loading inline-template>
<div
v-if="loading"
class="loading"
@click="$loading(false)"
>
<div class="lds-ring">
<div></div>
<div></div>
<div></div>
<div></div>
</div>
</div>
</vue-loading>
</div>
CSS
body {
background: #20262E;
padding: 20px;
font-family: Helvetica;
}
#app {
background: #fff;
border-radius: 4px;
padding: 20px;
transition: all 0.2s;
}
.loading {
position: absolute;
background: rgba(0, 0, 0, 0.6);
height: 100vh;
width: 100vw;
top: 0;
left: 0;
display: flex;
align-items: center;
justify-content: center;
}
.lds-ring {
display: inline-block;
position: relative;
width: 64px;
height: 64px;
}
.lds-ring div {
box-sizing: border-box;
display: block;
position: absolute;
width: 51px;
height: 51px;
margin: 6px;
border: 6px solid #fff;
border-radius: 50%;
animation: lds-ring 1.2s cubic-bezier(0.5, 0, 0.5, 1) infinite;
border-color: #fff transparent transparent transparent;
}
.lds-ring div:nth-child(1) {
animation-delay: -0.45s;
}
.lds-ring div:nth-child(2) {
animation-delay: -0.3s;
}
.lds-ring div:nth-child(3) {
animation-delay: -0.15s;
}
@keyframes lds-ring {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(360deg);
}
}
Vue
Vue.component('vue-loading', {
data: () => ({
loading: false
}),
methods: {
show () {
this.loading = true
},
hide () {
this.loading = false
}
},
created () {
this.$root.$on('loading:show', this.show)
this.$root.$on('loading:hide', this.hide)
},
beforeDestroy () {
this.$root.$off('loading:show')
this.$root.$off('loading:hide')
}
})
Vue.prototype.$loading = function (loading = true) {
if (loading) {
this.$root.$emit('loading:show')
return
}
this.$root.$emit('loading:hide')
}
new Vue({
el: "#app",
methods: {
showLoading () {
this.$loading()
}
}
})