美文网首页
制作iconpicker图标选择器组件

制作iconpicker图标选择器组件

作者: 谢_ffd1 | 来源:发表于2020-12-24 17:01 被阅读0次

    组件制作目的

    方便直观的选择所需要的图标

    组件效果图

    image.png

    组件代码

    <template>
        <div class="iconpicker"  v-clickoutside="handleClose">
            <div class="iconpicker-item">
                <div class="iconpicker-icon"><i :class="value"></i></div>
                <div style="flex: 1" @click="collapse = !collapse">
                    <i :class="collapse?'edge':''" class="el-icon-caret-bottom"></i>
                </div>
            </div>
            <div class="anim" v-show="collapse">
                <div class="iconpicker-body">
                    <div class="iconpicker-search">
                        <el-input placeholder="请输入样式名模糊查询" v-model="searchIcon" class="form-input__medium" :disabled="disabled">
                            <i slot="prefix" class="el-input__icon el-icon-search"></i>
                        </el-input>
                    </div>
                    <div class="iconpicker-list-box">
                        <div class="iconpicker-list">
                            <div class="iconpicker-icon-limit">
                                <div class="iconpicker-icon-item" v-for="(icon,index) in data" :key="index"
                                     @click="handleSelect(icon)"><i :class="icon"></i></div>
                            </div>
                        </div>
                        <div class="iconpicker-page">
                            <div class="iconpicker-page-count"><span>{{pageNo}}</span>/<span>{{totalPage}}</span> (<span>{{total}}</span>)
                            </div>
                            <div class="iconpicker-page-operate"><i class="el-icon-arrow-left" @click="handleLeft"></i> <i
                                    class="el-icon-arrow-right" @click="handleRight"></i></div>
                        </div>
                    </div>
                </div>
            </div>
        </div>
    </template>
    
    <script>
        import Clickoutside from 'element-ui/src/utils/clickoutside';
    
        export default {
            name: "IconPicker",
            data() {
                return {
                    allData: [],
                    searchData: [],
                    data: [],
                    collapse: false,
                    pageNo: 1,
                    pageSize: 12,
                    searchIcon: ''
                }
            },
            props: {
                value: String,
                disabled: Boolean,
            },
            directives: { Clickoutside },
            computed: {
                totalPage() {
                    return this.searchIcon ? parseInt(this.searchData.length / this.pageSize) : parseInt(this.allData.length / this.pageSize);
                },
                total() {
                    return this.searchIcon ? this.searchData.length : this.allData.length;
                },
                allList() {
                    return this.searchIcon ? this.searchData : this.allData;
                }
            },
            watch: {
                searchIcon(val) {
                    let reg = new RegExp(val);
                    let data = [];
                    this.allData.forEach(item => {
                        if (reg.test(item)) {
                            data.push(item);
                        }
                    });
                    this.searchData = data;
                    let start = (this.pageNo-1) * this.pageSize;
                    this.data = this.searchData.slice(start, start + this.pageSize);
                }
            },
            methods: {
                //减减
                handleLeft() {
                    if (this.pageNo > 1) {
                        this.pageNo--;
                        let start = (this.pageNo - 1) * this.pageSize;
                        this.data = this.allList.slice(start, start + this.pageSize);
                    }
                },
                //加加
                handleRight() {
                    if (this.pageNo < this.totalPage) {
                        this.pageNo++;
                        let start = (this.pageNo - 1) * this.pageSize;
                        this.data = this.allList.slice(start, start + this.pageSize);
                    }
                },
                //确认选择
                handleSelect(icon) {
                    this.collapse = false;
                    if(!this.disabled){
                        this.$emit('input', icon);
                    }
                },
                handleClose(){
                    this.collapse = false;
                }
            },
            created() {
                document.styleSheets.forEach(obj => {
                    obj.cssRules.forEach(item => {
                        if (item.selectorText) {
                            //Element-ui内置图标 ||  //自定义图标元素
                            if (item.selectorText.search(/^.el-icon-/) != -1 || item.selectorText.search(/^.sx-icon-/) != -1) {
                                let icon = item.selectorText.split(':')[0].split('.')[1];
                                if(!this.allData.includes(icon)){
                                    this.allData.push(icon)
                                }
                            }
                        }
                    })
                });
                let start = this.pageNo * this.pageSize;
                this.data = this.allData.slice(start, start + this.pageSize);
            }
        }
    </script>
    
    <style scoped lang="less" type="text/less">
        .iconpicker {
            position: relative;
            max-width: 280px;
        }
    
        .iconpicker-item {
            border: 1px solid #e6e6e6;
            width: 90px;
            height: 38px;
            border-radius: 4px;
            cursor: pointer;
            position: relative;
            display: flex;
            text-align: center;
            align-items: center;
        }
    
        .iconpicker-icon {
            border-right: 1px solid #e6e6e6;
            -webkit-box-sizing: border-box;
            -moz-box-sizing: border-box;
            box-sizing: border-box;
            width: 60px;
            height: 100%;
            background: #fff;
            transition: all .3s;
        }
    
        .iconpicker-item i {
            line-height: 38px;
            font-size: 18px;
        }
    
        .iconpicker-item:hover {
            border-color: #D2D2D2 !important;
        }
    
        .iconpicker-item:hover .iconpicker-icon {
            border-color: #D2D2D2 !important;
        }
    
        .iconpicker-item .el-icon-caret-bottom {
            transition: all .3s
        }
    
        .iconpicker-item .edge {
            transform: rotate(180deg);
        }
    
        .iconpicker .anim {
            position: absolute;
            left: 0;
            top: 42px;
            padding: 5px 0;
            z-index: 2000;
            min-width: 100%;
            border: 1px solid #d2d2d2;
            max-height: 300px;
            overflow-y: auto;
            background-color: #fff;
            border-radius: 2px;
            box-shadow: 0 2px 4px rgba(0, 0, 0, .12);
            box-sizing: border-box;
        }
    
        .iconpicker-body {
            padding: 6px;
        }
    
        .iconpicker-search {
            position: relative;
            margin: 0 0 6px 0;
        }
    
        .iconpicker-search:hover {
            border-color: #D2D2D2 !important;
        }
    
        .iconpicker .iconpicker-list {
            background-color: #fff;
            border: 1px solid #ccc;
            border-radius: 4px;
            padding-left: 15px;
        }
    
        .iconpicker .iconpicker-icon-item {
            display: inline-block;
            width: 21.1%;
            line-height: 36px;
            text-align: center;
            cursor: pointer;
            vertical-align: top;
            height: 36px;
            margin: 4px;
            border: 1px solid #ddd;
            border-radius: 2px;
            transition: 300ms;
        }
    
        .iconpicker .iconpicker-icon-item i {
            font-size: 17px;
        }
    
        .iconpicker .iconpicker-icon-item:hover {
            background-color: #eee;
            border-color: #ccc;
            -webkit-box-shadow: 0 0 2px #aaa, 0 0 2px #fff inset;
            -moz-box-shadow: 0 0 2px #aaa, 0 0 2px #fff inset;
            box-shadow: 0 0 2px #aaa, 0 0 2px #fff inset;
            text-shadow: 0 0 1px #fff;
        }
    
        .iconpicker-page {
            margin-top: 6px;
            margin-bottom: -6px;
            display: flex;
            font-size: 12px;
            padding: 0 2px;
            justify-content: space-between;
        }
    
        .iconpicker-page-operate {
            cursor: pointer;
        }
    </style>
    
    

    组件使用

    <icon-picker v-model="form.icon"></icon-picker>
    

    相关文章

      网友评论

          本文标题:制作iconpicker图标选择器组件

          本文链接:https://www.haomeiwen.com/subject/yuwnektx.html