Vue / vuetify focus input after modal is dismissed

2019-08-17 10:32发布

问题:

On a page I have a Vuetify v-form/v-text-field. Users can type a query in to this form and press Enter to update the page.

Sometimes the query is erroneous and a v-dialog modal pops up to explain the error. It's a complex error and can't just be packed in the rules attribute of the v-text-field.

The problem: when the modal is dismissed, the v-text-field is no longer focused and requires a click before it can be used again. This interrupts the user and requires a shift from keyboard to mouse and back.

What is Vue best practice for re-focusing on the input that triggered the modal?

I can think of one idea it doesn't feel Vue-ish: put a ref on the v-text-field and watch the dialog data property. If dialog becomes false, call this.$refs.input.focus(). However, this seems like the old-fashioned, imperative (not reactive) way to do it. For example:

<template>  
  <v-form v-model='valid' @submit.prevent='submit'>
    <v-text-field
      placeholder="Search..."
      v-model="query"
      :rules="[foo]"
      ref='input'
      autofocus
    ></v-text-field>

    <v-dialog
      v-model="dialog"
      @keydown.esc='dialog = false'
    >
      {{ someErrorMessage }}
    </v-dialog>
  </v-form>
</template>
// Vue instance
  export default { 

    data: function() {
      return {
        dialog: false,
        query: "",
        valid: false
      }
    },

    ...

    watch: {
      // Focus on query after dismissing an error
      dialog(newState) {
        if (!newState) {
          this.$refs.input.focus();
        }
      }
    },

    methods: {
      foo(value) {
        // ... validate value
      },
      submit(e) {
        if (!this.valid) {
          this.dialog = true;
          return;
        }
      }
    }
  }

回答1:

In the dialog element, I'd probably call a method instead of directly changing dialog to false. Then in that method, I'd add focus to the textarea with some plain old javascript.