工作生活

1.vue造轮子-button

2019-07-03  本文已影响0人  如梦初醒Tel

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
上一篇下一篇

猜你喜欢

热点阅读