vue 自定义指令
vue 自定义指令,及按钮
自定义指令也像组件那样存在钩子函数:
bind:只调用一次,指令第一次绑定到元素时调用。在这里可以进行一次性的初始化设置
inserted:被绑定元素插入父节点时调用 (仅保证父节点存在,但不一定已被插入文档中)
update:所在组件的 VNode 更新时调用,但是可能发生在其子 VNode更新之前。指令的值可能发生了改变,也可能没有。但是你可以通过比较更新前后的值来忽略不必要的模板更新
componentUpdated:指令所在组件的 VNode 及其子 VNode 全部更新后调用
unbind:只调用一次,指令与元素解绑时调用
钩子函数的参数都有以下:
el:指令所绑定的元素,可以用来直接操作 DOM
binding:一个对象,包含以下 property:
`name`:指令名,不包括 v- 前缀。
`value`:指令的绑定值,例如:v-my-directive="1 + 1" 中,绑定值为 2。
`oldValue`:指令绑定的前一个值,仅在 update 和 componentUpdated 钩子中可用。无论值是否改变都可用。
`expression`:字符串形式的指令表达式。例如 v-my-directive="1 + 1" 中,表达式为 "1 + 1"。
`arg`:传给指令的参数,可选。例如 v-my-directive:xx中,参数为 "xx"。
`modifiers`:一个包含修饰符的对象。例如:v-my-directive.foo.bar 中,修饰符对象为 { foo: true, bar: true }
`vnode`:Vue 编译生成的虚拟节点
`oldVnode`:上一个虚拟节点,仅在 update 和 componentUpdated 钩子中可用
案例:
1.通过v-auth='权限名' ,根据权限来控制是否显示节点
const authList=[]
// 权限列表判断,使用 v-auth='权限名'
Vue.directive('auth', {
inserted: (el, binding) => {
let value = binding.value
if (authList.indexOf(value) == -1) {
el.parentNode.removeChild(el)
}
}
})
2.通过v-look='"suffix"',控制el-input 获取input输入密码时的显示和隐藏:
1) el-input需要传值,例如v-look='"suffix"'
2) 原生input 不需要,例如 v-look,但是input 需要用一个父级元素包裹,
<div v-look><input /></div>
3) 代码使用的是iconfont图标,可以替换成图片,将document.createElement('i')改成 document.createElement('img'),以及obj.setAttribute('class','pointer hw-iconfont icon-biyan') 改成
obj.setAttribute('img',' ')
Vue.directive('look', {
inserted: (el, binding) => {
// 获取节点
let Dom=el
// 当前绑定节点是input
if(el.nodeName=='INPUT'){
Dom=el
}else{
// 绑定节点不是input
Dom=el.querySelector('input')
}
// 获取父级节点
let parentDom=Dom.parentNode
// 获取所有的css
let parentStyle=window.getComputedStyle ? window.getComputedStyle(parentDom,null) : parentDom.currentStyle;
let parentStyleArray=Object.keys(parentStyle).map(n=>parentStyle[n])
// 判断是否存在定位
if(parentStyleArray.indexOf('position')==-1){
parentDom.style.position='relative'
}
// 当前input节点的类型
let ThisDomType=Dom.getAttribute('type')
// 定义id
let id='look'+Math.floor(Math.random()*10000000)
// 切换眼睛图标
function changeIcon(obj,type){
iObj.removeAttribute('class')
// 这里可以替换成图片
if(type=='password'){
// 闭眼
obj.setAttribute('class','pointer hw-iconfont icon-biyan')
}else{
// 睁眼
obj.setAttribute('class','pointer el-icon-view')
}
}
// 创建眼睛节点
var iObj=document.createElement('i');
if(binding.value && binding.value!=''){
iObj.setAttribute('slot',binding.value)
}
iObj.setAttribute('id',id)
changeIcon(iObj,ThisDomType)
iObj.setAttribute('style','position:absolute;top:50%;right:10px;margin-top:-7px;font-size:14px;display:none')
// 添加节点
parentDom.appendChild(iObj)
// 是否执行了点击
let isClick=false
// 焦点离开方法
function blurFn(){
isClick=false
iObj.style.display='none'
}
// 点击眼睛
let clickDom= document.getElementById(id)
// 放在图标上
clickDom.addEventListener('mouseover',function(){
Dom.removeEventListener('blur',blurFn,false)
})
// 离开图标
clickDom.addEventListener('mouseout',function(){
if(isClick){
blurFn()
Dom.addEventListener('blur',blurFn,false)
}else{
Dom.addEventListener('blur',blurFn,false)
}
})
// 图标点击
clickDom.addEventListener('click',function(e){
isClick=true
iObj.style.display='block'
let DomType=Dom.getAttribute('type')
if(DomType=='password'){
Dom.setAttribute('type','text')
changeIcon(iObj,'text')
}else{
Dom.setAttribute('type','password')
changeIcon(iObj,'password')
}
})
// 焦点
Dom.addEventListener('focus',function(){
iObj.style.display='block'
},false)
// 失去焦点
Dom.addEventListener('blur',blurFn,false)
}
})
// 实现关闭浏览器自动填充
Vue.directive('autoComplete', {
inserted: (el, binding) => {
// 获取节点
let Dom=el
// 当前绑定节点是input
if(el.nodeName=='INPUT'){
Dom=el
}else{
// 绑定节点不是input
Dom=el.querySelector('input')
}
if(binding.value=='off'){
const inputType= Dom.getAttribute('type')
if(inputType=='password'){
Dom.setAttribute('autocomplete','new-password')
}else{
Dom.setAttribute('autocomplete','off')
}
Dom.setAttribute('readonly','readonly')
Dom.removeEventListener('blur',blurFn,false)
Dom.removeEventListener('focus',focusFN,false)
const focusFN=()=>{
setTimeout(()=>{
Dom.removeAttribute('readonly')
},0)
}
// 焦点
Dom.addEventListener('focus',focusFN,false)
const blurFn=()=>{
Dom.setAttribute('readonly','readonly')
}
// 失去焦点
Dom.addEventListener('blur',blurFn,false)
}else{
Dom.setAttribute('autocomplete','on')
}
}
})
更多推荐
所有评论(0)