从0搭建vue3组件库: Input组件( 二 )

然后写这三个类名的不同样式
//....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绑定
<template><div class="k-input" :class="styleClass"><inputclass="k-input__inner":value="https://www.huyubaike.com/biancheng/inputProps.modelValue"@input="changeInputVal":disabled="inputProps.disabled"v-bind="attrs"/></div></template><script lang="ts" setup>//...const attrs = useAttrs();</script>可清空通过clearable属性、Input的值是否为空以及是否鼠标是否移入来判断是否需要显示可清空图标 。图标则使用组件库的Icon组件
<template><divclass="k-input"@mouseenter="isEnter = true"@mouseleave="isEnter = false":class="styleClass"><inputclass="k-input__inner":disabled="inputProps.disabled"v-bind="attrs":value="https://www.huyubaike.com/biancheng/inputProps.modelValue"@input="changeInputVal"/><div@click="clearValue"v-if="inputProps.clearable && isClearAbled"v-show="isFoucs"class="k-input__suffix"><Icon name="error" /></div></div></template><script setup lang="ts">//...import Icon from "../icon/index";//...//双向数据绑定&接收属性type InputProps = {modelValue?: string | number;disabled?: boolean;size?: string;clearable?: boolean;};//...const isClearAbled = ref(false);const changeInputVal = (event: Event) => {//可清除clearable(event.target as HTMLInputElement).value? (isClearAbled.value = https://www.huyubaike.com/biancheng/true): (isClearAbled.value = false);inputEmits("update:modelValue", (event.target as HTMLInputElement).value);};//清除input valueconst isEnter = ref(true);const clearValue = https://www.huyubaike.com/biancheng/() => {inputEmits("update:modelValue", "");};</script>清除图标部分 css 样式
.k-input__suffix {position: absolute;right: 10px;height: 100%;top: 0;display: flex;align-items: center;cursor: pointer;color: #c0c4cc;}

从0搭建vue3组件库: Input组件

文章插图
密码框 show-password通过传入show-password属性可以得到一个可切换显示隐藏的密码框 。这里要注意的是如果传了clearable则不会显示切换显示隐藏的图标
<template><divclass="k-input"@mouseenter="isEnter = true"@mouseleave="isEnter = false":class="styleClass"><inputref="ipt"class="k-input__inner":disabled="inputProps.disabled"v-bind="attrs":value="https://www.huyubaike.com/biancheng/inputProps.modelValue"@input="changeInputVal"/><div class="k-input__suffix" v-show="isShowEye"><Icon @click="changeType" :name="eyeIcon" /></div></div></template><script setup lang="ts">//...const attrs = useAttrs();//...//显示隐藏密码框 showPasswordconst ipt = ref();Promise.resolve().then(() => {if (inputProps.showPassword) {ipt.value.type = "password";}});const eyeIcon = ref("browse");const isShowEye = computed(() => {return (inputProps.showPassword && inputProps.modelValue && !inputProps.clearable);});const changeType = () => {if (ipt.value.type === "password") {eyeIcon.value = "https://www.huyubaike.com/biancheng/eye-close";ipt.value.type = attrs.type || "text";return;}ipt.value.type = "password";eyeIcon.value = "https://www.huyubaike.com/biancheng/browse";};</script>
这里是通过获取input元素,然后通过它的type属性进行切换,其中browseeye-close分别是Icon组件中眼睛开与闭,效果如下

从0搭建vue3组件库: Input组件

文章插图
带 Icon 的输入框通过prefix-iconsuffix-icon 属性可以为Input组件添加首尾图标 。
可以通过计算属性判断出是否显示首尾图标,防止和前面的clearableshow-password冲突.这里代码做了
<template><div class="k-input"><inputref="ipt"class="k-input__inner":class="{ ['k-input--prefix']: isShowPrefixIcon }":disabled="inputProps.disabled"v-bind="attrs":value="https://www.huyubaike.com/biancheng/inputProps.modelValue"@input="changeInputVal"/><div class="k-input__prefix" v-if="isShowPrefixIcon"><Icon :name="inputProps.prefixIcon" /></div><div class="k-input__suffix no-cursor" v-if="isShowSuffixIcon"><Icon :name="inputProps.suffixIcon" /></div></div></template><script setup lang="ts">//...type InputProps = {prefixIcon?: string;suffixIcon?: string;};//...//带Icon输入框const isShowSuffixIcon = computed(() => {return (inputProps.suffixIcon && !inputProps.clearable && !inputProps.showPassword);});const isShowPrefixIcon = computed(() => {return inputProps.prefixIcon;});</script>

推荐阅读