您的位置:首页 > Web前端 > Vue.js

Vue3中的自定义指令

2021-11-05 18:20 357 查看

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

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

这是一段来自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")

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

 

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: