月度归档:2023年07月

element-plus el-button 增加 v-blur 指令

element-plus Button focus

element-plus el-button 增加 v-blur 指令

背景 & 问题

解决点击按钮后,触发 el-dialog 等弹窗组件的显示交互,弹窗隐藏之后,按钮的 focus 依然存在的问题。

🤔 思考:这个属于正常的交互,可以理解为:用户点击的哪里触发的这个弹窗,弹窗隐藏之后,用户的焦点应该回到点击的地方。

如果产品经理要求,弹窗隐藏之后,隐藏的按钮不要 focus,那么就需要增加一个指令来解决这个问题。

解决方案

1、在项目中新增一个指令文件 src/directives/blur/index.ts,内容如下:

src/directives/blur/index.ts

import { Directive } from "vue";

export const blur: Directive = {
  mounted(el) {
    if (!el) return;
    /**
     * 是否是点击触发的 blur
     *  - 点击触发 blur 时,不触发 focus
     *  - 非点击触发 blur 时,触发 focus
     */
    let isClick = false;
    el.addEventListener("click", () => {
      isClick = true;
    });
    el.addEventListener("focus", () => {
      if (isClick) {
        el.blur();
      }
    });
    el.addEventListener("blur", () => {
      isClick = false;
    });
  }
};

2、在 main.ts 中引入该指令:

main.ts

import App from "./App.vue";
import { createApp } from "vue";

import { blur } from "./directives/blur";

const app = createApp(App);

// ...

app.directive("blur", blur);

app.mount("#app");

3、在需要使用的地方,使用 v-blur 指令即可:

<script setup lang="ts">
defineOptions({
  name: "Demo"
});

const showDialog = () => {
  // ...
};
</script>

<template>
  <div class="demo">
    <el-button v-blur @click="showDialog">添加</el-button>
  </div>
</template>

<style lang="scss" scoped>
// ...
</style>

最终方案(2023-08-03 更新)

使用 css 覆盖即可解决:

.el-button:focus-visible {
  outline: 0;
}

element-plus Button focus after