使用div自定义一个el-select(可轻松改变text文本的背景颜色)

184 阅读2分钟

前言:
使用elementui封装的el-select不能改变选中文本的背景颜色(原因是该文本的dom标签压根就没有插入到body中),只能改变整个input框的背景色,所以本文将使用div标签封装一个el-select

效果如下:

donghua.gif

子组件CustomSelect

<template>
    <div id="container">
        <div class="c-select" @click="showDropDownList" :class="{ 'c-select-active': isShowPopup }"
            :style="{ width: selectWidth, height: selectHeight,'line-height':selectHeight }">
            <div class="default-placeholder" :style="{ 'background-color': defaultBgColor }">{{ defaultValue }}</div>
            <div>
                <i class="iconfont icon-a-xiala2" :class="{ 'triangle-rotate': isShowPopup }"></i>
            </div>
        </div>
        <transition name="bounce" mode="out-in">
            <div class="popup-div" v-if="isShowPopup" :style="{width:selectWidth}">
                <div class="popup-div-item" :class="{ 'active-bgcolor': cur === index }" @click="getTagetValue(option)"
                    @mouseenter="cur = index" @mouseleave="cur = ''" v-for="(option, index) in options" :key="index">
                    <span class="text" :style="{ 'background-color': option.bgcolor }">{{ option.label }}</span>
                </div>
            </div>
        </transition>
    </div>
</template>
  
<script>
export default {
    props: {
        options: {
            type: Array,
            default: []
        },
        selectedValue: {
            type: String,
            default: ""
        },
        selectHeight: {
            type: String,
            default: ''
        },
        selectWidth: {
            type: String,
            default: ''
        },
    },
    data() {
        return {
            cur: '',
            defaultValue: '', //默认选中的字
            defaultBgColor: '', //默认选中字的背景颜色
            isShowPopup: false,
        }
    },
    methods: {
        //选中option标签获取值
        getTagetValue(option) {
            console.log(option);
            this.defaultValue = option.label;
            this.defaultBgColor = option.bgcolor;
            this.isShowPopup = false;
        },
        showDropDownList() {
            this.isShowPopup = !this.isShowPopup;
        },
        changeBackgroundColor() {
        },
        removeBackgroundColor() {
        }
    },
    watch: {
        selectedValue: {
            handler(val) {
                this.defaultValue = val;
            },
            immediate: true
        }
    }
}
</script>

<style lang="scss" scoped>
.icon-a-xiala2 {
    color: #999999;
    transition: all 0.3s;
    display: inline-block;
}

.triangle-rotate {
    transform: rotate(180deg);
}

.bounce-enter,
.bounce-leave-to {
    opacity: 0;
    /* 初始时不可见 */
}

.bounce-enter-active,
.bounce-leave-active {
    transition: all 0.3s ease;
    /* 添加过渡效果 */
}

/*从上到下*/
@keyframes fadeInDown {
    from {
        opacity: 0;
        transform: translate(-50%, -30px);
    }

    to {
        opacity: 1;
        transform: translate(-50%, 0px);
    }
}

.bounce-enter-active {
    animation: fadeInDown 0.3s;
}

.bounce-leave-active {
    animation: fadeInDown 0.3s reverse;
}

#container {
    margin: 300px;
    width: 200px;
    position: relative;

    .c-select {
        transition: all .3s ease;
        cursor: pointer;
        // height: 40px;
        // line-height: 40px;
        box-sizing: border-box;
        display: flex;
        justify-content: space-between;
        align-items: center;
        padding: 0 15px;
        // width: 200px;
        border-radius: 4px;
        border: 1px solid #dcdfe6;

        .default-placeholder {
            background-color: #00C600;
            color: #ffffff;
            border-radius: 4px;
            width: 64px;
            height: 24px;
            line-height: 24px;
            text-align: center;
        }
    }

    .c-select-active {
        border-color: #409eff;
    }

    .popup-div {

        box-shadow: 0px 0px 8px rgba(0, 0, 0, 0.15);
        position: absolute;
        top: 55px;
        left: 50%;
        /* 将弹框水平居中 */
        transform: translateX(-50%);
        /* 将弹框垂直居中 */
        // width: 200px;
        height: auto;
        border: 1px solid #eee;
        box-shadow: 0px 1px 3px 1px #eee;
        border-radius: 4px;
        text-align: center;
        border: 1px solid #eee;

        .active-bgcolor {

            background: rgba(0, 162, 255, 0.1);
        }

        .popup-div-item {

            width: 100%;
            height: 35px;
            line-height: 35px;
            cursor: pointer;
            margin-top: 5px;


            .text {
                display: inline-block;
                background-color: #00C600;
                width: 64px;
                height: 24px;
                line-height: 24px;
                text-align: center;
                color: #ffffff;
                border-radius: 4px;
            }
        }

    }

    .popup-div::before {
        content: "";
        position: absolute;
        left: -12px;
        top: -56px;
        width: 10px;
        height: 10px;
        margin: 50px;
        transform: rotate(45deg);
        background: #fff;
        z-index: 0;
        border-top: 2px solid #eee;
        border-left: 2px solid #eee;
    }

}
</style>

父组件调用

<template>
   <div class="app-container">
      <CustomSelect :options="options" :selectedValue="selectedValue" :selectWidth="selectWidth" :selectHeight="selectHeight"></CustomSelect>
    </div>
</template>

<script>
import CustomSelect from '@/components/CustomSelect'
export default {
  components: {
    CustomSelect
  },
  data() {
    return {
      options: [{
        value: 'normal',
        label: '正常',
        bgcolor: '#00C600'
      }, {
        value: 'warn',
        label: '预警',
        bgcolor: '#FF8000'
      }, {
        value: 'delay',
        label: '延期',
        bgcolor: '#BA0000'
      }],
      selectedValue: '正常',
      selectWidth: '200px',
      selectHeight: '40px'
    }
  }
}
</script>

<style scoped lang="scss">
.app-container {}
</style>