Vue3中的自定义指令

277 阅读2分钟

有了前面组件、mixin的基础之后,再来了解今天小编要说的内容,就相对容易一些,今天小编和大家一起学习Vue3中的自定义指令,我们先来看看什么是Vue中的指令。

除了核心功能默认内置的指令 (例如 v-model 和 v-show),Vue 也允许注册自定义指令。注意,在 Vue 中,代码复用和抽象的主要形式是组件。然而,有的情况下,你仍然需要对普通 DOM 元素进行底层操作,这时候就会用到自定义指令

v3.cn.vuejs.org/guide/custo…

这是一段来自Vue3官网的一段话,用来解释什么是自定义指令,自定义指令产生的原因和实际应用
实际开发中,我们可能有这样的需求:页面中加载一个文本框,为了优化用户体验,需要在页面加载完成之后,自动获取焦点,在没有自定义指令的时候,我们会通过原生DOM这样处理这个问题

const app = Vue.createApp({    
    mounted(){        
        this.$refs.input.focus()    
    },    
    template:`<div><input ref="input" /></div>`
})
const vm = app.mount("#root")

下面我们看看在全局注册一个自定义指令是一种什么样的体验

const app = Vue.createApp({    
    template:`<div><input v-focus /></div>`
})
app.directive('focus',{    
    mounted(el){        
        el.focus()    
    }
})
const vm = app.mount("#root")

同样,我们也可以注册一个局部的自定义指令

const directives = {    
    focus: {        
        mounted(el) {            
            el.focus()        
        }    
    }}
const app = Vue.createApp({    
    directives:directives,    
    template: `<div><input v-focus /></div>`
})
const vm = app.mount("#root")

这样,我们最开始的需求是满足了,但是有的时候,我们也想像Vue其他的指令一样,在指令后面添加指定的指,然后根据这个值相应对应的样式或者其他属性。比如我们定义一个v-pos属性,然后元素的距离上边距的距离刚好是这个数字,这个时候,我们可以写成这样

const directives = {    
    focus: {        
        mounted(el) {
            el.focus()        
        }    
    }}
const app = Vue.createApp({    
    data(){    
        return {            
            top:400        
        }    
    },    
    template: `<div v-pos="top" class="header"><input /><button @click="top += 20">修改高度</button></div>`
})
app.directive('pos',{    
    mounted(el, binding){        
        el.style.top = binding.value + 'px'    
    },    
    updated(el, binding){        
        el.style.top = binding.value + 'px'    
    }
})
const vm = app.mount("#root")

解决了一个问题,但是我们并不满足,我们希望根据自定义指令后面的属性不同,调整元素的样式,也就是希望在自定义指令后跟的是left,我们希望就是距离左边的距离,同样,后面跟的是right,就是距离右侧的距离,我们就可以这样

const directives = {    
    focus: {        
        mounted(el) {            
            el.focus()        
        }    
    }}
const app = Vue.createApp({    
    data(){        
        return {            
            distance:400        
        }    
    },    
    template: `<div v-pos:left="distance" class="header"><input /></div>`
})
app.directive('pos',(el, binding) => {    
    console.log(binding, 'binding') // {arg: "abc",value:400}    
    el.style[binding.arg] = binding.value + 'px'
})
const vm = app.mount("#root")

大家还可以扫描二维码,关注我的微信公众号,蜗牛全栈。