vue中的自定义指令,以及具体使用场景?

背景

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

自定义指令基本用法

vue2全局注册

main.js文件

Vue.directives('focus',{
	bind(el, binding, vnode) {
  		el.focus()
	}
})
vue2局部注册
export default {
  data () {
    return {
     name:'我是名字',
    }
  },
  directives:{
  	test:{
  		// 指令的定义
	    inserted: function (el, binding) {
	       // el为绑定元素,可以对其进行dom操作
	       console.log(binding) // binding 一个对象,包含很多属性
	    },
	    bind: function (el, binding, vnode) {
		    el.innerHTML =binding.value
		}
  	}
  }
}
vue2生命周期
  • bind:只调用一次,指令第一次绑到元素调用,用于初始化
  • inserted:被绑定元素插入父节点时调用
  • update:所在组件vnode更新调用
  • componentUpdate:指令在组件的vnode及子组件的vnode全部更新完调用
  • ubind:只调用一侧,指令解绑
vue3全局注册

main.js文件

import { createApp } from 'vue'
import App from './App.vue'
const app = createApp(App)

app.directive('focus', {
	created(el, binding) {
  		el.style.backgroundColor = binding.value.color;
  		console.log(el, binding.value.color); 
  		//<input type="text" style="background-color: red;"> 'red'
	}
})
app.mount('#app')
vue3局部注册
<template>
	<input type="text" v-focus="{ color: 'red' }" />
</template>
<script setup>
const vFocus = {
	created(el, binding) {
		el.style.backgroundColor = binding.value.color;
		console.log(el, binding.value.color); 
        //<input type="text" style="background-color: red;"> 'red'
	},
};
</script>
vue3生命周期
  • created 元素初始化的时候
  • beforeMount 指令绑定到元素后调用 只调用一次
  • mounted 元素插入父级dom调用
  • beforeUpdate 元素被更新之前调用
  • update 这个周期方法被移除 改用updated
  • beforeUnmount 在元素被移除前调用
  • unmounted 指令被移除后调用 只调用一次

使用场景

防抖

防抖:在第一次触发事件时,不立即执行函数,在某个特定的时间之后执行,下一次触发重新计数,计数结束执行函数。可以实现输入框的onchange事件

Vue.directive('debounce', {
    inserted: function (el, binding) {
        let timer, flag;
        el.addEventListener('click', () => {
            if (!flag) {
                flag = true;
                timer && clearTimeout(timer);
                timer = setTimeout(() => {
                    typeof binding.value === 'function' && binding.value();
                    flag = false;
                }, 2000) //可通过指令传值设置计时时间
            }
        })
    }
})

节流

节流(throttle):就是指连续触发事件但是在 n 秒中只执行一次函数。

/** 发送验证码 **/
Vue.directive('throttle', {
    inserted: function (el, binding) {
        let timer, flag;
        el.addEventListener('click', () => {
            if (!flag) {
                flag = true;
                typeof binding.value === 'function' && binding.value();
                timer && clearTimeout(timer);
                timer = setTimeout(() => {
                    flag = false;
                }, 2000)
            }
        })
    }
})

图片懒加载

具体实现代码


<template>
  <div>
  	 <div class="lazy">
      <div class="lazy-li"> <img v-lazyLoad="imgAddress" alt="" /></div>
      <div class="lazy-li"> <img v-lazyLoad="imgAddress" alt="" /></div>
    </div>
  </div>
</template>
<script>
export default {
  directives: { // 局部自定义指令
    LazyLoad:{
    	// IntersectionObserver可以获取到当前的位置信息
		let lazyImageObserver = new IntersectionObserver((entries, observer) => {
      	console.log(observer)
        entries.forEach((entry, index) => {
            console.log(index)
            let lazyImage = entry.target;
            // 相交率,默认是相对于浏览器视窗
            if(entry.intersectionRatio > 0) {
                lazyImage.src = binding.value;
                // 当前图片加载完之后需要去掉监听
                lazyImageObserver.unobserve(lazyImage);
            }
        })
    })
    lazyImageObserver.observe(el);
	}
  },
  data(){
    return{
    }
  },
  methods:{
  }
}
</script>

按钮权限

核心代码

// <button v-permission="'1'">权限按钮1</button>
// main.js
/** 判断是否有权限
export function checkArray (key) {
  let arr = ['1', '2']
  let index = arr.indexOf(key)
  if (index > -1) {
    return true // 有权限
  } else {
    return false // 无权限
  }
}
**/
Vue.directive("permission", {
  inserted (el, binding) {
    let permission = binding.value; // 获取到 v-permission的值
    if (permission) {
    	// checkArray用来判断是否有权限
      	let hasPermission = checkArray(permission);
      	if (!hasPermission) { // 没有权限 移除Dom元素
        	el.parentNode && el.parentNode.removeChild(el);
      	}
    }
  }
});
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值