vue中自定义指令怎么用
发表于:2026-11-02 作者:千家信息网编辑
千家信息网最后更新 2026年11月02日,小编给大家分享一下vue中自定义指令怎么用,希望大家阅读完这篇文章之后都有所收获,下面让我们一起去探讨吧!1、v-drag需求:鼠标拖动元素思路:元素偏移量 = 鼠标滑动后的坐标 - 鼠标初始点击元素
千家信息网最后更新 2026年11月02日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安全错误
数据库的锁怎样保障安全
互联网科技
高科技互联网
互联网科技行业发展
互联网电商科技
新华互联网科技学院
智能科技公司是互联网公司吗
互联网科技社
合肥互联网科技公司
亿策互联网科技
极限挑战互联网科技
易通互联网络科技有限公司
昭通云南众福互联网科技有限公司
南平创想时代互联网科技有限公司
坤平互联网科技
呼和浩特新华互联网科技学院
华夏恒生科技与互联网科技
中科明德北京互联网科技
雨阳互联网卡科技有限公司
扫呗互联网科技有限公司
武汉亿视互联网科技有限公司
华服互联网科技怎么样
互联网科技的发展
广州互联网络科技有限公司
互联网科技大会
互联网 科技服务平台
恒生互联网科技指数跳水
民营互联网公司国防科技
明优互联网科技有限公司
科技大学互联网
广州全民伙伴互联网科技有限公司