v-alert 组件内的按钮单击事件导致聚焦在 v-dialog 内的输入字段中

Button click event inside v-alert component is causing to focus in the input field inside v-dialog

当我单击 v-alert 中的按钮时,它会聚焦于 v-dialog 中的第一个输入字段。

我搜索了事件传播,并尝试使用各种事件修饰符,例如 .stop、.prevent 和 .self,但没有任何效果。

我做了this video来展示一个例子。

组件文件是这样的:

<template>
  <v-app>
    <button 
      @click="show_dialog = !show_dialog"
      class="button"
    >Show dialog</button>

    <button 
      @click="show_alert = !show_alert"
      class="button2"
    >Show alert</button>

    <v-dialog v-model='show_dialog' max-width="500px">
      <v-card>
        <v-card-title>Login</v-card-title>
        <v-card-text>
            <v-container fluid>
              <v-text-field
                label="first field"
                @focus="textFieldEvent($event)"
                @click="textFieldEvent($event)"
              ></v-text-field>
              <v-text-field
                label="second field"
                required
              ></v-text-field>
            </v-container>
        </v-card-text>
        <v-card-actions>
          <v-spacer />
          <button class="blue--text darken-1" text @click="show_dialog = !show_dialog">Cancel</button>
          <button type="submit">Login</button>
        </v-card-actions>
      </v-card>
    </v-dialog>

    <v-alert
      :value="show_alert"
      type='info' 
      style="width: 50%;" 
      class="alert_message"
    >
      <button 
        @click="alertEvent"
        style="background-color: blue;"
      >Button</button>
    </v-alert>
  </v-app>
</template>

<script>
export default {
    name: "default",
  data(){
    return {
      show_dialog: true,
      show_alert: true,
    }
  },
  methods: {
    alertEvent(event){
      console.log(">>>>>>> Alert Event", event)
      event.preventDefault()
      event.stopPropagation()
      event.stopImmediatePropagation()
    },
    textFieldEvent(event) {
      console.log(">>>>>>> text Field Event:", event)
    },
  },
};
</script>

<style scoped>
.alert_message{
    position: fixed;
    left: 50%;
    top: 93%;
    transform: translate(-50%, -50%);
    z-index: 999;
}
.button {
  background-color: #4CAF50; /* Green */
  border: none;
  color: white;
  padding: 15px 32px;
  text-align: center;
  text-decoration: none;
  display: inline-block;
  font-size: 16px;
}
.button2 {
  background-color: red;
  border: none;
  color: white;
  padding: 15px 32px;
  text-align: center;
  text-decoration: none;
  display: inline-block;
  font-size: 16px;
}
</style>

这是因为默认情况下,v-dialog 在打开时保留焦点。
因此,每当您尝试聚焦不在对话框内的元素时,它都会捕获此焦点并自动聚焦对话框中的第一个可聚焦元素。

This is important for accessibility. Users using only keyboards only want to navigate within the dialog when it's opened, not in the whole application.

解决方案:

如果你真的需要这个v-alert同时打开,解决方法就是在对话框中添加:retain-focus="false"属性。

<v-dialog :retain-focus="false"></v-dialog>

参见 CodePen

上的工作示例