vue3 自定义指令 + 自定义组件 v-loading
自定义组件:
<template> <div class="loading"> <div class="loading-content"> <img width="24" height="24" src="./loading.gif"> <p class="desc">{{title}}</p> </div> </div> </template> <script> export default { name: 'loading', data() { return { title: '正在载入...' } }, methods: { setTitle(title) { this.title = title } } } </script> <style lang="scss" scoped> .loading { position: absolute; top: 50%; left: 50%; transform: translate3d(-50%, -50%, 0); .loading-content { text-align: center; .desc { line-height: 20px; font-size: $font-size-small; color: $color-text-l; } } } </style>
自定义指令:
指令封装:
create-loading-like-directive.js
import { createApp } from 'vue'
import { addClass, removeClass } from '@/assets/js/dom'
const relativeCls = 'g-relative'
export default function createLoadingLikeDirective(Comp) {
return {
mounted(el, binding) {
console.log(el, binding)
const app = createApp(Comp)
console.log(app)
const instance = app.mount(document.createElement('div'))
console.log(instance)
const name = Comp.name
if (!el[name]) {
el[name] = {}
}
el[name].instance = instance
const title = binding.arg
if (typeof title !== 'undefined') {
instance.setTitle(title)
}
if (binding.value) {
append(el)
}
},
updated(el, binding) {
const title = binding.arg
const name = Comp.name
if (typeof title !== 'undefined') {
el[name].instance.setTitle(title)
}
if (binding.value !== binding.oldValue) {
console.log(binding.value)
binding.value ? append(el) : remove(el)
}
}
}
function append(el) {
const name = Comp.name
const style = getComputedStyle(el)
console.log(style.position)
if (['absolute', 'fixed', 'relative'].indexOf(style.position) === -1) {
addClass(el, relativeCls)
}
el.appendChild(el[name].instance.$el)
}
function remove(el) {
const name = Comp.name
removeClass(el, relativeCls)
el.removeChild(el[name].instance.$el)
}
}
引用的js dom.js
export function addClass(el, className) { if (!el.classList.contains(className)) { el.classList.add(className) } } export function removeClass(el, className) { el.classList.remove(className) }
自定义组件的封装使用:
directive.js
import Loading from './loading' import createLoadingLikeDirective from '@/assets/js/create-loading-like-directive' const loadingDirective = createLoadingLikeDirective(Loading) export default loadingDirective
在项目使用 :
main.js 引入
createApp(App).use(store).use(router).use(lazyPlugin, { loading: require('@/assets/images/default.png') }).directive('loading', loadingDirective).directive('no-result', noResultDirective).mount('#app')
项目组件使用:
<div class="recommend" v-loading="loading"> 。。。。。。。。。。。 </div>
越努力越幸运

浙公网安备 33010602011771号