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

本文介绍了Vue中的自定义指令,包括在Vue2和Vue3中的全局与局部注册方法,以及对应的生命周期。还探讨了自定义指令的实用场景,如实现防抖、节流功能,图片懒加载和控制按钮权限。同时,给出了具体的代码示例来帮助理解。
摘要由CSDN通过智能技术生成

背景

除了核心功能默认内置的指令 (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
    评论
关于Vue自定义指令使用场景,通常是用来处理DOM操作或者DOM事件绑定的。比如,可以通过自定义指令来绑定一些特殊的事件,比如scroll事件、hover事件等等;也可以通过自定义指令来操作DOM元素,比如设置元素的宽高、位置等等。 自定义指令的用法一般是通过Vue.directive()方法来定义一个指令,该方法接收两个参数,第一个参数是指令的名称,第二个参数是一个对象,包含指令的各种配置选项。比如: ``` Vue.directive('my-directive', { bind: function (el, binding, vnode) { // 指令绑定到元素上时的操作 }, update: function (el, binding, vnode, oldVnode) { // 元素更新时的操作 }, unbind: function (el, binding, vnode) { // 指令从元素上解绑时的操作 } }); ``` 关于Vue项目无刷新token续传的实现方式,可以通过在请求拦截器判断token是否过期,如果已经过期,则请求刷新token的接口,获取到新的token后再重新发送请求。代码示例: ``` import axios from 'axios' import router from './router' // 请求拦截器 axios.interceptors.request.use( config => { // 判断token是否过期 if (localStorage.getItem('token') && isTokenExpired(localStorage.getItem('token'))) { // 刷新token return axios.post('/api/refreshToken', { token: localStorage.getItem('token') }).then(res => { // 更新token localStorage.setItem('token', res.data.token) config.headers.Authorization = 'Bearer ' + res.data.token return config }).catch(err => { // 刷新token失败,跳转到登录页 router.push('/login') return Promise.reject(error) }) } else { // token未过期,直接返回config config.headers.Authorization = 'Bearer ' + localStorage.getItem('token') return config } }, error => { return Promise.reject(error) } ) // 判断token是否过期的函数 function isTokenExpired (token) { const payload = JSON.parse(atob(token.split('.')[1])) return Date.now() / 1000 > payload.exp } ``` 关于VueVue.use()注册插件的方式,可以通过在插件对象上定义一个install方法,然后在调用Vue.use()方法时传入该插件对象来注册插件。代码示例: ``` // 定义插件对象 const myPlugin = { install: function (Vue, options) { // 在Vue上注册全局组件或者自定义指令等等 } } // 注册插件 Vue.use(myPlugin) ```
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值