Vue2和Vue3中自定义指令的钩子函数及对应的防抖和节流的简单实现

Vue3

Vue.js的版本更新到了Vue 3之后,对于自定义指令也有所改变。在Vue 2中,我们可以通过bind、inserted、update等钩子函数来控制自定义指令的行为。但是在Vue 3中,这些钩子函数被重命名并放置在不同的位置上。
下面是Vue 3中常用的自定义指令钩子函数及其作用:

beforeMount: 在元素首次挂载前调用,类似于Vue 2中的bind钩子函数。

app.directive('my-directive', {
  beforeMount(el) {
    // 在元素首次挂载前执行的操作
  }
})

mounted: 在元素挂载完成后调用,类似于Vue 2中的inserted钩子函数。

app.directive('my-directive', {
  mounted(el) {
    // 在元素挂载完成后执行的操作
  }
})

updated: 当组件或者DOM发生更新时调用,类似于Vue 2中的update钩子函数。

app.directive('my-directive', {
  updated(el) {
    // DOM更新后执行的操作
  }
})

unmounted: 在元素从页面移除时调用,相当于Vue 2中的unbind钩子函数。

app.directive('my-directive', {
  unmounted(el) {
    // 元素从页面移除时执行的操作
  }
})

需要注意的是,由于Vue 3使用了Composition API,因此在编写自定义指令时应该将逻辑包装在一个单独的函数内部,然后再导入到主文件中进行全局注册。

Vue2

Vue.js的自定义指令可以通过使用directive选项来创建。在自定义指令中,我们可以定义不同的钩子函数来控制指令的行为。
下面是常见的自定义指令钩子函数及其作用:

bind: 当指令第一次被绑定到元素时调用。这里可以进行初始化操作或者添加事件监听器等。

// Vue组件内部示例
export default {
  directives: {
    myDirective: {
      bind(el, binding) {
        // 初始化操作或者添加事件监听器等
      }
    }
  }
}

inserted: 当指令所在的元素被插入到DOM中后调用。此时,该元素已经存在于页面上了。

// Vue组件内部示例
export default {
  directives: {
    myDirective: {
      inserted(el, binding) {
        // DOM元素已经插入到页面上
      }
    }
  }
}

update: 当指令所在的元素更新时调用。比如,当绑定的值发生变化时会触发该钩子函数。

// Vue组件内部示例
export default {
  directives: {
    myDirective: {
      update(el, binding) {
        // 处理指令相关的更新逻辑
      }
    }
  }
}

componentUpdated: 当指令所在的组件更新完成之后调用。与updated类似,只是它是在组件本身及其子组件都更新完成后才调用。

// Vue组件内部示例
export default {
  directives: {
    myDirective: {
      componentUpdated(el, binding) {
        // 处理指令相关的更新逻辑(包括子组件)
      }
    }
  }
}

unbind: 当指令从元素上移除时调用。可以清理工作、删除事件监听器等。

// Vue组件内部示例
export default {
  directives: {
    myDirective: {
      unbind(el, binding) {
        // 清理工作、删除事件监听器等
      }
    }
  }
}

编写防抖和节流指令

防抖

// src/directive/debounce.js
const debounce = {
    mounted(el, binding) {
        console.log('指令挂载了');
        el.timer = null
        el.handler = function () {
            if (el.timer) {
                clearTimeout(el.timer)
            }
            el.timer = setTimeout(() => {
                binding.value.fn()
                el.timer = null
            }, binding.value.delay)
        }
        el.addEventListener(binding.value.event, el.handler)
    },
    unmounted(el, binding) {
        console.log('在元素从页面移除时调用');
        if (el.timer) {
            clearTimeout(el.timer);
            el.timer = null;
        }
        el.removeEventListener(binding.value.event, el.handler)
    }
}
export default debounce

节流

// src/directive/trottle.js
const trottle = {
    mounted(el, binding) {
        console.log('节流指令挂载了');
        el.timer = null
        el.handler = function () {
            if (el.timer) {
                return;
            }
            el.timer = setTimeout(() => {
                binding.value.fn()
                el.timer = null
            }, binding.value.delay)
        }
        el.addEventListener(binding.value.event, el.handler)
    },
    unmounted(el, binding) {
        console.log('在元素从页面移除时调用trottle');
        if (el.timer) {
            clearTimeout(el.timer);
            el.timer = null;
        }
        el.removeEventListener(binding.value.event, el.handler)
    }
}
export default trottle

注册

import { createApp } from 'vue'
import App from './App.vue'
import debounce from './directive/debounce';
import throttle from './directive/throttle';
const app = createApp(App)
app.directive("debounce", debounce);
app.directive('throttle',throttle)
app.mount("#app");

使用

<script setup>
const handleClick = () => {
  console.log('防抖点击');
}
</script>
<template>
  <button v-debounce="{ fn: handleClick, event: 'click', delay: 1000 }">点击试试</button>
  <input v-debounce="{ fn: handleClick, event: 'input', delay: 1000 }"/>
  <hr>
  <button v-throttle="{ fn: handleClick, event: 'click', delay: 1000 }">点击试试</button>
    <input v-throttle="{ fn: handleClick, event: 'input', delay: 1000 }"/>
</template>
  • 7
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Vue 3 自定义指令钩子函数有以下几个: 1. `beforeMount`: 在指令被绑定到元素之前调用。可以在这个钩子函数进行一些初始化操作。 2. `mounted`: 当指令被绑定到元素并且元素插入到 DOM 后调用。可以在这个钩子函数进行一些需要 DOM 的操作。 3. `beforeUpdate`: 在元素更新之前调用。在这个钩子函数,你可以访问更新前的 DOM 和数据。 4. `updated`: 在元素更新之后调用。可以在这个钩子函数进行一些更新后的 DOM 操作。 5. `beforeUnmount`: 在指令从元素上解绑之前调用。可以在这个钩子函数进行一些清理操作。 6. `unmounted`: 当指令从元素上解绑之后调用。可以在这个钩子函数进行一些清理后的操作。 这些钩子函数可以通过在自定义指令对象定义对应的属性来使用,例如: ```javascript const myDirective = { beforeMount(el, binding, vnode, prevVnode) { // 在指令绑定到元素之前调用 }, mounted(el, binding, vnode, prevVnode) { // 在指令绑定到元素并插入*** 后调用 }, beforeUpdate(el, binding, vnode, prevVnode) { // 在元素更新之前调用 }, updated(el, binding, vnode, prevVnode) { // 在元素更新之后调用 }, beforeUnmount(el, binding, vnode, prevVnode) { // 在指令从元素上解绑之前调用 }, unmounted(el, binding, vnode, prevVnode) { // 在指令从元素上解绑之后调用 } }; ``` 然后,你可以通过在元素上使用 `v-my-directive` 来应用这个自定义指令: ```html <div v-my-directive></div> ```

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值