菜单

Vue实现typeahead组件功能_vue

2020年3月23日 - www.2138.com

前言

事前十一分typeahead写的太早,不满意当下的事务供给。

与此同有的时候间有些欠缺,还会有也不实惠传入数据和响应数据..

于是就推倒了重来,写了个V2的本子

看图,多了部分细节的设想;简洁明了了贯彻的逻辑代码

贯彻的魔法

1: 鼠标点击下拉框之外的区域关闭下拉框

2: 扶持键盘上下键选用,援助鼠标选取

3: 帮助列表过滤搜索

4: 支持外界传入列表JSON格式的炫丽

5: 支持placeholder的传入

6: 选中指标的响应(.sync vue2.3的机件通信的语法糖卡塔尔国

7: 箭头icon的酷炫,以为效果相当的小,移除了

用法

asyncData:响应的数码,也正是选中的..回来是三个对象 mapData :
搜索的列表数据,明确是表面传入了… mapData : 列表值映射

代码

selectSearch.vue

             {{item[mapDataFormat.label]}}    未能查询到,请重新输入!     export default { name: 'selectSearch', data: function () { return { placeholderValue: '',// 给看到选择内容的 isExpand: false, searchVal: '', // 搜索关键字 resultVal: '', // 保存搜索到的值 searchList: [], //保存过滤的结果集 currentIndex: -1, // 当前默认选中的index, } }, computed: { mapFormatData () { // 外部有传入格式的时候映射mapData return this.mapData.map(item => { item[this.mapDataFormat.value] = item[this.mapDataFormat.value]; return item; }); }, typeaheadData () { let temp = []; if (this.searchVal && this.searchVal === '') { return this.mapFormatData; } else { this.currentIndex = -1; // 重置特殊情况下的索引 this.mapFormatData.map(item => { if (item[this.mapDataFormat.label].indexOf(this.searchVal.toLowerCase { temp.push } return item; }) return temp; } } }, props: { placeholder: { type: String, default: '--请选择--' }, emptyText: { type: String, default: '暂无数据' }, mapData: { // 外部传入的列表数据 type: Array, default: function () { return [] } }, mapDataFormat: { // 映射传入数据的格式 type: Object, default: function () { return { label: 'text', value: 'value', extraText: 'extraText' } } }, asyncData: { // 实时响应的值 type: [Object, String], default: function () { return {} } } }, methods: { showHideMenu  { // 点击其他区域关闭下拉列表 if  { if (this.$refs.selectSearch && this.$refs.selectSearch.contains { this.isExpand = true; } else { this.isExpand = false; } } }, resetDefaultStatus () { // 清除所有选中状态 this.searchVal = ''; this.currentIndex = -1; this.typeaheadData.map(item => { this.$delete }, setActiveClass  { // 设置样式活动类 this.typeaheadData.map => { if  { this.$set; this.currentIndex = index; // 这句话是用来修正index,就是键盘上下键的索引,不然会跳位 } else { this.$set(item, 'active', false) } }) }, selectChildWidthArrowDown () { // 判断index选中子项 if (this.currentIndex < this.typeaheadData.length) { this.currentIndex++; this.typeaheadData.map => { this.currentIndex === index ? this.$set : this.$set(item, 'active', false); }) } }, selectChildWidthArrowUp () { // 判断index选中子项 if (this.currentIndex > 0) { this.currentIndex--; this.typeaheadData.map => { this.currentIndex === index ? this.$set : this.$set(item, 'active', false); }) } }, selectChildWidthEnter () { // 若是结果集只有一个,则默认选中 if (this.typeaheadData.length === 1) { this.$emit('update:asyncData', this.typeaheadData[0]); // emit响应的值 this.placeholderValue = this.typeaheadData[0][this.mapDataFormat.label]; } else { // 若是搜索的内容完全匹配到项内的内容,则默认选中 this.typeaheadData.map(item => { if (this.searchVal === item[this.mapDataFormat.label] || item.active === true) { this.$emit('update:asyncData', item); // emit响应的值 this.placeholderValue = item[this.mapDataFormat.label]; } }) } this.isExpand = false; }, selectChild  { // 鼠标点击选择子项 this.typeaheadData.map => { if (index === innerIndex || item.active) { this.placeholderValue = item[this.mapDataFormat.label]; this.$emit('update:asyncData', item); // emit响应的值 } }); this.isExpand = false; }, }, mounted () { window.addEventListener('click', this.showHideMenu); }, beforeDestroy () { window.removeEventListener('click', this.showHideMenu); }, watch: { 'isExpand'  { if  { this.resetDefaultStatus(); } } } } .el-fade-in-linear-enter-active, .el-fade-in-linear-leave-active, .fade-in-linear-enter-active, .fade-in-linear-leave-active { transition: opacity .2s linear; } .el-fade-in-enter, .el-fade-in-leave-active, .el-fade-in-linear-enter, .el-fade-in-linear-leave, .el-fade-in-linear-leave-active, .fade-in-linear-enter, .fade-in-linear-leave, .fade-in-linear-leave-active { opacity: 0; } .noFound { text-align: center; } .select-search { position: relative; z-index: 1000; a { color: #333; text-decoration: none; padding: 5px; } ul { list-style: none; padding: 6px 0; margin: 0; max-height: 200px; overflow-x: hidden; overflow-y: auto; li { display: block; width: 100%; padding: 5px; font-size: 14px; padding: 8px 10px; position: relative; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; color: #48576a; height: 36px; line-height: 1.5; box-sizing: border-box; cursor: pointer; &.active { background-color: #20a0ff; a { color: #fff; } } } } .select-header { position: relative; border-radius: 4px; border: 1px solid #bfcbd9; outline: 0; padding: 0 8px; >input { border: none; -webkit-appearance: none; -moz-appearance: none; appearance: none; width: 100%; outline: 0; box-sizing: border-box; color: #1f2d3d; font-size: inherit; height: 36px; line-height: 1; } >i { transition: all .3s linear; display: inline-block; position: absolute; right: 3%; top: 50%; transform: translateY; } } .select-body { position: absolute; border-radius: 2px; background-color: #fff; box-sizing: border-box; margin: 5px 0; padding: 8px; width: 100%; box-shadow: 0 2px 4px rgba, 0 0 6px rgba; >input { -webkit-appearance: none; -moz-appearance: none; appearance: none; background-color: #fff; background-image: none; border-radius: 4px; border: 1px solid #bfcbd9; box-sizing: border-box; color: #1f2d3d; font-size: inherit; height: 36px; line-height: 1; outline: 0; padding: 3px 10px; transition: border-color .2s cubic-bezier; width: 100%; display: inline-block; &:focus { outline: 0; border-color: #20a0ff; } } } }

总结

如上所述是作者给大家介绍的Vue完成typeahead组件成效,希望对我们全体利于,假使大家有此外疑问请给笔者留言,笔者会及时回复大家的。在这里也极度多谢大家对台本之家网址的支撑!

相关文章

发表评论

电子邮件地址不会被公开。 必填项已用*标注

网站地图xml地图