Vue中的自定义指令directive

为什么要有自定义指令directive

希望input标签在加载的时候就处于focus的状态

1.使用自定义指令directive之前

敲代码

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

对于简单的DOM处理,获取DOM去处理是可以的

但是这种让输入框自动聚焦的代码是没法复用的

如果还有一个input1呢?就还需要再写一次 this.$refs.input1.focus()

对DOM的一些操作可以通过封装自定义指令来实现DOM逻辑的复用

2.使用自定义指令directive之后

全局的自定义指令

定义一个全局的自定义指令focus

敲代码

const app = Vue.createApp({
    template: `
        <div>


            <input v-focus/>
        </div>
    `
})


app.directive('focus',{
    mounted(el){
        el.focus();
    }
})

const vm = app.mount('#root')

备注

  • 定义了一个叫focus的自定义指令
  • 如果想使用自定指令就v-focus
  • mounted是自定义指令的生命周期函数,它的意思是当指令挂载到DOM上的某个元素并且元素挂载到页面上之后自动执行的函数,执行的时候接收的参数el表示模板中使用v-focus自定义指令的元素
  • mounted钩子函数执行的时候执行这个元素的聚焦

局部的自定义指令

敲代码

// 定义局部的自定义指令
const myDirectives = {
    focus: {
        mounted(el) {
            el.focus();
        }
    }
}
const app = Vue.createApp({
    directives: myDirectives,
    template: `
        <div>
            <input v-focus/>
        </div>
    `
})

// 定义全局的自定义指令
app.directive('focus', {
    mounted(el) {
       el.focus()
    }
})

备注

  • 如果想要使用局部的自定义指令就要在组件中使用directives:xxx引入这个定义好的局部自定义指令

自定义指令中的其他钩子函数

自定义指令中的钩子函数除了mounted之外还有其他的生命周期函数,如

beforeMount:当元素即将挂载到页面时自动触发的函数

mounted:当元素挂载到页面时自动触发的函数

beforeUpdate:当元素重新渲染前自动触发的函数

uodated:当元素重新渲染时自动触发的函数

beforeUnmount:当元素重新渲染前自动触发的函数

unmounted:当元素重新渲染时自动触发的函数

自定义指令v-pos控制元素的位置

1. 初体验

使用自定义指令v-pos的元素,让其距离顶部200px

敲代码

const app = Vue.createApp({




    template: `

        <div>


           <div v-pos="200" class="header">
              <input />

            </div>

        </div>

    `

})

app.directive('pos', {

    mounted(el) {
        el.style.top="200px"
    }

})






const vm = app.mount('#root')

2. 让指令接收额外的参数,如v-pos=400

如果想要让其距离顶部400px呢?

敲代码

const app = Vue.createApp({




    template: `

        <div>


           <div v-pos="400" class="header">
              <input />

            </div>

        </div>

    `

})

app.directive('pos', {

    mounted(el,binding) {
        el.style.top = binding.value + "px"
    }

})






const vm = app.mount('#root')

这样我们就可以自定义元素距离顶部的距离

备注

  • 参数binding.value可以获取到v-pos=400中的值400

3.将v-pos=400中的值400绑定到data中去管理

敲代码

const app = Vue.createApp({




    data() {


        return {


            top: 100


        }



    },



    template: `


        <div>



           <div v-pos="top" class="header">

              <input />



            </div>



        </div>



    `



})




app.directive('pos', {

    mounted(el,binding) {
        el.style.top = binding.value + "px"

    }
})




const vm = app.mount('#root')

当我们修改data中top的值时,发现页面并没有发生变化。因为数据发生变化后,mounted并不会重新的执行

我们可以结合另外一个钩子函数,使用updated钩子函数,当数据发生变化组件要重新渲染的时候自动触发

敲代码

const app = Vue.createApp({




    data() {


        return {


            top: 100


        }



    },



    template: `


        <div>



           <div v-pos="top" class="header">

              <input />



            </div>



        </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')

3.另外一种简写的写法

当自定义指令中只有mountedupdated两个钩子函数,并且这两个函数中的内容是相同的,那么就可以简写成下面这样的函数:

app.directive('pos',(el, binding) => {
    console.log(binding);
    el.style.top = binding.value + "px"
})

4.让指令支持参数和参数的值

可不可以像指令v-on:click那样让自定义指令支持参数v-pos:abc的写法?

敲代码

const app = Vue.createApp({




    data() {


        return {


            top: 100


        }



    },



    template: `


        <div>



           <div v-pos:abc="top" class="header">
              <input />



            </div>



        </div>



    `



    })
    // 简写
    app.directive('pos',(el, binding) => {
      console.log(binding);
      el.style.top = binding.value + "px"
    })



    const vm = app.mount('#root')

运行结果

image.png

我们发现其实这个参数可以通过binding.arg获取到

那么我们就可以使用自定义指令的参数和参数的值binding.argbinding.value做些事情:我们可以使用带参数的自定义使元素不仅可以距离顶部xxx距离,还可以是距离左边/右边xxx距离

敲代码

 const app = Vue.createApp({
    data() {
        return {
            distance: 100
        }



    },



    template: `
        <div>



           <div v-pos:left="distance" class="header">
              <input />



            </div>



        </div>



    `



})




// 简写
app.directive('pos',(el, binding) => {
    console.log(binding);
    el.style[binding.arg] = binding.value + "px"
})




const vm = app.mount('#root')

备注

这里要写成el.style[binding.arg] = binding.value + "px"

不要写成el.style.binding.arg = binding.value + "px"

当然不仅可以做到距离右边还可以做到距离下面、右边、左边,我们只需要修改自定义指令的参数即可

<div v-pos:bottom="distance" class="header"> 
    <input /> 
</div>

<div v-pos:right="distance" class="header"> 
    <input /> 
</div>


<div v-pos:left="distance" class="header"> 
    <input /> 
</div>

© 版权声明
THE END
喜欢就支持一下吧
点赞0

Warning: mysqli_query(): (HY000/3): Error writing file '/tmp/MYVz95JG' (Errcode: 28 - No space left on device) in /www/wwwroot/583.cn/wp-includes/class-wpdb.php on line 2345
admin的头像-五八三
评论 抢沙发
头像
欢迎您留下宝贵的见解!
提交
头像

昵称

图形验证码
取消
昵称代码图片