最近开始工作了,其中的一个小任务就是写一个通用的提示组件,产品意思大概就是,鼠标经过提示组件图标,就出现提示信息。

内心os: 太简单啦~

开始动手

<template>
    <div>
        <i @mouseover="showTips()" @mouseout="showTips"></i>
        <p v-if="show">{{tipsMessage}}<p>
    </div>
</template>

showTips() {
    this.show = !this.show;
}

几分钟完成。

然而,带我的看完代码,面色凝重,“不对,你这不对”

“那里不对?”
“我们项目里面有些地方没有用到VUE,那些地方怎么引用?”

为了在非vue的页面也能够使用,决定用动态添加class的方法来做,这样在非vue的页面可以手动去添加class来实现效果。

最终代码:

<template>
        <i :class="{
                'base-tips': true,
                'after-tips': !tipsType,
                'slot-tips': tipsType,
                'hover-tips': !showTips && !tipsType,
                'show-tips': showTips && !tipsType,
                'border-tips': borderTips && !tipsType,
                'tips-icon': showIcon,
                'tips-force-wrap': forceWrap,
                'this-auto-wrap': autoWrap
                }" 
                :value="tips" 
                :style ="{ 
                    maxWidth: maxWidth+'px', 
                    maxHeight: maxHeight + 'px', 
                    minHeight: minHeight+'px',
                    minWidth: minWidth+'px',
                    fontSize: fontSize+'px',
                    color: fontColor }"
                >
            <div v-if="tipsType">
                <p class="slot-box" >
                    <slot></slot>
                </p>
            </div>
        </i>
</template>

<script>
    import Vue from 'vue'
    export default {
        name: "VueTabs",
        props: {
            tipsType: { // 如果是0,就是不用换行自定义
                type: Number,
                default: 0
            },
            tips:{
                type: String,
                default: ""
            },
            showIcon: { //图标是否显示
                type: Boolean,
                default: true
            },
            showTips:{ //提示一开始是否显示
                type: Boolean,
                default: false
            },
            maxHeight: {
                type: Number,
                default: null
            },
            maxWidth: {
                type: Number,
                default: null
            },
            minHeight: {
                type: Number,
                default: null
            },
            minWidth: {
                type: Number,
                default: null
            },
            autoWrap: { //自动换行
                type: Boolean,
                default: true
            },
            forceWrap: { //强制不换行,超出内容....
                type: Boolean,
                default: false
            },
            borderTips: { //是否要border
                type: Boolean,
                default: true
            },
            fontSize: { //字体大小
                type: Number,
                default: 12
            },
            fontColor: {
                type: String,
                default: '#666666'
            }
        },
        data() {
            return {
                isSlot: false
            }
        }
    }
</script>

<style lang="less" rel="stylesheet/less">
.slot-tips{
    .slot-box{
        display: none;
        position: absolute;
        margin: 0 0 0 18px;
        padding: 2px;
        background: #ffffff;
        border: 1px solid #d5d5d5;
        border-radius: 3px;
    }
    &:hover{
        .slot-box{
            display: block;
        }
    }
}
</style>

在使用组件的时候可以自定义组件内部显示的形式,也有默认的形式,大体实现一下功能:

  • 支持Vue和普通页面使用
  • 提示内容支持设置有最大和最小的高度和宽度的限制
  • 图标支持显示隐藏
  • 多种显示方式

    • 一个图标,鼠标移入显示提示内容浮层
    • 直接显示在页面上
  • 是否支持换行

    • 可以换行

      • 超出显示区域自动换行
      • 使用者自主换行
    • 不能换行

      • 超出内容显示区域出现省略号,鼠标移入显示完整内容

小小的组件,其实代码并不复杂,但是在写的时候学会去考虑很多东西,一个好的组件应该是怎样的。
好的组件应该是通用的,在写的时候应该去考虑各种使用环境。


oylp
365 声望17 粉丝

只是一个普普通通喜欢吃脂肪还长肉的人