vue3 实现自定义指令封装 --- 通俗易懂

1、局部自定义指令

1.1 在<script setup>定义组件内的指令,任何以v开头的驼峰式命名的变量都可以被用作一个自定义指令

javascript 复制代码
<template>
  <div>
    <h3>使用自定义指令</h3>
    <div>########################## start 局部自定义指令</div>
    <div>
        我是一个input:
        <input type="text" v-myFocus />
    </div>
    <div>########################## end 局部自定义指令</div>

  </div>
</template>

<script setup>
import { ref, reactive } from 'vue'
/**
 * 1、局部自定义指令, 在模板中启用 v-focus
 *    在<script setup>定义组件内的指令,任何以v开头的驼峰式命名的变量都可以被用作一个自定义指令
 *  为了区分下面全局自定义指令 v-focus,这里全局改为v-MyFocus
 */
// const vFocus = {
//     mounted: (el) => el.focus()
// }
const vMyFocus = {
    mounted: (el) => el.focus()
}
</script>

效果:

1.2 如果是vue3的options api, 自定义指令需要在directives选项中注册

javascript 复制代码
<template>
  <input v-focus />
</template>
<script>
export default{
  setup() {},
  directives: {
    // 指令名
    focus: {
      // 生命周期
      mounted(el) {
        // 处理DOM的逻辑
        el.focus()
      },
    }
  }
}
</script>

效果:

2、全局自定义指令

2.1 创建文件: src/directives/focus.js

javascript 复制代码
export default function(app) {
    app.directive('focus', {
        mounted(el) {
            console.log('focus指令, mounted')
            el.focus()
        },
    })
}

2.2 创建文件: src/directives/index.js

javascript 复制代码
import registerFocus from './focus'     // 获取焦点

export default function registerDirectives(app) {
    registerFocus(app)
}

2.3 main.js中引入

javascript 复制代码
import registerDirectives from './directives/index'

const app = createApp(App)
registerDirectives(app)

报警告如下:

index.vue:9 Vue warn: Failed to resolve directive: focus

at <Index onVnodeUnmounted=fn<onVnodeUnmounted> ref=Ref< undefined > >

at <RouterView>

at <App>

2.4 页面内使用

javascript 复制代码
    <div>########################## start 全局自定义指令</div>
    <div>
        我是一个使用全局自定义指令的input:
        <input type="password" v-focus />
    </div>
    <div>########################## end 全局自定义指令</div>

效果:

3、 常用的自定义指令(后面有新的全局自定义指令封装会更新)

3.1 input获取焦点

src/directives/focus.js

javascript 复制代码
export default function(app) {
    app.directive('focus', {
        mounted(el) {
            console.log('focus指令, mounted')
            el.focus()
        },
    })
}

ts写法:

javascript 复制代码
// 获取焦点
export default function(app: any) {
app.directive("focus", {
    mounted(el: any) {
      console.log("focus mounted");
      el.focus();
    }
  })
}

3.2 防抖

src/directives/debounce.js

注册那一步和上面focus一样(此处及后面将省略)

javascript 复制代码
// 防抖
export default function (app) {
    app.directive('debounce', {
        mounted(el, binding) {
            console.log('el', el, 'binding', binding);
            let timer
            el.addEventListener('click', () => {
                if (timer) clearTimeout(timer)
                timer = setTimeout(() => {
                    binding.value()
                }, 2000)
            })
        },
    })
}

ts写法:

javascript 复制代码
// 防抖
export default function(app: any) {
  app.directive("debounce", {
    mounted(el: any, binding: any) {
      let timer:any
      el.addEventListener('click', () => {
        if (timer) {
          clearTimeout(timer)
        }
        timer = setTimeout(() => {
          binding.value()
        }, 1000)
      })
    }
  })
}

使用:

javascript 复制代码
<template>
    <div>
        我是测试防抖的全局自定义指令,
        如果在该间隔内再次触发,则重新计时。
        <button class="btn" v-debounce="testDebounceBtn" >防抖按钮:点击我,2秒后执行一次</button>
    </div>
</template>

<script setup>
 /**
  * 3、防抖自定义指令 --- 全局
  */
const testDebounceBtn = () => {
    console.log('防抖按钮:点击我,2秒内只执行一次')
}
</script>

效果:

点击按钮后2秒后执行,2秒内再次触发点击,将重新计时,重新计时后2秒后才执行。(正常开发时,时间按照实际情况设定,一般设定1秒后执行)

相关推荐
IT乐手7 分钟前
佛德角逼平西班牙,国足还有啥借口?
前端
JustHappy43 分钟前
我汇总了身边朋友的经历才发现,其实第一份实习是最难找的......
前端·后端·面试
星栈1 小时前
Dioxus 的响应式系统:`Signal`、`Memo`、`Effect` 和异步状态到底该怎么分工
前端·前端框架
yingyima1 小时前
Java 正则表达式:比你想象的更强大
前端
yuanyxh4 小时前
macOS 应用 - 纯对话生成
前端·macos·ai编程
大家的林语冰4 小时前
ES5 凉凉,Babel 8 正式发布,默认不再编译为 ES5 和 CJS......
前端·javascript·前端工程化
光影少年5 小时前
react批量更新、同步/异步更新场景
前端·react.js·掘金·金石计划
假如让我当三天老蒯5 小时前
模块化:ES Module 与 CommonJS 的区别
前端·面试
用户40950115773175 小时前
Private Forge v2.0 发布:12大前端业务场景技能系统
前端
weedsfly6 小时前
异步编程全景与事件循环——彻底搞懂 JS 执行机制
前端·javascript