自定义指令v-focus在vuetify组件上不起作用

时间:2019-09-27 13:21:40

标签: vue.js vuetify.js

我正在尝试使用vuejs自定义指令,该指令称为v-field-text,来自vuetify的组件。

directives: {
    focus: {
      // directive definition
      inserted: function(el) {
        el.focus();
      }
    }
  }

我有一个待办事项列表,待办事项打印有v-for,每当我单击“编辑”按钮待办事项和待办事项编辑输入的待办事项时,我还可以编辑待办事项。
我正在使用此focus指令来自动聚焦输入。

但是,当我像这样使用时不起作用:

<v-field-text v-focus></v-field-text>

但是它是这样的:

<input v-focus />

当我从指令中console.log el时,我看到它指向由vuetify创建的div元素。 如何解决此问题?

2 个答案:

答案 0 :(得分:1)

在这些元素上使用div时看到v-focus的原因是因为它们被包裹在div中。要使用不受您控制的代码的第三方组件来解决此问题,可以使用以下函数:

import Vue from 'vue'

Vue.directive('focus', {
  inserted: function(el) {
    // Recursion based function for finding an input
    // nested within other elements.
    let findInput = (el, max_depth = 5) => {
      // We found the input, so we return it, which causes
      // the entire function stack to pop
      if (el.nodeName === 'INPUT') {
        return el
      }

      // Prevent infinite recursion by providing a maximum
      // depth, and returning when we've reached that depth
      if (max_depth === 0) {
        return null
      }

      // Our current element is not an input, so we need to loop
      // over its children and call findInput recursively
      for (let child of el.children) {

        let input = findInput(child, max_depth - 1)

        // We've found our input, return it to unwind the stack
        // otherwise, continue through the loop
        if (input) {
          return input
        }
      }

      // Fallback in case for when el has no children, or we reached the end of the loop with no input
      return null
    }

    // Start searching for the input.  We can optionally
    // pass a higher max_depth.  Use with caution.
    let input = findInput(el, 20)

    if (input) {
      input.focus()
    }
  }
})

这是使用递归逐步遍历子元素的每个元素,并使用nodeName === 'INPUT'搜索元素。

作为示例,将解析以下复杂结构,并将重点放在找到的第一个输入上:

<div v-focus>
  <div>
    <div>
      <div>
        <div>
          <div>
            <div>
              <div>
                Hello
              </div>
              <p>
                world
              </p>
              <span>!</span>
            </div>
          </div>
        </div>
      </div>
    </div>
  </div>
  <div>
    <div>
      <div>
        <input type="text" value="I will be focused">
      </div>
    </div>
  </div>
</div>

答案 1 :(得分:1)

请尝试此解决方案。它为我工作:

 directives: {
        focus: {
          // directive definition
      inserted: function (el) {
          let childData = el.querySelectorAll("input")[0]; 
          childData.focus()
        }
          }
        }