簡體   English   中英

通過單擊外部 vue 重置自動完成字段文本

[英]reset autocomplete field text by clicking outside vue

我有一個自動完成字段。 如果我輸入任何文本並且它與結果集匹配,那么它將填充下拉結果。 如果它不匹配任何內容,則通過單擊外部它將強制重置輸入字段。

因此,對於這種方法,我創建了 vue click outside 指令

    import Vue from 'vue';

const nodeList = [];
const ctx = '@@clickoutsideContext';

let startClick;
const counter = 0;

const isServer = Vue.prototype.$isServer;

/**
 * added this on event function for direct dom manipulation
 */
const onEvent = (function() {
    if (!isServer && document.addEventListener) {
        return function(element, event, handler) {
            if (element && event && handler) {
                element.addEventListener(event, handler, false);
            }
        };
    }
    return function(element, event, handler) {
        if (element && event && handler) {
            element.attachEvent(`on${event}`, handler);
        }
    };
})();

!isServer &&
    onEvent(document, 'mousedown', e => {
        startClick = e;
    });

!isServer &&
    onEvent(document, 'mouseup', e => {
        nodeList.forEach(node => node[ctx].documentHandler(e, startClick));
    });

// setting up mouse events

function createDocumentHandler(el, binding, vnode) {
    return function(mouseup = {}, mousedown = {}) {
        if (
            !vnode ||
            !vnode.context ||
            !mouseup.target ||
            !mousedown.target ||
            el.contains(mouseup.target) ||
            el.contains(mousedown.target) ||
            el === mouseup.target ||
            (vnode.context.popperElm &&
                (vnode.context.popperElm.contains(mouseup.target) ||
                    vnode.context.popperElm.contains(mousedown.target)))
        )
            return;

        if (
            binding.expression &&
            el[ctx].methodName &&
            vnode.context[el[ctx].methodName]
        ) {
            vnode.context[el[ctx].methodName]();
        } else {
            el[ctx].bindingFn && el[ctx].bindingFn();
        }
    };
}

/**
 * v-clickoutside
 * @desc Only trigger when click outside
 * @example
 * ```vue
 * <div v-element-clickoutside="handleClose">
 * ```
 */
export default {
    bind(el, binding, vnode) {
        nodeList.push(el);
        const id = counter + 1;
        el[ctx] = {
            id,
            documentHandler: createDocumentHandler(el, binding, vnode),
            methodName: binding.expression,
            bindingFn: binding.value
        };
    },

    update(el, binding, vnode) {
        el[ctx].documentHandler = createDocumentHandler(el, binding, vnode);
        el[ctx].methodName = binding.expression;
        el[ctx].bindingFn = binding.value;
    },

    unbind(el) {
        const len = nodeList.length;

        for (let i = 0; i < len; i += 1) {
            if (nodeList[i][ctx].id === el[ctx].id) {
                nodeList.splice(i, 1);
                break;
            }
        }
        delete el[ctx];
    }
};

這是 forms 字段中的自動完成字段

<div v-if="field.type == 'autocomplete'">
                <vu-auto-complete
                    v-model="fieldvalues[field.key]"
               :items="formFieldAutocompleteItems[fieldvalues[field.key]] || []"
                    :label="labelrequired(field)"
                    :placeholder="field.placeholder"
                    :error-message="errorMsg[field.key]"
                    @input="handleOnInput($event, field)"
                    @selected="getSelectedData($event, field)"
                >
                </vu-auto-complete>
            </div>

handleOnInput 的方法

handleOnInput(inputKey, field) {
        if (inputKey !== null && inputKey.length >= 3) {
            this.fieldvalues = {
                ...this.fieldvalues,
                [field.key]: inputKey
            };
            const data = {
                url: field.autocompleteUri,
                search: field.autocompleteUriKey,
                text: inputKey,
                key: field.key
            };
            clearTimeout(this.timer);
            this.timer = setTimeout(() => {
                this.$emit('autocompleteInput', data);
            }, 500);
        } else if (inputKey.length === 0 || inputKey === null) {
            const formData = { ...this.fieldvalues };
            if (field.dependentFields && field.dependentFields.length > 0) {
                for (let i = 0; i < field.dependentFields.length; i += 1) {
                    formData[field.dependentFields[i]] = '';
                }
            }
            this.fieldvalues = formData;
        }
    },

自動完成字段工作正常。 所以,我需要指令或方法來通過點擊外部來重置任何輸入。

任何建議或示例都將有助於理解。

我建議您使用 VueUse 的onClickOutside實用程序。

VueUse 實際上是 Vue 超級有用的實用程序功能的集合,支持 Vue2、Vue3 和 Typescript。

對於這么多不同的用例,有超過 90 種不同的實用程序,並且該庫是可搖樹的,因此您只需捆綁您使用的內容。

onClickOutside實用程序需要一個目標ref和一個回調以及可選的第三個配置參數。

像這樣的東西應該適合你:

onClickOutside(
  inputRef,
  (event) => {
    console.log(event);
    this.inputText = '';
  },
  { event: 'mousedown' },
)

這可以節省您編寫自定義代碼的時間,因為您可能會錯過重要的考慮因素,例如可訪問性。 如果需要,您可以深入研究該實用程序的源代碼並探索其內部工作原理。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM