VUE+CSS模拟组件库的Input组件
话不多说,不会插图,样式可能存在不科学的地方,关键是核心利用了CSS变量和表单元素的
:invalid无效伪类和required伪类模拟组件库的input框,直接上代码,欢迎提出宝贵意见
1.html部分:
<template>
<!-- html结构,必须使用form表单元素才可以和input表单元素的伪类进行联动控制子元素 -->
<form class="box">
<!-- -->
<template v-if="props.label !== ''">
<label class="label" for="current">
<span class="star" v-show="props.required">*</span>{{ props.label }}:</label>
</template>
<div class="inpbox">
<!-- 手动双向绑定 input事件-->
<input :type="props.type" :value="inpVal" @input="changeHandler" :required="props.required" id="current"
:placeholder="props.placeholder" />
</div>
</form>
</template>
2.js部分,因为应用了CSS的新属性,js大大减少
<script lang="ts" setup>
import { ref } from 'vue';
//存储
const inpVal = ref<string>('')
// 默认接收一个onchange事件,用来向外传递表单元素输入的内容
const emit = defineEmits<{ (e: 'onchange', val: string): void }>()
// 这里配置组件的属性以及默认值
const props = defineProps({
// placeholder的内容
placeholder: {
type: String,
default: '请输入内容'
},
// 输入框前面的文字
label: {
type: String,
default: '用户名'
},
// 是否必填
required: {
type: Boolean,
default: false
},
// 其实这里应该进一步限定type不应该是radio button checkbox等值
type: {
type: String,
default: 'text'
}
})
//向外传递数据的回调函数
const changeHandler = (event: Event) => {
inpVal.value = (event.target as HTMLInputElement).value
emit('onchange', inpVal.value)
}
</script>
3.CSS部分,合理运用CSS减少js代码
<style scoped>
/*
·合理利用CSS变量,实现用户按需定制
·合理利用:invalid伪类,:required伪类模拟组件库表单input输入框
可以减少大量js代码,这也是组件库们积极拥抱CSS3的重要原因
1.单个input输入框依据是否必须 (input 标签上添加required 表示此项必填 )
对应地我们可以在CSS样式表里进行相应提示,比如当input为必填时,没有输入内容
我们可以设置边框红色,设置input前面的提示文字红色
2.单个元素输入内容无效时(input自带email,url等新增的type,自带校验),我们可以
通过元素的:invalid伪类选择器对样式进行修改
3.重点:当一个具体表单元素(这里是input)无效或者必须时,想要联动实现该元素
之外的元素效果时,请保证这些元素都被一个公共的form表单元素包裹,
这样就可以设置form:invalid .inpbox::after{display:block}
这段样式表示当input内容无效时就是form无效,form里的.inpbox的伪元素
将在页面显示
*/
.box {
/* 输入框内容无效时的边框颜色变量 */
--inp-required-invalid-border-color: orangered;
/* 无效内容时的字体颜色 */
--inp-required-invalid-color: orangered;
/* 整个组件的宽度 */
--inp-box-width: 200px;
/* 组件的高度 */
--inp-box-height: 70px;
/* 输入框的宽度 */
--inp-width: 100px;
/* 输入框的高度 */
--inp-height: 15px;
/* input的圆角,按需传入 */
--inp-border-radius: 3px;
/* placeholder的字体颜色 */
--inp-placeholder-color: deeppink;
width: var(--inp-box-width);
height: var(--inp-box-height);
display: flex;
justify-content: center;
align-items: center;
font-size: calc(var(--inp-box-width) * .06);
}
/* input img这种单标签元素不能添加伪元素,因此我们给input套个盒子并定位 */
.inpbox {
margin: 0 calc(var(--inp-width) * .1);
position: relative;
}
/* input 外层盒子的伪元素默认隐藏状态,当内用格式不正确 */
.inpbox::after {
position: absolute;
left: 20%;
top: 100%;
content: '格式错误';
color: var(--inp-required-invalid-color);
display: none;
}
/* 当.box外层的form,注意一定要用form才能和invalid required伪类选择器联动实现效果 */
.box:invalid .inpbox::after {
display: block;
}
/* input框的宽度高度,这些样式可能不太科学 */
#current {
width: var(--inp-width);
height: var(--inp-height);
border: 1px solid #ccc;
outline: none;
border-radius: var(--inp-border-radius);
font-size: calc(var(--inp-box-width) * .06);
}
#current::placeholder{
color:var(--inp-placeholder-color);
font-size: 12px;
line-height: var(--inp-height);
}
/* 输入框内容无效时的边框颜色和字体颜色 */
#current:invalid {
border-color: var(--inp-required-invalid-border-color);
color: var(--inp-required-invalid-color);
}
/* 当输入框无效时label里的字体颜色 */
.box:invalid label[for=current] {
color: var(--inp-required-invalid-color)
}
/* 让label标签内的元素躺平 */
.label {
display: flex;
}
</style>
注释写的比较多,有兴趣可以研究研究,CSS3的新特性之多和强大都是不言而喻的,今天就到这里,欢迎点赞,评论,转发,好的作品离不开大家的捧场支持!