<template> <div> <el-popover ref="pop" v-model="pop" :placement="placement" width="380" trigger="click"> <div class="header d2-clearfix d2-mb-10" v-if="clearable"> <el-button type="danger" icon="el-icon-delete" size="mini" class="d2-fr" @click="selectIcon()">清空</el-button> </div> <el-input v-model="searchText" :clearable="true" placeholder="搜索 比如 '球机'" prefix-icon="el-icon-search"> </el-input> <el-collapse v-if="!searchMode" class="group" v-model="collapseActive"> <el-collapse-item v-for="(item, index) in iconList" :key="index" :title="item.title" :name="index" class="class"> <el-row class="class-row"> <el-col class="class-col" v-for="(icon, iconIndex) in item.iconList" :key="iconIndex" :span="4" @click.native="selectIcon(icon)"> <el-image :src="icon.icon" fit='scale-down' :title="icon.name"></el-image> </el-col> </el-row> </el-collapse-item> </el-collapse> <div v-if="searchMode" class="group"> <div class="class" v-for="(item, index) in iconFilted" :key="index"> <div class="class-title">{{item.title}}</div> <el-row class="class-row"> <el-col class="class-col" v-for="(icon, iconIndex) in item.iconList" :key="iconIndex" :span="4" @click.native="selectIcon(icon)"> <el-image :src="icon.icon" fit='scale-down' :title="icon.name"></el-image> </el-col> </el-row> </div> </div> </el-popover> <!-- 允许用户输入 --> <el-input v-if="userInput" v-model="currentValue" v-bind="bind" style="max-width: 240px;"> <template v-if="value" slot="prepend"> <!-- <i :class="'fa fa-' + value"></i> --> <el-image class="show-icon" :src="chooseIcon.icon" fit='scale-down' :title="chooseIcon.name"></el-image> </template> <el-button v-popover:pop slot="append"> <!-- <i class="fa fa-list"></i> --> <el-image class="show-icon" :src="chooseIcon.icon" fit='scale-down' :title="chooseIcon.name"></el-image> </el-button> </el-input> <!-- 不允许用户输入 --> <el-button v-popover:pop v-if="!userInput"> <template v-if="value"> <!-- <i :class="'fa fa-' + value"></i> --> <el-image class="show-icon" :src="chooseIcon.icon" fit='scale-down' :title="chooseIcon.name"></el-image> </template> <span class="show-span">{{value ? chooseIcon.name : placeholder}}</span> </el-button> </div> </template> <script> export default { name: 'my-icon-select', props: { // 图标库 iconList: { type: Array, required: false, default: new Array(0) }, // 值 value: { type: String, required: false, default: '' }, // 占位符 placeholder: { type: String, required: false, default: '请选择' }, // 弹出界面的方向 placement: { type: String, required: false, default: 'right' }, // 是否可清空 clearable: { type: Boolean, required: false, default: true }, // 是否允许用户输入 userInput: { type: Boolean, required: false, default: false }, // 是否在选择后自动关闭 autoClose: { type: Boolean, required: false, default: true } }, data () { return { // 绑定弹出框 pop: false, //选中的图标 chooseIcon: {}, // 组件内输入框的值 currentValue: '', // 搜索的文字 searchText: '', // 不是搜索的时候显示的折叠面板绑定的展开数据 collapseActive: [] // collapseActive: [...Array(icon.length)].map((e, i) => i) } }, computed: { // 输入框上绑定的设置 bind () { return { placeholder: this.placeholder, clearable: this.clearable, ...this.$attrs } }, // 是否在搜索 searchMode () { return !!this.searchText }, // 过滤后的图标 iconFilted () { return this.iconList.map(iconClass => ({ title: iconClass.title, iconList: iconClass.iconList.filter(icon => icon.name.indexOf(this.searchText) >= 0) })).filter(iconClass => iconClass.iconList.length > 0) } }, watch: { value (value) { this.currentValue = value }, currentValue (value) { this.selectIcon(null, value) } }, created () { this.currentValue = this.value this.selectIcon(null, this.value) // this.initIconList() }, methods: { // initIconList() { // this.$http({ // url: this.$http.adornUrl(`/liResourceIcon/getIconlist`), // method: 'post', // data: {} // }).then(data => { // if (data && data.code === 0) { // this.iconList = data.list // } // }) // }, selectIcon (icon = {}, path) { if (path) { this.iconList.forEach(item => { item.iconList.forEach(ic => { if (ic.path === path) { this.chooseIcon = ic } }) }) this.$emit('input', path) if (path && this.autoClose) { this.pop = false } } else { this.chooseIcon = icon this.$emit('input', icon.path) if (icon && this.autoClose) { this.pop = false } } } } } </script> <style lang="scss" scoped> @import '~@/assets/style/public.scss'; .group { max-height: 400px; overflow-x: hidden; overflow-y: scroll; border-top: none; border-bottom: none; .class { .class-title { line-height: 30px; text-align: center; background-color: $color-bg; border-radius: 4px; margin: 10px 0px; } .class-row { display: flex; justify-content: flex-start ; align-items: center; flex-wrap:wrap; .class-col { width:50px; height:50px; line-height: 40px; text-align: center; align-items: center; color: $color-text-sub; .el-image{ width:26px; height:26px; &:hover { width:40px; height:40px; } } } } } } .el-button{ padding: 0 20px; height: 40px; .show-icon{ width:26px; height:26px; vertical-align: middle; transform: translateY(-2px); margin-right: 5px; } .show-span{ line-height: 40px; } } </style>