vue3指令:点击元素移除或添加指定类名

367 阅读2分钟

结构目录

  • directives --------------------------------------------指令目录
    • index.ts-------------------------------------------统一注册
    • onClickRemoveOrAddClass.ts--------------------------点击元素移除指定类名的指令

1.index.ts文件

import type { App } from "vue";
// 引入同文件夹下所有ts文件,index文件除外
// 引入 views 文件夹下所有 vue 文件
const modules = import.meta.glob("./**/*.ts");
console.log("modules", modules);
// 动态注册所有指令

const directives = {
  install: function (app: App<Element>) {
    Object.keys(modules).forEach(async key => {
      if (key !== "./index.ts") {
        // 对key进行截取,只需要.ts之前 /之后
        const reg = //+(.*).ts/;
        const match = key.match(reg);
        const name = match?.[1];
        const direct = await modules[key]();
        console.log("name", name);
        // 注册所有自定义指令
        name && app.directive(name, (direct as any)?.default);
      }
    });
  }
};

export default directives;

2.onClickRemoveOrAddClass.ts文件

import type { Directive, DirectiveBinding } from "vue";
/**
 * @description  点击元素移除或添加指定类名
 * @param  {array | string} 需要移除类名的数组或者字符串
 * @docs  v-on-click-remove-or-add-class
 * 1.单独注册:使用方式,在main.js中引入并注册repeat
 * import onClickRemoveOrAddClass from './direct/onClickRemoveOrAddClass'
 * app.directive('on-click-remove-or-add-class', onClickRemoveOrAddClass);
 * 2.统一注册directives目录下所有指令:使用方式,在main.js中引入并注册
 * import directives from "@/directives";
 * app.use(directives);
 * 页面内直接使用
 *    <div v-on-click-remove-or-add-class="['class1', 'class2']">点 击我去除或添加 class1 和 class2</div>
 **/

const removeOrAddClassDirective: Directive = {
  mounted(el: HTMLElement, binding: DirectiveBinding) {
    const classNames = binding.value;
    /**
     * @description 判断元素是否存在该类名,存在则移除,否则添加
     * @param el 元素
     * @param className 类名
     */
    const handleRemoveOrAddClass = (el: HTMLElement, className: string) => {
      // 判断元素是否存在该类名,存在则移除,否则添加
      Array.from(el.classList).includes(className)
        ? el.classList.remove(className)
        : el.classList.add(className);
    };
    const handleClick = (event: MouseEvent) => {
      if (event.target instanceof Element && classNames) {
        // 如果传入的是数组,则循环处理
        if (Array.isArray(classNames)) {
          classNames.forEach(className => {
            // 判断元素是否存在该类名,存在则移除,否则添加
            handleRemoveOrAddClass(el, className);
          });
        } else {
          // 判断元素是否存在该类名,存在则移除,否则添加
          handleRemoveOrAddClass(el, classNames);
        }
      }
    };
    // 添加事件监听
    el.addEventListener("click", handleClick);
  }
};

export default removeOrAddClassDirective;

2.注册使用

1.单独注册

  // 单独注册:使用方式,在main.js中引入并注册
  import onClickRemoveOraddClass from './direct/onClickRemoveOraddClass'
  app.directive('on-click-remove-or-add-class', onClickRemoveOraddClass);

1.统一注册

  // 统一注册directives目录下所有指令:使用方式,在main.js中引入并注册
 import directives from "@/directives";
 app.use(directives);

示例代码

<template>
  <div class="box" v-on-click-remove-or-add-class="['pink']"></div>
</template>

![20230909_092809.gif](https://p1-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/5c49a9e942fe4742b74a94fa8eca8613~tplv-k3u1fbpfcp-jj-mark:0:0:0:0:q75.image#?w=1160&h=850&s=248617&e=gif&f=51&b=fbfbfb)
<script setup lang="tsx"></script>
<style lang="less" scoped>
.box {
  width: 100%;
  height: 200px;
  background-color: red;
}
.pink {
  background-color: pink;
}
</style>

效果演示

20230909_092809.gif