仿element-ui 实现自己组件库 <3>

目录

[input 组件封装](#input 组件封装)

v-model用在组件上

显示和隐藏密码

封装switch组件

实现转换的功能

设置checkbox


input 组件封装

首先input组件的基本框架和样式:

html 复制代码
<div class="miao-input">
        <input class="miao-input_inner" >
</div>
        
css 复制代码
<style lang="scss" scoped>
 .miao-input {
     width: 100%;
     position: relative;
     font-size: 14px;
     display: inline-block;

     .miao-input_inner {
         -webkit-appearance: none;
         background-color: #fff;
         background-image: none;
         border: 1px solid #dcdfe6;
         border-radius: 4px;
         box-sizing: border-box;
         color: #606266;
         display: inline-block;
         font-size: inherit;
         height: 40px;
         line-height: 40px;
         outline: none;
         padding: 0 15px;
         transition: border-color .2s cubic-bezier(.645, 045, .355, 1);
         width: 100%;

         &:focus {
             outline: none;
             border-color: #409eff;
         }

         // input禁用样式
         &.is-disabled {
             background-color: #f5f7fa;
             border-color: #e4e7ed;
             color: #c0c4cc;
             cursor: not-allowed;
         }
     }
 }

 // 后面加suffix的意思是后面如果有后缀的话,触发该样式
 .miao-input_suffix {
     .miao-input_inner {
         padding-right: 30px;
     }

     .miao-input_suffix {
         position: absolute;
         right: 10px;
         height: 100%;
         top: 0;
         line-height: 40px;
         text-align: center;
         color: #c0c4cc;
         transition: all .3s;
         z-index: 900;

         i {
             color: #c0c4cc;
             font-size: 14px;
             cursor: pointer;
             transition: color .2s cubic-bezier(.645, .045, .355, 1);
         }
     }
 }
</style>

v-model用在组件上

首先app.vue里:

html 复制代码
<miao-input v-model="username">
</miao-input>
javascript 复制代码
data(){
return {
username:'ss'
}
}

在input.vue里:

javascript 复制代码
props:{
value:{
type:String,
default:''
}
}
html 复制代码
 <input class="miao-input_inner" 
        :class="{'is-disabled': disabled}"
        :placeholder="placeholder" :type="type" :name="name"
            :disabled="disabled"
            :value="value"
                    
            >

除了value之外还要触发事件

html 复制代码
@input="handleinput"   
javascript 复制代码
methods:{
        handleinput(e){
// this.value=e.target.value是不行的因为直接改了父组件传的参数
this.$emit('input',e.target.value)
// 触发这个事件

        }
    }

添加图标

html 复制代码
<span class="miao-input_suffix">
            <i class="miao-input_icon miao-icon-cancel" v-if="clearable" @click="clear"></i>
            <i class="miao-input_icon miao-icon-visible" v-if="showPassword"></i>
        </span>
html 复制代码
<div class="miao-input" :class="{'miao-input_suffix': showSuffix}">
javascript 复制代码
computed:{
  showSuffix(){
            return this.clearable || this.showPassword
  }
    },

点击图标清空内容:

javascript 复制代码
 clear(){
            this.$emit('input','')
            // 父组件就会清空
        }

显示和隐藏密码

html 复制代码
<i class="miao-input_icon miao-icon-visible" v-if="showPassword" @click="handlePassword"></i>
javascript 复制代码
 :type="showPassword ? (passwordVisible ? 'text':'password'):type"

如果传来show-password判断是否需要切换密码显示,如果不传不判断

封装switch组件

只要是表单元素都支持name属性

switch初始模版:

html 复制代码
<template>
    <div class="one-switch">
        <span class="one-switch_core">
            <span class="one-switch_button"></span>
        </span>
    </div>
</template>

css:

css 复制代码
.miao-switch {
    display: inline-block;
    align-items: center;
    position: relative;
    font-size: 14px;
    line-height: 20px;
    vertical-align: middle;

    .miao-switch_core {
        margin: 0;
        display: inline-block;
        position: relative;
        width: 40px;
        height: 20px;
        border: 1px solid #dcdfe6;
        outline: none;
        border-radius: 10px;
        box-sizing: border-box;
        background: #dcdfe6;
        cursor: pointer;
        transition: border-color .3s, background-color .3s;
        vertical-align: middle;

        .miao-switch_button {
            position: absolute;
            top: 1px;
            left: 1px;
            border-radius: 100%;
            transition: all .3s;
            width: 16px;
            height: 16px;
            background-color: #fff;
        }
    }
}

// 选中样式
.is-checked {
    .miao-switch_core {
        border-color: #409eff;
        background-color: #409eff;

        .miao-switch_button {
            transform: translateX(20px);
        }
    }
}

// 隐藏input标签
.miao-switch_input {
    position: absolute;
    width: 0;
    height: 0;
    opacity: 0;
    margin: 0;
}

v-model绑定组件里的value和触发的事件:

javascript 复制代码
props:{
        value:{
            type:Boolean,
            default:false
        }
    },
    methods:{
        handleClick(){
            this.$emit('input',!this.value)
        }
    }

实现转换的功能

html 复制代码
<label class="miao-switch" :class="{'is-checked': value}" @click="handleClick">
css 复制代码
// 选中样式
.is-checked {
    .miao-switch_core {
        border-color: #409eff;
        background-color: #409eff;

        .miao-switch_button {
            transform: translateX(20px);
        }
    }
}

根据传入switch.vue的两个颜色来控制:

nexttick是基于promsie的封装,这里用语法糖async和await,用nexttick等数据修改后dom更新完毕再更改按钮颜色

javascript 复制代码
methods:{
        async handleClick(){
            this.$emit('input',!this.value)
            //点击时候还要修改背景色
            //等待value发生变化再setcolor
            //把数据改了发生更新
            //nexttick基于promise封装
            //数据修改后等待dom更新再修改按钮颜色
         await this.$nextTick()
         this.setColor()

        },
        setColor() {
            //修改开关颜色,必须传入其一的颜色
            if (this.activeColor || this.inactiveColor) {
                let color = this.value ? this.activeColor : this.inactiveColor
                this.$refs.core.style.borderColor = color
                this.$refs.core.style.backgroundColor = color

            }
        }

    },
    mounted(){
        this.setColor()
    }

设置checkbox

用户使用switch组件实际上当成表单元素使用,可能用到name属性,需要在switch组件中添加一个checkbox,当值改变时候,需要设置checkbox的value值

同步checkbox里的checked值,一进来mounted和切换时候设置值

点击label相当于点击input框

html 复制代码
<!-- 外面的大框架如果用label会触发两次,抵消了 -->
        <input class="miao-switch_input" type="checkbox" :name="name" ref="input">
javascript 复制代码
 async handleClick(){
            this.$emit('input',!this.value)
            //点击时候还要修改背景色
            //等待value发生变化再setcolor
            //把数据改了发生更新
            //nexttick基于promise封装
            //数据修改后等待dom更新再修改按钮颜色
         await this.$nextTick()
         this.setColor()
            this.$refs.input.checked = this.value

        },
javascript 复制代码
mounted(){
        this.setColor()
        //控制checkbox的值
        this.$refs.input.checked=this.value
        //input值和value同步


    }

具体代码:

GitHub - Alicca-miao/component-library-vue-ui-Contribute to Alicca-miao/component-library-vue-ui- development by creating an account on GitHub.https://github.com/Alicca-miao/component-library-vue-ui-

相关推荐
也无晴也无风雨1 小时前
深入剖析输入URL按下回车,浏览器做了什么
前端·后端·计算机网络
Martin -Tang2 小时前
Vue 3 中,ref 和 reactive的区别
前端·javascript·vue.js
FakeOccupational3 小时前
nodejs 020: React语法规则 props和state
前端·javascript·react.js
放逐者-保持本心,方可放逐3 小时前
react 组件应用
开发语言·前端·javascript·react.js·前端框架
曹天骄4 小时前
next中服务端组件共享接口数据
前端·javascript·react.js
阮少年、4 小时前
java后台生成模拟聊天截图并返回给前端
java·开发语言·前端
郝晨妤6 小时前
鸿蒙ArkTS和TS有什么区别?
前端·javascript·typescript·鸿蒙
AvatarGiser6 小时前
《ElementPlus 与 ElementUI 差异集合》Icon 图标 More 差异说明
前端·vue.js·elementui
喝旺仔la6 小时前
vue的样式知识点
前端·javascript·vue.js
别忘了微笑_cuicui6 小时前
elementUI中2个日期组件实现开始时间、结束时间(禁用日期面板、控制开始时间不能超过结束时间的时分秒)实现方案
前端·javascript·elementui