找回密码
 立即注册
首页 业界区 业界 Vue 实现图片下拉选择控件

Vue 实现图片下拉选择控件

赶塑坠 3 天前
1.png

element-ui 的组件库中没有图片下拉选择组件,基于 el-select 组件做的改动并不能完全满足需求,因此决定重写一个。
从头到尾做下来收获很多,我决定把实现过程中遇到的问题记录一下。
效果图

在线试用地址
2.gif
设计要点

接下来将上面代码中的关键部分拆分介绍
1. 回显选中的图片和 label

下拉选项组件的本质是一个 input,毕竟下拉选择也是为了快速 input 嘛。那我们的设计理念就是 "以 input 为中心",input 左侧留出固定的宽度回显选择的图片,input 的右侧留出固定宽度显示 icon,提醒用户支持下拉/搜索。
3.png
为了在输入框左侧显示图片,我们设置图片元素为 position: absolute; input 元素通过设置 padding-left 和 padding-right 将 image 和 icon 的空间预留出。
右侧默认显示下拉 icon,当显示下拉选项时切换为搜索 icon,提示用户输入框支持搜索功能。
  1.    
  2.         <img  :src="selectedOption.icon" />
  3.    
  4.     <input v-model="inputContent"  />
  5.    
  6.         
  7.         
  8.    
复制代码
2. 下拉选项

点击选择控件时显示下拉选项,选择某个选项或者点击页面空白处时隐藏下拉选项。
下拉选项中依次显示选项的 image、选项的 label,选项的 category。
5.png
已选中的选项要区别于未选中的选项,这里用到了动态 css 绑定,通过比较 selectedOption.key 和 option.key 是否相等来判断选中状态。
  1.    
  2.         
  3.             <img v-if="option.icon" :src="option.icon" :alt="option.label"  />
  4.         
  5.         
  6.             {{ option.label }}
  7.             {{ option.type }}
  8.         
  9.    
复制代码
  1. .selected-option {
  2.     background-color: #f5f7fa;
  3. }
复制代码
为了保证每个 image 占据相同的宽度,label 有相同的缩进,为 image 设置了 max-width 和 min-width 为相同值:
  1. .select-option-icon-container {
  2.     min-width: 60px;
  3.     max-width: 60px;
  4.     height: 100%;
  5. }
复制代码
下拉选项 list 要设置 max-height 和 overflow-y:auto,防止选项较多时占据太多页面空间。微调滚动条的显示样式:
  1. /* 滚动条整体样式 */
  2. .select-option-list::-webkit-scrollbar {
  3.     width: 6px;
  4. }
  5. /* 滚动条轨道样式 */
  6. .select-option-list::-webkit-scrollbar-track {
  7.     background: #f1f1f1;
  8.     border-radius: 6px;
  9. }
  10. /* 滚动条滑块样式 */
  11. .select-option-list::-webkit-scrollbar-thumb {
  12.     background: #dadcdd;
  13.     border-radius: 6px;
  14. }
  15. /* 滑块 hover 样式 */
  16. .select-option-list::-webkit-scrollbar-thumb:hover {
  17.     background: #999;
  18. }
复制代码
3. 支持搜索

当用户输入了搜索内容时(@input),希望显示过滤后的选项以快速定位;当我们点击控件时,一般是有选项切换的需求,此时需要显示全部的选项,通过 showAllOptions 来控制是否显示全部的选项。
  1.    
  2.         <img  :src="selectedOption.icon" />
  3.    
  4.     <input v-model="inputContent"  />
  5.    
  6.         
  7.         
  8.    
复制代码
4. 组件数据传递

父组件传递 options 选项给子组件,子组件将选中的选项通知给父组件:
  1. export default {
  2.     props: {
  3.         // 父组件传递来的所有选项
  4.         options: {
  5.             type: Array,
  6.             required: true
  7.         }
  8.     },
  9.     data () {
  10.         return {
  11.             // 选择的选项
  12.             selectedOption: this.options[0]
  13.         }
  14.     },
  15.     methods: {
  16.         // 点击某个选项时
  17.         selectOption (option) {
  18.             this.selectedOption = option
  19.             this.showSelectOptions = false
  20.             this.inputContent = option.label
  21.             // 将选择的选项通知给父组件
  22.             // v-model 默认监听input事件
  23.             this.$emit('input', option)
  24.         }
  25.     }
  26. }
复制代码
完整实现

ImgSelect.vue
  1.                                 
  2.         <img  :src="selectedOption.icon" />
  3.    
  4.     <input v-model="inputContent"  />
  5.    
  6.         
  7.         
  8.                                                                                                                                                                                             [align=center][img]https://www.33rz.com/option.icon[/img][/align]                                                    {{ option.label }}                    {{ option.type }}                                       
复制代码
  1. [/code][code]
复制代码
在父组件中使用:
  1. <template>
  2.    
  3.         <img-select v-model="selectedDatasource" :options="datasourceOptions"></img-select>
  4.    
  5. </template>
复制代码
[code][/code]
来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
您需要登录后才可以回帖 登录 | 立即注册