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()
}
},
Je suis un développeur web japonais débutant. Je ne suis pas bon en anglais, désolé.
Le HTML est en "v-for" (v-for="node in list"
).
Lorsque vous double-cliquez sur du texte, il se transforme en <input>
.
Je veux permettre de me concentrer sur l'entrée lorsqu'elle apparaît.
J'ai essayé mais ça n'a pas marché.
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())
},
Il n'y a pas eu d'erreur sur la console, mais cela n'a pas fonctionné.
Votre principal problème est que $nextTick
prend une fonction de rappel mais vous exécutez
this.$refs["input_" + id][0].focus()
immédiatement. Vous pourriez faire fonctionner votre code correctement avec
this.$nextTick(() => {
this.$refs["input_" + id][0].focus()
})
Cependant, je pense que vous rencontrerez d'autres problèmes et votre code peut être rendu beaucoup plus simple.
Un problème que vous constaterez est que toutes vos entrées de nœud deviendront visibles lorsque vous double-cliquez sur l'une d'entre elles en raison de vos règles de style.
Vous pouvez à la place stocker un indicateur "édition" quelque part sur le node
ou dans un objet séparé.
Voici un exemple qui simplifie votre code en ...
ref
lorsqu'il est utilisé dans un v-for
loop, etenter
sur votre @keydown
liaison d'événementnew 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>
La façon dont vous utilisez this.$nextTick();
est incorrecte. Vous devez lui passer une fonction de rappel.
this.$nextTick(function () {
this.$refs["input_" + id].focus()
})
https://jsfiddle.net/un65e9oc/7/
Je ne suis cependant pas sûr de savoir comment cet accès au tableau fonctionne pour vous, car comme je le constate, $refs
Est un objet avec les clés faisant référence au nom de la référence.
[Modifier: Merci au commentaire de @ Phil, ci-dessus est clair.]
Ce qui précède est la bonne solution à votre problème. Puisque vous avez déjà obtenu cette réponse, je vais ajouter autre chose que cela.
La raison pour laquelle vous voyez ce comportement est que parce que la référence que vous tenez dans $refs
N'est pas mise à jour lorsque vous modifiez la visibilité de la zone de texte dans votre méthode showInput()
. Ainsi, lorsque vous appelez this.$refs["input_" + id].focus();
, il essaie en fait de définir focus
sur un élément caché (car la référence actuelle n'est pas mise à jour).
C'est pourquoi vous devez appeler la $nextTick()
pour la mettre à jour. Mais si vous vouliez une solution rapide à votre problème, sans appeler $nextTick()
, vous pouvez le mettre à jour manuellement comme ceci:
this.displayTitleInput = "inline-block"
this.$refs["input_" + id].style.display = this.displayTitleInput
this.$refs["input_" + id].focus();
Cela fonctionnerait aussi :) J'espère que ça aide !!
L'attribut autofocus
est votre ami:
<input type="text" autofocus />