美文网首页工作生活
1.vue造轮子-button

1.vue造轮子-button

作者: 如梦初醒Tel | 来源:发表于2019-07-03 17:12 被阅读0次

    icon如何使用

    使用icon 推荐网站

    插槽的用处

    <div id="app">
        <g-button>我爱JS</g-button>
    </div>
    

    如上所示,父组件中插入文字我爱JS,然后子组件必须要有slot标签,用来接收父组件传来的文字

    <template>
        <button class="g-button" >
            <svg class="icon" aria-hidden="true">
                <use :xlink:href="`#i-${icon}`"></use>
            </svg>
            <slot></slot>//重点
        </button>
    </template>
    

    其中以上代码中,对于传入的不同svg标签名如何做呢?
    简单的方法就是 父组件中传入svg的名称,子组件根据父组件传来的名称设置不同的svg
    <use :xlink:href="`#i-${icon}`"></use>

    在script中要设置props接收父组件传来的参数

    <script>
        export default {
            props: ['icon']
        }
    </script>
    

    收到参数之后通过 #i-${icon}中,来获取参数

    在这里面的有点毛病,就是不传svg标签的话就是会有空格,难看的很

    优化思路

    image.png

    做出上图的效果图

    第一种:没有svg的时候
    第二种:有svg的时候,但是还要position是在left还是right

    第一种思路

    使用v-if来判断传进来的参数中有没有icon,没有就不显示svg标签

    <template>
        <button class="g-button">
            <svg v-if="icon" class="icon" aria-hidden="true">
                <use :xlink:href="`#i-${icon}`"></use>
            </svg>
            <slot></slot>
         </button>
    </template>
    
    <div id="app">
        <g-button>我爱JS</g-button>
        <g-button icon="setting">我爱JS</g-button>
    </div>
    
    image.png

    第二种思路

    这里面一定要接收两个参数,分别是svg标签和position的位置

    在这里面有两种做法

    第一种做法
    <template>
        <button class="g-button" v-if="iconPoition ==='right' ">
           <slot></slot>
            <svg v-if="icon" class="icon" aria-hidden="true">
                <use :xlink:href="`#i-${icon}`"></use>
            </svg>
           </button>
          <button class="g-button" v-else>
            <svg v-if="icon" class="icon" aria-hidden="true">
                <use :xlink:href="`#i-${icon}`"></use>
            </svg>
             <slot></slot>
           </button>
    </template>
    
    <div id="app">
        <g-button>我爱JS</g-button>
        <g-button icon="setting">我爱JS</g-button>
        <g-button icon="setting" icon-position="right">我爱JS</g-button>
    </div>
    

    如果是新手,这样写也没毛病,就是有点重复代码。

    第二种做法

    通过控制css来实现

    <template>
        <button class="g-button" :class="{[`icon-${iconPosition}`]:true}">
            <svg v-if="icon" class="icon" aria-hidden="true">
                <use :xlink:href="`#i-${icon}`"></use>
            </svg>
            <div class="content">
                <slot></slot>
            </div>
        </button>
    </template>
    
    <script>
        export default {
            props: ['icon', 'iconPosition']
        }
    </script>
    
    <style lang="scss">
        .g-button {
            font-size: inherit;
            height: var(--button-height);
            padding: 0 1em; /*没有写width*/
            border-radius: var(--border-radius);
            border: 1px solid var(--border-color);
            background: var(--button-bg);
            display: inline-flex;
            justify-content: center;
            align-items: center;
            vertical-align: top;
    
            &:hover {
                border-color: var(--border-color-hover);
            }
    
            &:active {
                background-color: var(--button-active-bg)
            }
    
            /*获取button的焦点,外面的连线(轮廓)为空,去掉选中的时候就会出现的蓝色框*/
            &:focus {
                outline: none;
            }
    
            > .icon {
                order: 1;
            }
    
            > .content {
                order: 2;
            }
    
            &.icon-right {
                > .icon {
                    order: 2;
                }
    
                > .content{
                    order: 1;
                }
            }
        }
    </style>
    

    在这里面通过 :class 来接收position位置,其中
    {[`icon-${iconPosition}`]:true}

    就相当于

    image.png

    通过控制右边的位置来控制 svg 的位置

    在上面代码中,将button标签设置成

            display: inline-flex;
            justify-content: center;
            align-items: center;
    
    image.png

    最后出现的效果是这样的,这是css文字的问题,不懂的话就去看看css深入浅出(2)这篇文章

    解决方法:va:t 或者 va:m
    以后遇到上下不对齐的时候就添加这几个,没有为什么,唯有经验而已

    /*vertical-align: top;*/
    vertical-align: middle;
    
    image.png

    继续优化

    image.png
    <script>
        export default {
            // props: ['icon', 'iconPosition']
            props: {
                icon:{},
                iconPosition:{
                    type:String,
                    default:'left'
                }
            }
        }
    </script>
    

    原来的时候对传来的参数不做限制,现在限制传来的参数是String类型,并且设置默认值是left

    万一总有sb喜欢用up怎么办???

    使用validator校验

    <div id="app">
        <g-button>按钮</g-button>
        <g-button icon="setting" icon-position="left">按钮</g-button>
        <g-button icon="setting" icon-position="up">按钮</g-button>
    </div>
    
        export default {
            // props: ['icon', 'iconPosition']
            props: {
                icon:{},
                iconPosition:{
                    type:String,
                    default:'left',
                    validator(value){
                        console.log(value);
                        if (value !=='left' && value !=='right'){
                            return false
                        }else {
                            return true
                        }
                    }
                }
            }
        }
    
    image.png

    上面报错说不是合法的属性,修改up 为right就ok了

    简化写法

    validator(value){
         return value === 'left' || value === 'right';
    }
    
    image.png

    相关文章

      网友评论

        本文标题:1.vue造轮子-button

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