如何在剩下字段时隐藏文本字段浮动建议,但如果单击建议?

问题描述 投票:0回答:1
i制作了一个vue组件(我有史以来的第一个!),目的是在您输入时向选项显示建议:

const AutoCompleteComponent = { data() { return { open: false, current: 0, /** @type {string[]} **/ suggestions: ["first", "ble", "hello"], fieldWidth: 0, } }, mounted() { this.fieldWidth = this.$refs.inputField.clientWidth; }, methods: { focus() { console.log("Focus activated"); this.open = true; }, blur() { console.log("Focus deactivated") // when I do this, the suggestions dissappear the frame before they are // clicked, causing the suggestionClick to not be called this.open = false; }, //For highlighting element isActive(index) { return index === this.current; }, //When the user changes input change() { this.loadSuggestions(); //console.log("change()"); if (this.open == false) { this.open = true; this.current = 0; } }, //When one of the suggestion is clicked suggestionClick(index) { this.currentText = this.matches[index]; console.log("Clicked suggestion: ", index, this.matches[index]); this.open = false; }, }, computed: { /** * Filtering the suggestion based on the input * @this {ReturnType<AutoCompleteComponent["data"]>} */ matches() { console.log("computed.matches() str=", this.currentText, " suggestions=", this.suggestions); return this.suggestions.filter((str) => { const withoutAccents = str.toLowerCase(); return withoutAccents.indexOf(this.currentText.toLowerCase()) >= 0; }); }, //The flag openSuggestion() { return this.currentText !== "" && this.matches.length != 0 && this.open === true; }, copiedWidth() { return this.fieldWidth + "px"; } }, template: "#vue-auto-complete-template" };
这是HTML模板:

<template id="vue-auto-complete-template"> <div v-bind:class="{'open':openSuggestion}" class="auto-complete-field"> <div class="field-wrapper"> <input class="form-control" type="text" v-model="currentText" @keydown.enter='enter' @keydown.down='down' @keydown.up='up' @input='change' @focus="focus" @blur="blur" ref="inputField" /> </div> <div class="suggestions-wrapper"> <ul class="field-suggestions" :style="{ width: copiedWidth }" > <li v-for="(suggestion, suggestion_index) in matches" v-bind:class="{'active': isActive(suggestion_index)}" @click="suggestionClick(suggestion_index)"> {{ suggestion }} </li> </ul> </div> </div> </template>
所以我这样创建它:

<AutoCompleteComponent class="some class names"></AutoCompleteComponent>
为了使其出现在现场下,应用了以下CSS:

.auto-complete-field { display:inline-block; } .auto-complete-field .suggestions-wrapper { display:block; position: relative; } .auto-complete-field.open ul { display:initial; } .auto-complete-field ul { list-style:none; padding:0; margin:0; display: none; position: absolute; top:0px; left: 0px; border-bottom: 1px solid black; } .auto-complete-field ul li { background-color: white; border: 1px solid black; border-bottom: none; }
现在问题是,如果您查看

blur()

函数,它将设置为false,而false又可以使用
open
类名称隐藏建议。
由于处理事件的顺序,
ul.field-suggestions
在创建点击事件之前,该场上的事件隐藏了
active
,从而使其在其下面的任何内容上被调用。

Quick和肮脏的补救措施将是

blur

。我认为这样可以使用,至少必须是两个渲染帧。它没有用作微型审判也不起来。我不想使用超时,尤其是大型超时,因为它可能会通过快速点击引起gui闪烁。
我正在为此寻求更坚实的解决方案。我希望Vue为此有所作为。普通的JS解决方案通常是通过在窗口上的多个事件中聆听并检查其发生的位置来重新实现模糊事件。我宁愿避免这种情况。
    
您应该尝试

.auto-complete-field.open ul

而不是

setTimeout(()=>{this.open=false}, 100)
i我在我的VUE3项目上重现了您的代码,他的工作(直到单击建议的项目完成后完成完成后才召集)

javascript vue.js vue-component
1个回答
0
投票
事件在模糊之前开火。

@mousedown

    

最新问题
© www.soinside.com 2019 - 2025. All rights reserved.