开发loading组件
/src/components/Loading/index.vue
<template>
<transition name="u-loading-fade">
<div v-show="visible" class="u-loading-mask">
<div class="u-loading-spinner">
<img src="~@/assets/loading.gif"/>
<p class="u-loading-text">{{ text }}</p>
</div>
</div>
</transition>
</template>
<script>
export default {
data() {
return {
visible: true,
text: ''
}
}
}
</script>
<style lang="scss" scoped>
.u-loading-mask {
position: fixed;
z-index: 9999999;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: rgba($color: #000000, $alpha: .3);
color: #ffffff;
.u-loading-spinner {
width: 100%;
height: 100%;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
}
}
</style>
开发v-loading指令
/src/directives/index.js
import Vue from 'vue';
import LoadingComponent from '@/components/loading';
const LoadingConstructor = Vue.extend(LoadingComponent);
export default() => {
Vue.directive('loading', {
/**
* 只调用一次;指令第一次绑定到元素时调用,可用于初始化设置
* @param {*} el 指令绑定的元素
* @param {*} binding 指令传入的信息{ name: '指令名称', value: '指令绑定的值', arg: 'v-bind:text 对应的text' }
*/
bind(el, binding) {
const instance = new LoadingConstructor({
el: document.createElement('div'),
data: {},
})
el.appendChild(instance.$el)
el.instance = instance
Vue.nextTick(() => {
el.style.setProperty('position', 'relative', 'important')
el.instance.$el.style.setProperty('position', 'absolute', 'important')
el.instance.visible = binding.value
})
},
/**
* 组件的VNode更新时调用
* @param {*} el
* @param {*} binding
*/
update(el, binding) {
if (binding.oldValue !== binding.value) {
el.instance.visible = binding.value
}
},
/**
* 只调用一次;指令与元素解绑是调用
* @param {*} el
*/
unbind(el) {
const loading = el.instance.$el
if (loading.parentNode) {
loading.parentNode.removeChild(loading)
}
el.instance.$destroy()
el.instance = undefined
}
})
}
注册全局指令
/src/main.js
...
import directives from './directives'
Vue.use(directives)
使用loading指令
/src/App.vue(以该页面为例子)
<template>
<div id="app">
...
<div v-loading="visible" class="box">测试loading指令</div>
</div>
</template>
<script>
export default {
name: 'App',
data() {
return {
visible: false,
}
},
mounted() {
this.visible = true
setTimeout(() => {
this.visible = false
}, 3000)
}
}
</script>
<style>
...
</style>