1.主要思路
这里讲的是
v-loading的区域加载
- 获得使用
v-loading指令的dom(使用targetDom指代); - 将
loading组件插入到targetDom中 - 获取
targetDom的宽高定位等样式,并赋值给loading组件样式,保证loading组件在区域内全覆盖 - 需要注意的是:
loading组件需要脱离文档流,如果targetDom没有定位属性,需要补充上position: relative, 并且loading组件需要决对定位position: absolute
2.文件结构
@/components/VLoading
├─ index.js
└─ v-loading.vue
3.组件使用
3-1.组件注册
//在项目的main.js文件中注册组件
import VLoading from "@/components/VLoading/index.js"
...
Vue.use(VLoading)
3-2.组件使用
<template>
<div v-loading="loading">this is a test</div>
</template>
<script>
export default{
data(){
return {
loading: true
}
},
Mounted(){
window.setTimeout(()=> { this.loading = false })
}
}
</script>
4.组件代码
4-1. v-loading.vue
<template>
<div v-show="visible">加载中...</div>
</template>
<script>
export default{
data(){
return {
visible: true
}
}
}
</script>
<style lang="scss" scoped>
div{
position: absolute;
top: 0;
left:0;
width: 100%;
height: 100%;
z:index: 9999
}
</style>
4-2. index.js
import loadingComponent from "./v-loading.vue"
const renderComponent = (component) => {
//接受组件实例, 返回组件的真实Dom树和组件实例
const Constructor = Vue.extend(component)
const instance = new Constructor()
const dom = instance.$mount().$el
return { instance, dom }
}
export default {
install(Vue){
const { instance, dom } = renderComponent(loadingComponent)
Vue.directive("loading", {
bind(el, binding) {
Vue.nextTick(()=>{
//获取绑定指令的元素的计算样式
const style = window.getComputedStyle(el,null)
if(style.position === "static") el.style.position = "relative"
el.appendChild(dom)
instance.visible = Boolean(binding.value)
el.instance = instance
})
},
update(el, binding){
el.instance.visible = Boolean(binding.value)
}
})
}
}
5. 补充说明
5-1.关于vue插件的问题
import VLoading from "@/components/VLoading/index.js"
Vue.use(VLoading)
//等价于
if(isFunction(Vloading)){
VLoading(Vue)
}else if(isFunction(Vloading?.install)){
VLoading.install(Vue)
}
//所以VLoading需要导出带有install方法的对象,或者一个insatll函数
5-2.关于组件实例化的问题
const renderComponent = (component) => {
// 使用Vue.extend生成组件构造器
const Constructor = Vue.extend(component)
// 生成一个组件实例
const instance = new Constructor()
// 将组件挂载后拿到真实dom
const dom = instance.$mount().$el
...
}