封装一个element-ui风格的input组件
参数支持:
参数名称 | 参数描述 | 参数类型 | 默认值 |
placeholder | 占位符 | string | 无 |
type | 文本框类型(text/password) | string | text |
disabled | 禁用 | boolean | false |
clearable | 是否显示清空按钮 | boolean | false |
show-password | 是否显示密码切换按钮 | boolean | false |
name | name属性 | string | 无 |
事件支持:
事件名称 | 事件描述 |
---|---|
blur | 失去焦点事件 |
change | 内容改变事件 |
focus | 获取焦点事件 |
input组件的基本框架和样式以及处理placeholde、type、name、disabled
<template>
<div class="dl-input">
<input
class="dl-input_inner"
:class="{'is-disabled': disabled}"
:placeholder="placeholder"
:type="type"
:name="name"
:disabled="disabled">
</div>
</template>
<script>
export default {
name: 'oneInput',
components: {
},
props: {
placeholder: {
type: String,
default: ''
},
type: {
type: String,
default: 'text'
},
name: {
type: String,
default: ''
},
disabled: {
type: Boolean,
default: false
}
},
data () {
return {}
},
methods: {}
}
</script>
<style lang="scss" scoped>
.dl-input{
width: 100%;
position: relative;
font-size: 14px;
display: inline-block;
.dl-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;
}
}
}
</style>
父组件中传值:
<dl-input placeholder="请输入密码" type="password" name="name" disabled></dl-input>
v-model语法糖——实现双向数据绑定
当我们给一个input标签进行双向数据绑定时,我们需要使用value绑定数据,在使用input事件监听标签内数据变动
<input :value="username" @input="username=$event.target.value"/>
在封装input组件时,这样显然不合适,所以这里我们需要使用到v-model语法糖。
由于v-model的特性,它将value值绑定在了组件上,所以我们内部组件通过接收value值得方式,就可以接收传入的数据;并且v-model也实现了input事件,在组件内部绑定的input事件作为回调,把value值返回给父组件,这样就实现了input组件的双向绑定了。
父组件中使用v-model绑定:
<dl-input v-model="username"></dl-input>
组件内部绑定value值以及实现回调:
<input
class="dl-input_inner"
:class="{'is-disabled': disabled}"
:placeholder="placeholder"
:type="type"
:name="name"
:value="value"
@input="handleInput"
:disabled="disabled">
//绑定input事件进行回调
handleInput (e) {
this.$emit('input', e.target.value)
}
实现clearable功能和showPassword功能
场景:
组件中的clearable属性,当输入框中有数据时,可以删除数据
当input组件的type属性时password时,我们希望可以有一个显示和隐藏密码的按钮,我们可以通过show-password属性进行控制
实现这个两个功能,除了基本的父子组件传值外,还要添加i标签的icon字体图标,以及实现功能。
字体图标的引用详解:Vue项目中引入字体图标(详细讲解)_Dl_蜡笔小新的博客-优快云博客
<div class="dl-input" :class="{'dl-input_suffix':showSuffix}">
<input
class="dl-input_inner"
:class="{'is-disabled': disabled}"
:placeholder="placeholder"
:type="type"
:name="name"
:value="value"
@input="handleInput"
:disabled=disabled>
<span class="dl-input_suffix">
<i class="dl-input_icon dl-icon-cancel" v-if="clearable && value" @click="clear"></i>
<i class="dl-input_icon dl-icon-visible" v-if="showPassword && type=='password'" @click="handlePassword"></i>
</span>
</div>
样式:
.dl-input_suffix{
.dl-input_inner{
padding-right: 30px;
}
.dl-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);
}
}
}
实现clearable功能
首先获取父组件传递的clearable值,然后给i标签绑定一个点击事件,这个事件触发input(本身父组件有这个事件,不需要在父组件中注册)事件回调,当点击叉号图标时,将父组件的value值清空:
clear() {
this.$emit('input', '')
}
实现showPassword功能
实现showPassword功能的思路很简单,就是改变input的type类型即可。但是,我们不能直接改变父组件传递过来的type值,但是我们可以判断type值得方式,实现改变type的改变
首先设置一个布尔值的变量,并且设置点击事件改变这个变量:
data() {
return {
//是否显示密码框
passwordVisible: false
}
},
methods: {
handlePassword() {
this.passwordVisible = !this.passwordVisible
}
}
然后我们需要再绑定type的值得时候,进行双重判断
第一步:判断showPassword是否为真,不为真就显示type就行
第二步:是真通过passwordVisible去判断type为text还是password,以此来控制隐藏和显示
:type="showPassword ? (passwordVisible ? 'text' : 'password') : type"