从0搭建vue3组件库Input组件

本篇文章将为我们的组件库添加一个新成员:Input组件。其中Input组件要实现的功能有:

  • 基础用法
  • 禁用状态
  • 尺寸大小
  • 输入长度
  • 可清空
  • 密码框
  • 带Icon的输入框
  • 文本域
  • 自适应文本高度的文本域
  • 复合型输入框

每个功能的实现代码都做了精简,方便大家快速定位到核心逻辑,接下来就开始对这些功能进行一一的实现。

基础用法

首先先新建一个input.vue文件,然后写入一个最基本的input输入框


然后在我们的 vue 项目examples下的app.vue引入Input组件



此时页面上便出现了原生的输入框,所以需要对这个输入框进行样式的添加,在input.vue同级新建style/index.less,Input样式便写在这里

.k-input {
  font-size: 14px;
  display: inline-block;
  position: relative;

  .k-input__inner {
    background-color: #fff;
    border-radius: 4px;
    border: 1px solid #dcdfe6;
    box-sizing: border-box;
    color: #606266;
    display: inline-block;
    font-size: inherit;
    height: 40px;
    line-height: 40px;
    outline: none;
    padding: 0 15px;
    width: 100%;
    &::placeholder {
      color: #c2c2ca;
    }

    &:hover {
      border: 1px solid #c0c4cc;
    }

    &:focus {
      border: 1px solid #409eff;
    }
  }
}

从0搭建vue3组件库Input组件_第1张图片

接下来要实现Input组件的核心功能:双向数据绑定。当我们在 vue 中使用input输入框的时候,我们可以直接使用v-model来实现双向数据绑定,v-model其实就是value @input结合的语法糖。而在 vue3 组件中使用v-model则表示的是modelValue @update:modelValue的语法糖。比如Input组件为例


其实就是


所以在input.vue中我们就可以根据这个来实现Input组件的双向数据绑定,这里我们使用setup语法




从0搭建vue3组件库Input组件_第2张图片

到这里基础用法就完成了,接下来开始实现禁用状态

禁用状态

这个比较简单,只要根据propsdisabled来赋予禁用类名即可


然后给is-disabled写些样式

//...

.k-input.is-disabled {
  .k-input__inner {
    background-color: #f5f7fa;
    border-color: #e4e7ed;
    color: #c0c4cc;
    cursor: not-allowed;
    &::placeholder {
      color: #c3c4cc;
    }
  }
}

从0搭建vue3组件库Input组件_第3张图片

尺寸

按钮尺寸包括medium,small,mini,不传则是默认尺寸。同样的根据propssize来赋予不同类名

const styleClass = computed(() => {
  return {
    "is-disabled": inputProps.disabled,
    [`k-input--${inputProps.size}`]: inputProps.size,
  };
});

然后写这三个类名的不同样式

//...
.k-input.k-input--medium {
  .k-input__inner {
    height: 36px;
    &::placeholder {
      font-size: 15px;
    }
  }
}

.k-input.k-input--small {
  .k-input__inner {
    height: 32px;

    &::placeholder {
      font-size: 14px;
    }
  }
}

.k-input.k-input--mini {
  .k-input__inner {
    height: 28px;

    &::placeholder {
      font-size: 13px;
    }
  }
}

继承原生 input 属性

原生的inputtype,placeholder等属性,这里可以使用 vue3 中的useAttrs来实现props穿透.子组件可以通过v-bindprops绑定


可清空

通过clearable属性、Input的值是否为空以及是否鼠标是否移入来判断是否需要显示可清空图标。图标则使用组件库的Icon组件




清除图标部分 css 样式

.k-input__suffix {
  position: absolute;
  right: 10px;
  height: 100%;
  top: 0;
  display: flex;
  align-items: center;
  cursor: pointer;
  color: #c0c4cc;
}

从0搭建vue3组件库Input组件_第4张图片

密码框 show-password

通过传入show-password属性可以得到一个可切换显示隐藏的密码框。这里要注意的是如果传了clearable则不会显示切换显示隐藏的图标


这里是通过获取input元素,然后通过它的type属性进行切换,其中browseeye-close分别是Icon组件中眼睛开与闭,效果如下

从0搭建vue3组件库Input组件_第5张图片

带 Icon 的输入框

通过prefix-iconsuffix-icon 属性可以为Input组件添加首尾图标。

可以通过计算属性判断出是否显示首尾图标,防止和前面的clearableshow-password冲突.这里代码做了




相关样式部分

.k-input__suffix,
.k-input__prefix {
  position: absolute;
  right: 10px;
  height: 100%;
  top: 0;
  display: flex;
  align-items: center;
  cursor: pointer;
  color: #c0c4cc;
  font-size: 15px;
}

.no-cursor {
  cursor: default;
}

.k-input--prefix.k-input__inner {
  padding-left: 30px;
}

.k-input__prefix {
  position: absolute;
  width: 20px;
  cursor: default;
  left: 10px;
}

app.vue中使用效果如下



从0搭建vue3组件库Input组件_第6张图片

文本域

type属性的值指定为textarea即可展示文本域模式。它绑定的事件以及属性和input基本一样