vue自定义指令

vue自定义指令

当我们使用插件的时候,有时候会看到插件上使用v-xxx的用法,例如在使用图片懒加载时,我们可以看到他用了v-lazy的指令,这是怎么做的呢 ?

图片:在这里插入图片描述

这是vue中的自定义指令,Vue-directive,我们可以使用这个自定义指令来做很多效果,例如数据加载时,显示加载的遮罩,当加载完成后,再把这个遮罩框移除,效果如下:

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

这样的效果要如何来做呢,根据vue官网上的用法说明来使用就可以

// main.js
Vue.directive('loading',{
  }
})

我们可以在main.js中写到Vue.directive('loding',{...})

这里第一个参数是loading,也就是要传入的指令,如果要自定义一个v-lazy指令那就写Vue.directive('lazy',{...})

第二个参数我们可以写一个对象,对象中包含以下几种钩子函数,他们分别表示

  • bind:只调用一次,指令第一次绑定到元素时调用。在这里可以进行一次性的初始化设置。
  • inserted:被绑定元素插入父节点时调用 (仅保证父节点存在,但不一定已被插入文档中)。
  • update:所在组件的 VNode 更新时调用,但是可能发生在其子 VNode 更新之前。指令的值可能发生了改变,也可能没有。但是你可以通过比较更新前后的值来忽略不必要的模板更新 (详细的钩子函数参数见下)。
  • componentUpdated:指令所在组件的 VNode 及其子 VNode 全部更新后调用。
  • unbind:只调用一次,指令与元素解绑时调用。

我们这个方法中使用update方法就可以了,让v-loading的初始值为false,当请求数据的时候将它设为true,请求数据完成后再设为false

这样v-loading的状态发生了改变,就会触发自定义指令中的update方法

// main.js
Vue.directive('loading',{
  update(el,binding,vNode,oldVnode){
  }
})

这个方法有4个参数,分别是el,binding,vnode, oldVnode,将它依次打印出来可以看到这些参数

在这里插入图片描述
第一个是绑定的dom元素,第二个参数是一个对象,包含不同的属性,我们在这里可以依据binding.value来判断v-loading中绑定的值,当它为true时,说明正在加载,这时候往body中添加一个遮罩框就可以实现加载中…的效果,当它为false的时候,加载完成,我们再把它移除就可以了。

  • 下面是完整代码
// main.js
Vue.directive('loading',{
  update(el,binding,vNode,oldVnode){
    console.log(el,binding,vNode,oldVnode)
    if(binding.value===true){
      let oDiv = document.createElement('div')
      oDiv.id = 'loadingWrapper'
      oDiv.style = `position:fixed;
        background:rgba(0,0,0,.3);top:0;right:0;
        bottom:0;left:0;color:#fff;z-index:3000;display:flex;
        justify-content:center;align-items:center;`
      oDiv.innerHTML = '加载中...'
      document.body.appendChild(oDiv)
    } else {
      document.body.removeChild(document.getElementById('loadingWrapper'))
    }
  }
})
<template>
  <div id="app">
    <button @click="getData" v-loading="isLoading">加载数据</button>
    <ul>
      <li v-for="item in list" :key="item.id">{{item}}</li>
    </ul>
  </div>
</template>

<script>

export default {
  name: 'App',
  data(){
    return{
      list: [],
      isLoading: false
    }
  },
  methods:{
    getData(){
      this.isLoading = true
      setTimeout(()=>{
        this.list = ['小明,20岁,来自北京','小张,22岁,来自河北','老刘,31岁,来自包头']
        this.isLoading = false
      },1000)
    }
  },
  
}
</script>

<style>

</style>

动态指令参数

到了这里,我们已经完成了指令的使用,如果我们希望自己来定义遮罩的颜色,字体大小,位置等,我们应该怎么做呢,这时候可以借助动态指令参数来完成

v-loading:[argument]

我们可以将原来的代码改写成

// App.vue

<button @click="getData" v-loading[style]="isLoading">加载数据</button>
...省略其他代码...
data(){
  return{
  	style: `position:fixed;z-index:3000;display:flex;
        background:rgba(255,0,0,.3);top:0;right:0;
        bottom:0;left:0;color:#green;font-size:40px;
        justify-content:center;align-items:center;`
  }
}

// main.js
Vue.directive('loading',{
  update(el,binding,vNode,oldVnode){
    console.log(el,binding,vNode,oldVnode)
    if(binding.value===true){
      console.log('jiazai')
      let oDiv = document.createElement('div')
      oDiv.id = 'loadingWrapper'
      oDiv.style = binding.arg
      oDiv.innerHTML = '加载中...'
      document.body.appendChild(oDiv)
    } else {
      document.body.removeChild(document.getElementById('loadingWrapper'))
    }
  }
})

这时候动态传入指令参数就完成了,遮罩的背景变成了红色,字体变大
在这里插入图片描述

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值