vue中自定义指令怎么用
发表于:2025-11-15 作者:千家信息网编辑
千家信息网最后更新 2025年11月15日,小编给大家分享一下vue中自定义指令怎么用,希望大家阅读完这篇文章之后都有所收获,下面让我们一起去探讨吧!1、v-drag需求:鼠标拖动元素思路:元素偏移量 = 鼠标滑动后的坐标 - 鼠标初始点击元素
千家信息网最后更新 2025年11月15日vue中自定义指令怎么用
小编给大家分享一下vue中自定义指令怎么用,希望大家阅读完这篇文章之后都有所收获,下面让我们一起去探讨吧!
1、v-drag
需求:鼠标拖动元素
思路:
元素偏移量 = 鼠标滑动后的坐标 - 鼠标初始点击元素时的坐标 + 初始点击时元素距离可视区域的top、left。
将可视区域作为边界,限制在可视区域里面拖拽。
代码:
Vue.directive('drag', { inserted(el) { let header = el.querySelector('.dialog_header') header.style.cssText += ';cursor:move;' header.onmousedown = function (e) { //获取当前可视区域宽、高 let clientWidth = document.documentElement.clientWidth let clientHeight = document.documentElement.clientHeight //获取自身宽高 let elWidth = el.getBoundingClientRect().width let elHeight = el.getBoundingClientRect().height //获取当前距离可视区域的top、left let elTop = el.getBoundingClientRect().top let elLeft = el.getBoundingClientRect().left //获取点击时候的坐标 let startX = e.pageX let startY = e.pageY _document.onmousemove = function (e) { //元素偏移量 = 鼠标滑动后的坐标 - 鼠标初始点击元素时的坐标 + 初始点击时元素距离可视区域的top、left let moveX = e.pageX - startX + elLeft let moveY = e.pageY - startY + elTop //将可视区域作为边界,限制在可视区域里面拖拽 if ((moveX + elWidth) > clientWidth || moveX < 0 || (moveY + elHeight) > clientHeight || moveY < 0) { return } el.style.cssText += 'top:' + moveY + 'px;left:' + moveX + 'px;' } _document.onmouseup = function () { _document.onmousemove = null _document.onmouseup = null } } }})2、v-wordlimit
需求:后台字段限制了长度,并且区分中英文,中文两个字节,英文一个字节;所以输入框需要限制输入的字数并且区分字节数,且需回显已输入的字数。
思路:
一个字节的正则/[\x00-\xff]/g
创建包裹字数限制的元素,并定位布局在textarea和input框上
分别计算输入的字符一个字节的有enLen个,两个字节的有cnLen个;用来后面字符串截断处理
当输入的字数超过限定的字数,截断处理;substr(0,enLen+cnLen)
接口更新了输入框的值,或者初始化输入框的值,需要回显正确的字节数
代码:
Vue.directive('wordlimit',{ bind(el,binding){ console.log('bind'); let { value } = binding Vue.nextTick(() =>{ //找到输入框是textarea框还是input框 let current = 0 let arr = Array.prototype.slice.call(el.children) for (let i = 0; i < arr.length; i++) { if(arr[i].tagName=='TEXTAREA' || arr[i].tagName=='INPUT'){ current = i } } //更新当前输入框的字节数 el.children[el.children.length-1][xss_clean] = el.children[current].value.replace(/[^\x00-\xff]/g,'**').length +'/'+value//eslint-disable-line }) }, update(el,binding){ console.log('update'); let { value } = binding Vue.nextTick(() =>{ //找到输入框是textarea框还是input框 let current = 0 let arr = Array.prototype.slice.call(el.children) for (let i = 0; i < arr.length; i++) { if(arr[i].tagName=='TEXTAREA' || arr[i].tagName=='INPUT'){ current = i } } //更新当前输入框的字节数 el.children[el.children.length-1][xss_clean] = el.children[current].value.replace(/[^\x00-\xff]/g,'**').length +'/'+value//eslint-disable-line }) }, inserted(el,binding){ console.log('inserted'); let { value } = binding //找到输入框是textarea框还是input框 let current = 0 let arr = Array.prototype.slice.call(el.children) for (let i = 0; i < arr.length; i++) { if(arr[i].tagName=='TEXTAREA' || arr[i].tagName=='INPUT'){ current = i } } //创建包裹字数限制的元素,并定位布局在textarea和input框上 let div = document.createElement('div') if(el.children[current].tagName=='TEXTAREA'){//是textarea,定位在右下角 div.style = 'color:#909399;position:absolute;font-size:12px;bottom:5px;right:10px;' }else{ let styStr = '' if(!el.classList.contains('is-disabled')){//input框不是置灰的状态则添加背景颜色 styStr = 'background:#fff;' } div.style = 'color:#909399;position:absolute;font-size:12px;bottom:2px;right:10px;line-height:28px;height:28px;'+styStr } div[xss_clean] = '0/'+ value el.appendChild(div) el.children[current].style.paddingRight = '60px' el.oninput = () =>{ let val = el.children[current].valueval = val.replace(/[^\x00-\xff]/g,'**') //eslint-disable-line // 字数限制的盒子插入到el后是最后一个元素 el.children[el.children.length-1][xss_clean] = val.length + '/' + value if(val.length>value){ let cnLen = 0 //一个字节的字数 let enLen = 0 //两个字节的字数 if(val.match(/[^**]/g) && val.match(/[^**]/g).length){ enLen = val.match(/[^**]/g).length // 计算一个字节的字数 //一个字节两个字节都有的情况 if((value - val.match(/[^**]/g).length)>0){ cnLen = Math.floor((value - val.match(/[^**]/g).length)/2) }else{ cnLen = 0 } }else{ //全部两个字节的情况 enLen = 0 cnLen = Math.floor(value/2) } if(enLen>value){ enLen = value } //超过限定字节数则截取 el.children[current].value = el.children[current].value.substr(0,enLen+cnLen) //更新当前输入框的字节数 el.children[el.children.length-1][xss_clean] = el.children[current].value.replace(/[^\x00-\xff]/g,'**').length +'/'+value//eslint-disable-line } } },})使用:
3、v-anthor
需求:点击某个元素(通常是标题、副标题之类的),动画滚动到对应的内容块
思路:
定时器使用window.scrollBy
不考虑ie的话,可直接使用 window.scrollBy({ top: ,left:0,behavior:'smooth' })
代码:
Vue.directive('anchor',{ inserted(el,binding){ let { value } = binding let timer = null el.addEventListener('click',function(){ // 当前元素距离可视区域顶部的距离 let currentTop = el.getBoundingClientRect().top animateScroll(currentTop) },false) function animateScroll(currentTop){ if(timer){ clearInterval(timer) } let c = 9 timer = setInterval(() =>{ if(c==0){ clearInterval(timer) } c-- window.scrollBy(0,(currentTop-value)/10) },16.7) } }})使用:
是的
4、v-hasRole
需求:根据系统角色添加或删除相应元素
代码:
Vue.directive('hasRole',{ inserted(el,binding){ let { value } = binding let roles = JSON.parse(sessionStorage.getItem('userInfo')).roleIds if(value && value instanceof Array && value.length>0){ let hasPermission = value.includes(roles) if(!hasPermission){ el[xss_clean] && el[xss_clean].removeChild(el) } }else{ throw new Error(`请检查指令绑定的表达式,正确格式例如 v-hasRole="['admin','reviewer']"`) } }})看完了这篇文章,相信你对"vue中自定义指令怎么用"有了一定的了解,如果想了解更多相关知识,欢迎关注行业资讯频道,感谢各位的阅读!
字节
元素
输入
区域
字数
限制
两个
坐标
鼠标
代码
需求
指令
思路
还是
更新
字符
情况
篇文章
边界
偏移
数据库的安全要保护哪些东西
数据库安全各自的含义是什么
生产安全数据库录入
数据库的安全性及管理
数据库安全策略包含哪些
海淀数据库安全审计系统
建立农村房屋安全信息数据库
易用的数据库客户端支持安全管理
连接数据库失败ssl安全错误
数据库的锁怎样保障安全
微视频网络安全公益宣传
数据库查询执行的两种方法
国家网络安全数据灾备中心
电脑数据库已满
杭州建设智慧工厂软件开发
数据库中显示001
bms数据库修改
网络安全与生活的关系
sql数据库怎么添加两个主键
山东省软件开发公司张潇
添加大数据库快捷键
惠州通讯软件开发优化价格
电商优惠券数据库设置
亚纷互联网科技有限公司
桥西区青云软件开发工作室
三德量热仪数据库如何下载导出
机器人软件开发就业形势
方舟如何建立云服务器
上海网络安全发布
社会网络安全问卷调查
安徽公安网络安全
网络安全类书本推荐
SQL员工数据库
网络安全课前三分钟教育
巨灾数据库
软件开发管理的书
数据库的表id怎么顺序生成
山东东网互联网科技有限公司
政府网络安全的思考
网络安全专项检查背景