Vue 实现图片下拉选择控件

element-ui 的组件库中没有图片下拉选择组件,基于 el-select 组件做的改动并不能完全满足需求,因此决定重写一个。

从头到尾做下来收获很多,我决定把实现过程中遇到的问题记录一下。

效果图

在线试用地址

设计要点

接下来将上面代码中的关键部分拆分介绍

1. 回显选中的图片和 label

下拉选项组件的本质是一个 input,毕竟下拉选择也是为了快速 input 嘛。那我们的设计理念就是 “以 input 为中心”,input 左侧留出固定的宽度回显选择的图片,input 的右侧留出固定宽度显示 icon,提醒用户支持下拉/搜索。

为了在输入框左侧显示图片,我们设置图片元素为 position: absolute; input 元素通过设置 padding-leftpadding-right 将 image 和 icon 的空间预留出。

右侧默认显示下拉 icon,当显示下拉选项时切换为搜索 icon,提示用户输入框支持搜索功能。

图片[1]-Vue 实现图片下拉选择控件 - 玄机博客-玄机博客

2. 下拉选项

点击选择控件时显示下拉选项,选择某个选项或者点击页面空白处时隐藏下拉选项。

下拉选项中依次显示选项的 image、选项的 label,选项的 category。

已选中的选项要区别于未选中的选项,这里用到了动态 css 绑定,通过比较 selectedOption.key 和 option.key 是否相等来判断选中状态。

{{ option.label }}
{{ option.type }}
.selected-option {
    background-color: #f5f7fa;
}

为了保证每个 image 占据相同的宽度,label 有相同的缩进,为 image 设置了 max-widthmin-width 为相同值:

.select-option-icon-container {
    min-width: 60px;
    max-width: 60px;
    height: 100%;
}

下拉选项 list 要设置 max-heightoverflow-y:auto,防止选项较多时占据太多页面空间。微调滚动条的显示样式:

/* 滚动条整体样式 */
.select-option-list::-webkit-scrollbar {
    width: 6px;
}
/* 滚动条轨道样式 */
.select-option-list::-webkit-scrollbar-track {
    background: #f1f1f1;
    border-radius: 6px;
}
/* 滚动条滑块样式 */
.select-option-list::-webkit-scrollbar-thumb {
    background: #dadcdd;
    border-radius: 6px;
}
/* 滑块 hover 样式 */
.select-option-list::-webkit-scrollbar-thumb:hover {
    background: #999;
}

3. 支持搜索

当用户输入了搜索内容时(@input),希望显示过滤后的选项以快速定位;当我们点击控件时,一般是有选项切换的需求,此时需要显示全部的选项,通过 showAllOptions 来控制是否显示全部的选项。

图片[1]-Vue 实现图片下拉选择控件 - 玄机博客-玄机博客

4. 组件数据传递

父组件传递 options 选项给子组件,子组件将选中的选项通知给父组件:

export default {
    props: {
        // 父组件传递来的所有选项
        options: {
            type: Array,
            required: true
        }
    },
    data () {
        return {
            // 选择的选项
            selectedOption: this.options[0]
        }
    },
    methods: {
        // 点击某个选项时
        selectOption (option) {
            this.selectedOption = option
            this.showSelectOptions = false
            this.inputContent = option.label
            // 将选择的选项通知给父组件
            // v-model 默认监听input事件
            this.$emit('input', option)
        }
    }
}

完整实现

ImgSelect.vue




在父组件中使用:



玄机博客
© 版权声明
THE END
喜欢就支持一下吧
点赞5 分享
评论 抢沙发
头像
欢迎您留下宝贵的见解!
提交
头像

昵称

取消
昵称表情代码图片快捷回复

    暂无评论内容