vue.js делает акцент на вводе - PullRequest
       0

vue.js делает акцент на вводе

0 голосов
/ 30 августа 2018

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())
},

На консоли не было ошибки, но она не работала.

Ответы [ 3 ]

0 голосов
/ 30 августа 2018

То, как вы используете this.$nextTick();, неверно. Вы должны передать ему функцию обратного вызова.

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

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


Однако я не уверен, как этот доступ к массиву работает для вас, потому что, как я заметил, $refs - это объект, ключи которого ссылаются на имя ссылки.

[Редактировать: Благодаря комментарию @ Фила, выше ясно.]


Выше приведено правильное решение вашей проблемы. Поскольку у вас уже есть этот ответ, я добавлю что-то другое.

Причина, по которой вы видите такое поведение, заключается в том, что ссылка, которую вы держите в $refs, не обновляется при изменении видимости текстового поля в вашем методе showInput(). Поэтому, когда вы вызываете 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();

Это бы тоже сработало :) Надеюсь, это поможет !!

0 голосов
/ 03 июля 2019

Атрибут autofocus - ваш друг:

<input type="text" autofocus />
0 голосов
/ 30 августа 2018

Ваша основная проблема в том, что $nextTick принимает функцию обратного вызова, но вы выполняете

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

немедленно. Вы можете заставить ваш код работать правильно с

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

Однако я думаю, что вы столкнетесь с дальнейшими проблемами, и ваш код можно будет сделать намного проще.

Одна проблема, которую вы обнаружите, заключается в том, что все входы вашего узла станут видимыми при двойном щелчке по любому из них в соответствии с вашими правилами стиля.

Вместо этого вы можете хранить флаг «редактирования» где-нибудь либо на node, либо в отдельном объекте.

Ниже приведен пример, который упрощает ваш код на ...

  1. Использование массивоподобной природы ref при использовании внутри цикла v-for и
  2. Использование модификатора enter в привязке событий @keydown

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>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...