Vue
封装loading
自定义指令
一、前言
在项目中,免不了要请求一些数据,一般都会在数据请求时加上loading
效果,提高用户体验,而且这个可以用在项目的需求地方,所以为了减少代码重复,就可以封装成自定义指令,在需要使用的地方加上就行。
二、实现
1. 编写loading
组件
<template>
<div class="loading-wrap">
<img src="../assets/loading.gif" alt="加载...">
</div>
</template>
<script>
export default {
name: 'Loading'
}
</script>
<style scoped>
.loading-wrap {
position: absolute;
top: 50%;
width: 100%;
transform: translateY(-50%);
}
.loading-wrap img {
width: 100px;
height: 100px;
}
</style>
2. 定义loading
指令
import Vue from 'vue'
// 引入 loading 组件
import Loading from '../components/Loading.vue'
// 定义 loading 指令
const loadingDirective = {
inserted: function(el, binding) {
// 创建 loading 组件构造函数
const LoadingCtor = Vue.extend(Loading)
// new 一个 loading组件实例
const loadingInstance = new LoadingCtor()
// 组件挂载
el.instance = loadingInstance.$mount()
// 传入值为 true 时才展示
if (binding.value) {
// 将组件挂载到绑定指令的元素上
append(el)
}
},
update(el, binding) {
// 值更新时进行操作
if (binding.value !== binding.oldValue) {
binding.value ? append(el) : remove(el)
}
}
}
function append(el) {
el.appendChild(el.instance.$el)
}
function remove(el) {
el.removeChild(el.instance.$el)
}
export default loadingDirective
3. 注册loading
自定义指令
import Vue from 'vue'
import App from './App.vue'
// 引入 loading 自定义指令
import loadingDirective from './directive/loading.js'
Vue.config.productionTip = false
Vue.directive('loading', loadingDirective)
new Vue({
render: h => h(App),
}).$mount('#app')
4. 使用loading
指令
<template>
<div id="app" v-loading="loading">
<img alt="Vue logo" src="./assets/logo.png">
<HelloWorld msg="Welcome to Your Vue.js App"/>
</div>
</template>
<script>
import HelloWorld from './components/HelloWorld.vue'
export default {
name: 'App',
components: {
HelloWorld
},
data() {
return {
fetchData: []
}
},
mounted() {
setTimeout(() => {
this.fetchData = [1, 2, 3, 4, 5]
}, 5000)
},
computed: {
loading() {
return !this.fetchData.length
}
}
}
</script>
<style>
#app {
font-family: Avenir, Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
margin-top: 60px;
}
</style>