当前位置: 首页 > Web前端 > JavaScript

利用Vue自定义指令让你的开发变得更优雅

时间:2023-03-27 16:10:50 JavaScript

使用Vue自定义指令让你的开发更优雅但是这个方法让我产生了一个想法:我可以自己写一个属性来实现这样的功能吗?想了想,发现Vue的指令方式和写属性的方式很相似。在Vue中,我们使用v-ifv-for等模板指令来完成很多工作,Vue也支持自定义属性:constapp=Vue.createApp({})//注册一个全局自定义指令`v-focus`app.directive('focus',{//当绑定元素挂载到DOM中时...mounted(el){//焦点元素el.focus()}})然后就可以使用新的v-focus模板中任意元素上的属性,如下注意:这里除了全局注册,还可以使用本地注册,在实际开发中,可以使用Vue的另一个方便的函数mixin来混合对应的将指令写入要用于实现代码重用的文件中,让我们进入正题。底部安全区适配首先,页面必须在head标签中添加meta标签,并设置viewport-fit=covervalue指令:{safeAreaBottom:{bind(el,binding){constaddHigh=binding.value||0el.setAttribute('style',el.style.cssText+`padding-bottom:calc(${addHigh}+常数(safe-area-inset-bottom));padding-bottom:calc(${addHigh}+环境(安全区域-插图底部));`);}}}使用:

如果设计本身有margin,可以动态适配:
方便吗?再来看看移动端H5会遇到的另一个问题,使用Vue指令来解决。弹窗背景页面不滚动。在移动开发中,当页面弹出滚动窗口时,需要固定背景页面,否则会出现“滚过”的现象。touchScroll:{inserted(){constscrollTop=document.body.scrollTop||文档.documentElement.scrollTop;document.body.style.cssText+='position:fixed;width:100%;top:-'+scrollTop+'px;';},unbind(){constbody=document.body||文档.文档元素;body.style.position='';consttop=body.style.top;document.body.scrollTop=document.documentElement.scrollTop=-parseInt(top,10);body.style.top='';}}是的,我是一个弹窗,当我出现的时候我的背景会被吓到移动
实现一个复制工具有时候我们需要实现“一键复制”的功能,点击这一页。可能大家都用过一个叫vue-clipboard的库。知道了使用说明,实现一个copy不是问题,那就自己写一个vueCopy,为以后的开发项目减少第三方库的使用。首先来看看这个工具是如何使用的:可以看出作者也是使用了说明,所以顺着他的思路做了一个。这里直接上代码。具体思路看注释:clipboard:{bind(el,binding,{context}){const_this=context//使用arg注入回调函数if(binding.arg==='success'){_this.__clipboardSuccess=_this[binding.expression]}elseif(binding.arg==='error'){_this.__clipboardError=_this[binding.expression]}else{//通常,文本被缓存_this.__clipboardValue=binding.value}el.handler=()=>{if(!_this.__clipboardValue){this.__clipboardError&&this.__clipboardError('nocontent')return}if(binding.arg){//这是因为属性已经被使用多次被我们执行多次,所以限制执行次数return}try{consttextarea=document.createElement('textarea')textarea.readOnly='readonly'//禁止输入,readonly防止错误聚焦手机自动唤醒键盘textarea.setAttribute('style','position:fixed;top:-9999px;left:-9999px;')//可见,不可见textarea.value=binding.value文档.body.appendChild(textarea)textarea.select()constresult=document.execCommand('Copy')if(result){_this.__clipboardSuccess&&_this.__clipboardSuccess(binding.value)//这里可以定义成功回调返回的数据}文档。body.removeChild(textarea)}catch(e){this.__clipboardError&&this.__clipboardError(e)}}el.addEventListener('click',el.handler)},componentUpdated(el,{arg,value},{上下文}){//更新值时触发const_this=contextif(!arg){//不要将_this.__clipboardValue=value赋值给注册的回调部分}},unbind(el){el.removeEventListener('click',el.handler)},}简单使用:点击直接复制到剪贴板配合回调使用:表单防止重复提交//设置v-throttle自定义指令Vue.directive('throttle',{bind:(el,binding)=>{letthrottleTime=binding.value;//节流时间if(!throttleTime){//如果用户没有设置节流时间,默认为2sthrottleTime=2000;}letcbFun;el.addEventListener('click',event=>{if(!cbFun){//第一次执行cbFun=setTimeout(()=>{cbFun=null;},throttleTime);}else{event&&event.stopImmediatePropagation();}},true);},});use:Submit图片延迟加载constLazyLoad={//安装方法install(Vue,options){//替换图片加载图片letdefaultSrc=options.default;Vue.directive('lazy',{bind(el,binding){LazyLoad.init(el,binding.value,defaultSrc);},inserted(el){//兼容处理if('IntersectionObserver'inwindow){LazyLoad.observe(el);}else{LazyLoad.listenerScroll(el);}},})},//初始化init(el,val,def){//data-src存储真实的srcel.setAttribute('data-src',val);//设置src为加载图片el.setAttribute('src',def);},//使用IntersectionObserver监控elobserve(el){letio=newIntersectionObserver(entries=>{letrealSrc=el.dataset.src;if(entries[0].isIntersecting){if(realSrc){el.src=realSrc;el.removeAttribute('data-src');}}});io.observe(el);},//监听滚动事件listenerScroll(el){lethandler=LazyLoad.throttle(LazyLoad.load,300);延迟加载。加载(el);window.addEventListener('scroll',()=>{handler(el);});},//加载真实图片load(el){letwindowHeight=document.documentElement.clientHeightletelTop=el.getBoundingClientRect().top;让elBtm=el.getBoundingClientRect().bottom;让realSrc=el.dataset.src;if(elTop-windowHeight<0&&elBtm>0){if(realSrc){el.src=realSrc;el.removeAttribute('data-src');}}},//节流throttle(fn,delay){lettimer;让上一个时间;返回函数(...args){让currTime=Date.now();让上下文=这个;如果(!prevTime)prevTime=currTime;清除超时(计时器);如果(currTime-prevTime>delay){prevTime=currTime;fn.apply(上下文,参数);清除超时(计时器);返回;}timer=setTimeout(function(){prevTime=Date.now();timer=null;fn.apply(context,args);},delay);}}}导出默认的LazyLoad;以上就是文章的全部内容,希望对你有所帮助!觉得文章写得好,可以点赞收藏。也欢迎您关注。我会持续更新更多有用的前端知识和实用技巧。一日茶无味,愿与你共同成长~