vue3 setup语法糖下,vue自定义指令的实现,以及指令全局挂载,自定义v-loading的实现
最近一段时间,在做h5的移动端项目,UI组件库使用的vant,vant组件中的loading实在难用,无法包裹某个块进行loading,也无法对非组件的标签进行loading,所以想着自定义写个指令,挂载全局,通过v-loading的方式实现控制加载,好了,话不多说,vue3的自定义指令实现,和vue2还是有区别的,下面进入正题
首先,写个loading组件:
内容根据自己的需求来,可以是loading的图片,或者自己写的loading样式都行,组件怎么写,此处就不详说了,非本篇博文重点
接着,创建一个js文件,loading.js,用于写指令相关的方法内容:
//引入写好的loading组件 import Loading from '../components/loading.vue'; // 封装,挂载dom节点在 绑定了v-loading的标签dom节点之下的函数 function createLoading(el){ // 创建div标签 const loadingDom = document.createElement('div') // 添加自定义属性作为标识,避免重复loading loadingDom.setAttribute('data-v','loading') // 设置样式,父元素相对定位,子元素绝对定位父元素之上 el.style.position = 'relative' loadingDom.style.width = `${el.offsetWidth}px` loadingDom.style.height = `${el.offsetHeight}px` loadingDom.style.maxHeight = '100vh' loadingDom.style.position = `absolute` loadingDom.style.background = `black` loadingDom.style.display = `flex` loadingDom.style.justifyContent = `center` loadingDom.style.alignItems = `center` loadingDom.style.opacity = '.16' loadingDom.style.top = '0' loadingDom.style.borderRadius = 'inherit' // 创建APP实例,传入loading组件,并且挂载loading组件和创建的标签 const app = createApp(Loading) const instance = app.mount(loadingDom) loadingDom.appendChild(instance.$el) el.appendChild(loadingDom) } // 创建自定义指令 const vLoading = { //mounted的时候,v-loading变量值为true时,加载loading mounted(el,binding) { if(binding.value === true){ createLoading(el) } }, //update的时候 updated(el,binding){ //v-loading 的值为false,并且该节点下最后一个元素是loading时,移除节点 if(binding.value === false && el.lastChild.dataset.v === 'loading'){ el.removeChild(el.lastChild) return } //v-loading 的值为true,并且该节点下没有loading节点时,调用函数,挂载loading if(binding.value === true && el.lastChild.dataset.v !== 'loading'){ createLoading(el) } } } //导出创建好的指令 export default vLoading
到此,指令已经创建好了,上述代码如果是在setup标签中创建的,那么在该页面中,组件或者标签 通过v-loading绑定即可使用,接下来我们挂载全局
//在main入口文件中,引入刚刚创建好的指令 import vLoading from './composables/loading' import {createApp} from "vue"; import "./style.scss"; import App from "./App.vue"; import vLoading from './composables/loading' import router from "./router"; const app = createApp(App); app.use(router); // 调用app.directive,传入自定义指令名,和刚才定义好的指令内容 app.directive('loading',vLoading) app.mount("#app");
接下来是在组件中的使用,通过变量控制显示与否即可
效果图如下,不会截动图,就这样啦
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!