web-dev-qa-db-ja.com

vue.jsは入力に焦点を合わせます

HTML

<span :style="{ display : displayTitle }" @dblclick="showInput()">
  {{ node.title }}
</span>
<input :style="{ display : displayTitleInput }" type="text" 
       @blur="hideInput1" @keydown="hideInput2" 
       @input="changeTitle(node.id , $event.target.value)" 
       :value="node.title">

JS

data() {
  return {
      displayTitle: "inline-block",
      displayTitleInput: "none"
    };
},
showInput() {
    this.displayTitle = "none"
    this.displayTitleInput = "inline-block"
},
hideInput1() {
   this.displayTitle = "inline-block"
   this.displayTitleInput = "none"
},
hideInput2(event) {
    if (event.keyCode === 13) {
        this.hideInput1()
    }
},

私は初心者の日本のウェブ開発者です。私は英語が苦手です、ごめんなさい。

HTMLは「v-for」(v-for="node in list")。

テキストをダブルクリックすると、<input>

表示されたときに入力に集中できるようにしたい。

私はこれを試しましたが、うまくいきませんでした。

HTML

<span :style="{ display : displayTitle }" @dblclick="showInput(node.id)">
  {{ node.title }}
</span>
<input :ref='"input_" + node.id' :style="{display:displayTitleInput}" type="text" 
       @blur="hideInput1" @keydown="hideInput2" 
       @input="changeTitle(node.id , $event.target.value)" 
       :value="node.title">

JS

showInput(id) {
    this.displayTitle = "none"
    this.displayTitleInput = "inline-block"

    this.$nextTick(this.$refs["input_" + id][0].focus())
},

コンソールにはエラーはありませんでしたが、機能しませんでした。

11
akao

あなたの主な問題は、$nextTickがコールバック関数を取るが、あなたが実行していることです

this.$refs["input_" + id][0].focus()

すぐに。あなたはあなたのコードを正しく動作させることができます

this.$nextTick(() => {
  this.$refs["input_" + id][0].focus()
})

ただし、さらに問題が発生する可能性があり、コードをはるかに単純化できると思います。

見つかる問題の1つは、スタイルルールにより、ノード入力をダブルクリックすると、すべてのノード入力が表示されることです。

代わりに、 "editing"フラグをnodeまたは別のオブジェクトのどこかに保存できます。

以下は、コードを単純化する例です...

  1. v-forループ内で使用される場合、 ref の配列のような性質を使用し、
  2. @keydownイベントバインディングでenter修飾子を使用する
new Vue({
  el: '#app',
  data: {
    list: [
      {id: 1, title: 'Node #1'},
      {id: 2, title: 'Node #2'}
    ],
    editing: {}
  },
  methods: {
    showInput(id, index) {
      this.$set(this.editing, id, true)
      
      this.$nextTick(() => {
        this.$refs.input[index].focus()
      })
    },
    hideInput(id) {
      this.editing[id] = false
    }
  }
})
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
<ul id="app">
  <li v-for="(node, index) in list">
    <span v-show="!editing[node.id]" @dblclick="showInput(node.id, index)">
      {{ node.title }}
    </span>
    <input v-show="editing[node.id]" type="text"
           ref="input" :value="node.title"
           @blur="hideInput(node.id)" @keydown.enter="hideInput(node.id)">
  </li>
</ul>
16
Phil

this.$nextTick();の使用方法は正しくありません。コールバック関数を渡す必要があります。

_this.$nextTick(function () {
    this.$refs["input_" + id].focus()
})
_

https://jsfiddle.net/un65e9oc/7/


しかし、気づいたように、_$refs_は参照名を参照するキーを持つオブジェクトであるため、その配列アクセスがどのように機能しているかはわかりません。

[編集:@Philのコメントのおかげで、上記は明らかです。]


上記が問題の正しい解決策です。あなたはすでにその答えを持っているので、それ以外のものを追加します。

この動作が発生する理由は、showInput()メソッドのテキストボックスの表示を変更しても、_$refs_に保持する参照が更新されないためです。したがって、this.$refs["input_" + id].focus();を呼び出すと、実際には隠し要素にfocusを設定しようとします(現在の参照が更新されないため)。

そのため、$nextTick()を呼び出して更新する必要があります。ただし、$nextTick()を呼び出さずに問題をすばやく修正したい場合は、次のように手動で更新できます。

_this.displayTitleInput = "inline-block"
this.$refs["input_" + id].style.display = this.displayTitleInput

this.$refs["input_" + id].focus();
_

これも機能します:)

2
Nimeshka Srimal

autofocus属性はあなたの友達です:

<input type="text" autofocus />