Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/363.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 自定义选择元素的模糊上的Vuejs无效_Javascript_Vue.js - Fatal编程技术网

Javascript 自定义选择元素的模糊上的Vuejs无效

Javascript 自定义选择元素的模糊上的Vuejs无效,javascript,vue.js,Javascript,Vue.js,场景 我已经构建了自定义的自动完成选择组件,它可以在其中自动完成,但是另外,如果没有找到结果,我们可以添加新的值。(我发现在vue选择模块中不可能) 问题 我尝试使用@blur,但如果单击该项,菜单将关闭。 我将自定义div作为一个项目列表,用于选择在焦点位于文本字段时切换的项目。如果我删除模糊,效果会很好,但不会关闭,我会在文本字段外单击。 我复制了用于处理向上键、向下键、键盘输入、滚动、处理vue select选择指针的函数 代码 <template> <

场景

我已经构建了自定义的自动完成选择组件,它可以在其中自动完成,但是另外,如果没有找到结果,我们可以添加新的值。(我发现在vue选择模块中不可能)

问题

我尝试使用@blur,但如果单击该项,菜单将关闭。 我将自定义div作为一个项目列表,用于选择在焦点位于文本字段时切换的项目。如果我删除模糊,效果会很好,但不会关闭,我会在文本字段外单击。 我复制了用于处理向上键、向下键、键盘输入、滚动、处理vue select选择指针的函数

代码

    <template>
    <div class="vselect">
        <div class="form-group">
            <label>{{label}}</label>
            <p class="control has-icon has-icon-right">
                <input ref="selected" @keyup="filterSelect($event)" @focus="onFocus" v-model="mutableValue" type="text" class="form-control"
                    @keydown.up.prevent="onKeyUp" @keydown.down.prevent="onKeyDown" @keydown.enter.prevent="onKeyEnter" @blur="onBlur">
            </p>
        </div>
        <div ref="dropdown" class="my-dropdown" v-show="toggled" v-if="options">
            <div v-for="(item,index) in filterList" :class="{'my-dropdwon--item':true,active:index === pointer}" @click="handleItemClick(item)"
                @mouseover="pointer = index">{{item}}</div>
        </div>
    </div>
</template>

<script>
    export default {
        name: 'VSelect',
        props: {
            'options': Array,
            'label': String,
            'value': String,
        },
        data() {
            return {
                selected: null,
                toggled: false,
                filterList: [],
                mutableValue: null,
                mutableOptions: [],
                pointer: 0
            }
        },
        methods: {
            filterSelect: function (key) {
                if (!this.toggled) this.toggled = !this.toggled;
                let oldArr = this.options;
                if (this.mutableValue && this.mutableValue.length <= 0)
                    this.filterList = this.mutableOptions;
                else if (key.key.length == 1 || key.key == 'Backspace') {
                    oldArr = oldArr.filter(item => {
                        if (item.toLowerCase().includes(this.mutableValue.toLowerCase()))
                            return true;
                    })
                    this.filterList = oldArr;
                    //console.log('type', this.filterList)
                }
                // if (key.key == 'Enter')
                //     this.toggled = !this.toggled;
                this.$emit('input', this.mutableValue);
            },
            handleItemClick: function (item) {                
                this.mutableValue = item;
                this.$emit('input', item);                                    
                this.toggled = !this.toggled;                               
            },
            onFocus: function () {
                this.$refs.dropdown.scrollTop = 0;
                this.toggled = !this.toggled;
            },
            onBlur: function () { 
                this.handleItemClick(this.mutableValue)                
                this.$refs.selected.blur();
            },
            onKeyUp: function () {
                if (this.pointer > 0) this.pointer--;
                if (this.maybeAdjustScroll) {
                    this.maybeAdjustScroll()
                }
            },
            onKeyDown: function () {            
                if (this.pointer < this.options.length && this.filterList.length) this.pointer++;
                if (this.pointer == this.options.length) this.pointer = 0;
                if (this.maybeAdjustScroll) {
                    this.maybeAdjustScroll()
                }
            },
            onKeyEnter: function () {
                //console.log(this.filterList.length> 0);
                if(this.filterList.length > 0)
                    this.handleItemClick(this.filterList[this.pointer])                
                this.$refs.selected.blur();
                this.$emit('input', this.mutableValue);
                this.toggled = false;
            },
            maybeAdjustScroll() {
                let pixelsToPointerTop = this.pixelsToPointerTop()
                let pixelsToPointerBottom = this.pixelsToPointerBottom()
                //console.log(pixelsToPointerTop,pixelsToPointerBottom);
                if (pixelsToPointerTop <= this.viewport().top) {
                    return this.scrollTo(pixelsToPointerTop)
                } else if (pixelsToPointerBottom >= this.viewport().bottom) {
                    return this.scrollTo(this.viewport().top + this.pointerHeight())
                }
            },

            pixelsToPointerTop() {
                let pixelsToPointerTop = 0
                if (this.$refs.dropdown && this.$refs.dropdown.children) {
                    for (let i = 0; i < this.pointer; i++) {
                        pixelsToPointerTop += this.$refs.dropdown.children[i].offsetHeight
                    }
                }
                return pixelsToPointerTop
            },

            pixelsToPointerBottom() {
                return this.pixelsToPointerTop() + this.pointerHeight()
            },

            pointerHeight() {
                let element = this.$refs.dropdown ? this.$refs.dropdown.children[this.pointer] : false
                return element ? element.offsetHeight : 0
            },

            viewport() {
                return {
                    top: this.$refs.dropdown ? this.$refs.dropdown.scrollTop : 0,
                    bottom: this.$refs.dropdown ? this.$refs.dropdown.offsetHeight + this.$refs.dropdown.scrollTop : 0
                }
            },
            scrollTo(position) {
                //console.log(position);
                return this.$refs.dropdown ? this.$refs.dropdown.scrollTop = position : null
            },

        },
        mounted() {
            this.filterList = this.options;
        },
        watch: {
            value(val) {
                this.mutableValue = val
            },
            options(val) {
                this.mutableOptions = val
            },
            pointer() {
                this.maybeAdjustScroll()
            }

        }
    }
</script>

<style scoped>
    .vselect {
        display: block;
        position: relative;
    }

    .my-dropdown {
        width: 100%;
        background: #f7f7f7;
        margin-top: 0.1rem;
        border: 1px solid #ced4da;
        border-radius: 3px;
        transition: all 0.5s;
        position: absolute;
        z-index: 1;
        max-height: 10rem;
        overflow: auto
    }

    .my-dropdwon--item {
        padding: 0.5rem;
        width: 100%;
        transition: all 0.5s;
    }

    .active {
        cursor: pointer;
        background-color: rgb(223, 221, 221);
    }

    /* .my-dropdwon--item:hover {
        cursor: pointer;
        background-color: rgb(223, 221, 221);
    } */

    .form-group {
        margin-bottom: 0px;
    }

    .control.has-icon has-icon-right {
        margin-bottom: 0px;
    }

    .form-group>p {
        margin-bottom: 0px;
    }
</style>

{{label}}

{{item}} 导出默认值{ 名称:“VSelect”, 道具:{ “选项”:数组, “标签”:字符串, “值”:字符串, }, 数据(){ 返回{ 选中:空, 切换为:false, 过滤器列表:[], 可变值:null, 可变选项:[], 指针:0 } }, 方法:{ 过滤器选择:功能(键){ 如果(!this.toggled)this.toggled=!this.toggled; 设oldArr=this.options; if(this.mutableValue&&this.mutableValue.length{ if(item.toLowerCase().includes(this.mutableValue.toLowerCase())) 返回true; }) this.filterList=oldArr; //console.log('type',this.filterList) } //如果(key.key=='Enter') //this.toggled=!this.toggled; this.$emit('input',this.mutableValue); }, handleItemClick:函数(项){ this.mutableValue=项目; 此.$emit('输入',项); this.toggled=!this.toggled; }, onFocus:function(){ 这是。$refs.dropdown.scrollTop=0; this.toggled=!this.toggled; }, onBlur:function(){ this.handleItemClick(this.mutableValue) 这是.$refs.selected.blur(); }, onKeyUp:函数(){ 如果(this.pointer>0)this.pointer--; 如果(此.maybeAdjustScroll){ this.maybeAdjustScroll() } }, onKeyDown:函数(){ 如果(this.pointer0); 如果(this.filterList.length>0) this.handleItemClick(this.filterList[this.pointer]) 这是.$refs.selected.blur(); this.$emit('input',this.mutableValue); this.toggled=false; }, maybeAdjustScroll(){ 设pixelsToPointerTop=this.pixelsToPointerTop() 设pixelsToPointerBottom=this.pixelsToPointerBottom() //log(pixelsToPointerTop,pixelsToPointerBottom); 如果(pixelsToPointerTop=this.viewport().bottom){ 返回this.scrollTo(this.viewport().top+this.pointerHeight()) } }, pixelsToPointerTop(){ 设pixelsToPointerTop=0 if(this.$refs.dropdown&&this.$refs.dropdown.children){ for(设i=0;i<div v-for="(item,index) in filterList" :class="{'my-dropdwon--item':true,active:index === pointer}" @mousedown="handleItemClick(item)" @mouseover="pointer = index"> {{item}} </div>