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>
越努力越幸运