在实际的vue项目开发中,通常与element-ui搭配使用的比较多,每每能知足大部分的需求。
可是有时某些需求element-ui并不能知足,例如如今咱们有这样一个场景:远程搜索框的下拉列表项不单单能显示文字内容,还要将搜索到的内容的图片显示出来。css
首先,咱们来看一下官网上的这个组件的功能(el-autocomplete),以下图,这个是element-ui官网为咱们提供的远程搜索组件,它可以在咱们输入时,根据输入内容实时从远程服务器获取内容并显示在下拉框中。vue
Element-ui列表中对应的内容显然 是搜索到的内容的value字段,是一个字符串,是没法知足咱们放入图片的需求的。ajax
这时就须要咱们本身去封装一个自定义的能显示图片的远程搜索框了。element-ui
原理其实很简单,主要有这么几点:segmentfault
最终实现效果如图:
代码以下:数组
// 封了一个从服务器远程获取搜索内容的输入框,比autocompleteuole多了在列表中显示图片的功能 <template> <div class="container"> <!-- 输入框 --> <el-input placeholder="输入单词或ID" v-model="obj[name]" @input="onInput" @blur="isShow=false" clearable style="width: 200px" > </el-input> <!-- 下拉列表框 --> <div class="selectLIst" v-if="isShow==true"> <div v-for="item in resultList" :key="item.id" @click="handleSelect(item)" class="item"> <span>{{item.value}}</span> // 文字内容 <img :src="item.picUrl" style="width: 20px; height: 20px; margin-left: 5px"> // 图片 </div> </div> </div> </template> <script> export default { name: 'RemoteSearch', props: { obj: { type: Object }, name: { type: String }, }, data() { return { timer: null, // 这里放外面其实不安全,容易被篡改 resultList: [], // 最终要渲染的内容数组 isShow: false // 控制下拉列表的显示与隐藏 } }, methods: { onInput() { this.isShow = true // 防抖 if(this.timer) { clearTimeout(this.timer) } this.timer = setTimeout(()=>{ this.fetchContent() },800) }, async fetchContent() { this.resultList = [] let queryObj = {type:1} // 判断 queryString是数字仍是单词 if(!isNaN(Number(this.obj[this.name]))) { queryObj.id = this.obj[this.name] } else { queryObj.word = this.obj[this.name] } // 这里写你要请求的地址 const result = await this.$ajax.post( `/admin/incentive/queryRewardDetail`,queryObj ) if (result.data.data) { const res = result.data.data res.forEach(e => { // 这里从返回的结果中选取须要用到的的内容放入resultList this.resultList.push({value: e.id+' '+e.word, picUrl: e.wordPic, id: e.id}) }); } else { this.$message.warning("请求出错!"); } }, handleSelect(item) { this.obj[this.name] = item.id+'' // 选中后给对应字段赋值 this.isShow = false // 选中某一项后隐藏下拉列表框 } } } </script> <style lang="scss" scoped> .container { position: absolute; .selectLIst { position: relative; z-index: 10; background-color: #FFFFFF; box-shadow: 0 4px 3px #C5C5C5; max-height: 200px; overflow: auto; .item { height: 30px; display: flex; align-items: center; justify-content: center; } .item:hover { background-color: #EFEFEF; } } ul { list-style: none // 隐藏无序列表前面的小圆点 } } </style>
直接在须要的页面引入并使用:安全
// item: { word: '' } // 假如你要将input框与item的word属性绑定,则 <RemoteSearch :obj="item" name='word'/>