在 Vue 3 中单击按钮后如何将焦点保持在输入上而不闪烁?

问题描述 投票:0回答:3

脚本

const amountRef = ref(null);
const amount = ref(0.1);

const insertSuggestion = (e, value) => {
  e.preventDefault();
  e.stopPropagation();
  amount.value = value;
  amountRef.value.focus();
};

模板

<Suggestion
   class="..."
   v-for="suggestion in suggestions"
   :key="suggestion"
   @click="insertSuggestion($event, suggestion)"
>
    {{ suggestion }}
</Suggestion>
<input
   class="..."
   @keyup.enter="handleBuy"
   placeholder="Amount"
   ref="amountRef"
   v-model="amount"
/>

javascript vue.js focus vuejs3
3个回答
1
投票

您可以将输入元素重新聚焦在

blur
事件上:

<input ref="amountRef" @blur="$refs.amountRef.focus()"/>

编辑

您还需要检查

relatedTarget
事件的
blur
,以确保仅在单击其中一个按钮时重新聚焦。

注意:此解决方案不适用于 Firefox。

<Suggestion
   class="suggestion-btn"
   ...
>
</Suggestion>
<input
   ref="amountRef"
   @blur="onBlur"
/>

onBlur(evt) {
    if (
        evt.relatedTarget &&
        evt.relatedTarget.classList.contains("suggestion-btn")
    ) {
        this.$refs.amountRef.focus();
    }
},

1
投票

如果

relatedTarget
是这些按钮之一,您可以尝试捕获模糊事件并将类添加回来。超级伪代码如下:

<input
   class="..."
   @keyup.enter="handleBuy"
   @blur="maybeMimicFocus"
   placeholder="Amount"
   ref="amountRef"
   v-model="amount"
/>
maybeMimicFocus (event) {
  if (event.relatedTarget && event.relatedTarget.tagname === 'btn') {
    this.$refs.amountRef.$el.classList.add('the-classes-that-make-it-look-focused')
  }
}

浏览器不必重新绘制 dom,因此该事务应该很快,肉眼看不出有什么不同。我能看到的唯一警告是是否有附加到过渡属性的动画,其中这些动画必须触发。


0
投票

使用 @mousedown.prevent 停止散焦

TLDR:

mousedown
出现在
blur
click
之前。

我强烈建议完全避免任何焦点更改,甚至重新焦点,因为任何状态更改都可能引发一系列二级状态更改,特别是与某些深度嵌套的组件一起使用时。即使它有效,您也会面临向用户暴露视觉“打嗝”的风险。

相反,您应该首先尝试真正阻止散焦的发生。

您对

@click
和随后的
e.preventDefault()
的想法是正确的,但是在模糊之后发生了点击事件。

相反,通过从较早的事件

preventDefault
(该事件发生在模糊和单击之前)触发它,使 mousedown 发生在
模糊发生之前。

只需添加 Vue 的

@mousedown.prevent

 来停止失焦,然后你也可以摆脱一堆后续行:

脚本

const insertSuggestion = (value) => { amount.value = value }

模板

<Suggestion class="..." v-for="suggestion in suggestions" :key="suggestion" @mousedown.prevent @click="insertSuggestion(suggestion)" > {{ suggestion }} </Suggestion>
    
© www.soinside.com 2019 - 2024. All rights reserved.