当父节点中有很多 v-if 时,自定义 v-focus 不起作用
custom v-focus not work when there are many v-if in parent node
我在我的组件中定义了自定义指令 "focus":
<script>
export default {
name: 'demo',
data () {
return {
show: true
}
},
methods: {
showInput () {
this.show = false
}
},
directives: {
focus: {
inserted: function (el) {
el.focus()
}
}
}
}
这是我的 html 模板:
<template>
<div>
<input type="number" id="readonly" v-if="show">
<button type="button" @click="showInput" v-if="show">show</button>
<input type="number" id="timing" v-model="timing" v-if="!show" v-focus>
</div>
</template>
但是当我点击button
时,input#timing
不能自动对焦。
当我将input#readonly
和button
放入一个div
中并且只使用一个v-if时,input#timing
可以成为 自动对焦:
<template>
<div>
<div v-if="show">
<input type="number" id="readonly">
<button type="button" @click="showInput">show</button>
</div>
<input type="number" id="timing" v-model="timing" v-if="!show" v-focus>
</div>
</template>
这是为什么???
指令的代码确实是 运行 并且关注 <input>
.
但它正在从 DOM 中删除!发生这种情况时,它会失去焦点。检查下面 fiddle 的控制台:https://jsfiddle.net/acdcjunior/srfse9oe/21/
还有一个很重要的一点是,当inserted
被调用时,<input id="timing">
在DOM中(如上所述),但是在DOM中在 错误的位置 (在 <p>a</p>
和 <p>b</p>
之间,它本来不应该在的地方)。发生这种情况是因为 Vue 尝试重用元素 .
并且当 nextTick
触发时(参见 fiddle),它处于正确的位置(在 <p>c</p>
和 <p>d</p>
之间),因为 Vue 将它移到了正确的位置。这种移动是否正在转移注意力。
并且因为 nextTick
在 DOM 移动完成后运行,所以焦点仍然存在(见下文)。
Defer the callback to be executed after the next DOM update cycle. Use
it immediately after you’ve changed some data to wait for the DOM
update.
new Vue({
el: '#app',
data() {
return {
show: true,
timing: 123
}
},
methods: {
showInput() {
this.show = false
}
},
directives: {
focus: {
inserted: function(el) {
Vue.nextTick(() => el.focus()); // <======== changed this line
}
}
}
})
<script src="https://unpkg.com/vue"></script>
<div id="app">
<div>
<input type="number" id="readonly" v-if="show">
<button type="button" @click="showInput" v-if="show">show</button>
<input type="number" id="timing" v-model="timing" v-if="!show" v-focus>
</div>
</div>
我在我的组件中定义了自定义指令 "focus":
<script>
export default {
name: 'demo',
data () {
return {
show: true
}
},
methods: {
showInput () {
this.show = false
}
},
directives: {
focus: {
inserted: function (el) {
el.focus()
}
}
}
}
这是我的 html 模板:
<template>
<div>
<input type="number" id="readonly" v-if="show">
<button type="button" @click="showInput" v-if="show">show</button>
<input type="number" id="timing" v-model="timing" v-if="!show" v-focus>
</div>
</template>
但是当我点击button
时,input#timing
不能自动对焦。
当我将input#readonly
和button
放入一个div
中并且只使用一个v-if时,input#timing
可以成为 自动对焦:
<template>
<div>
<div v-if="show">
<input type="number" id="readonly">
<button type="button" @click="showInput">show</button>
</div>
<input type="number" id="timing" v-model="timing" v-if="!show" v-focus>
</div>
</template>
这是为什么???
指令的代码确实是 运行 并且关注 <input>
.
但它正在从 DOM 中删除!发生这种情况时,它会失去焦点。检查下面 fiddle 的控制台:https://jsfiddle.net/acdcjunior/srfse9oe/21/
还有一个很重要的一点是,当inserted
被调用时,<input id="timing">
在DOM中(如上所述),但是在DOM中在 错误的位置 (在 <p>a</p>
和 <p>b</p>
之间,它本来不应该在的地方)。发生这种情况是因为 Vue 尝试重用元素 .
并且当 nextTick
触发时(参见 fiddle),它处于正确的位置(在 <p>c</p>
和 <p>d</p>
之间),因为 Vue 将它移到了正确的位置。这种移动是否正在转移注意力。
并且因为 nextTick
在 DOM 移动完成后运行,所以焦点仍然存在(见下文)。
Defer the callback to be executed after the next DOM update cycle. Use it immediately after you’ve changed some data to wait for the DOM update.
new Vue({
el: '#app',
data() {
return {
show: true,
timing: 123
}
},
methods: {
showInput() {
this.show = false
}
},
directives: {
focus: {
inserted: function(el) {
Vue.nextTick(() => el.focus()); // <======== changed this line
}
}
}
})
<script src="https://unpkg.com/vue"></script>
<div id="app">
<div>
<input type="number" id="readonly" v-if="show">
<button type="button" @click="showInput" v-if="show">show</button>
<input type="number" id="timing" v-model="timing" v-if="!show" v-focus>
</div>
</div>