五、封装一个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
获取焦点事件
5.1input组件的基本框架和样式以及处理placeholde、type、name、disabled
因为这部分与前面介绍的内容相同且比较简单,所以将这部分放在一起,不多做介绍了。
这里需要注意的是,disabled属性为true时,输入框禁用,并且需要改变样式,之前在button组件封装的时候也用到了相同的方法,获取到值后动态设置组件样式。
input组件的框架以及样式,获取到的数据以及数据处理:
<template>
<div class="one-input">
<input
class="one-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>
.one-input{
width: 100%;
position: relative;
font-size: 14px;
display: inline-block;
.one-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>
父组件中传值也是与之前一样的:
<input :value="username" @input="username=$event.target.value"/>
5.2v-model语法糖——实现双向数据绑定
当我们给一个input标签进行双向数据绑定时,我们需要使用value绑定数据,再使用input事件监听标签内数据的变动,如下:
-
:value=“username” 使得我们可以设置变量修改表单的value的值 控制值
-
@input=“username=$event.target.value”/ 使得表单的值改动后会更新我们的变量 值反馈
<input :value=“username” @input=“username=$event.target.value”/>
在封装input组件时,这样显然是不合适的,所以这里我们需要使用到v-model语法糖。
显然,我们是不能给我们封装的input组件直接使用v-model绑定数据的,但是由于v-model的特性,他将value值绑定在了组件上,所以,我们组件内部通过接收value值的方式,就可以接收到传入的数据;并且v-model也实现了input事件,在组件内部绑定的input事件作为回调,把value值返回给父组件,这样就实现了input组件的双向绑定了。
父组件中的使用v-model绑定:
<one-input v-model="username"></one-input>
- 注意v-model=“username” 等价于 :value=“username” @input=“username=$event.target.value” 子组件会接受到父组件传的value (注意需要接受)
- 组件内部需要修改value的值 但不能直接 this.value = e.target.value 无法直接修改父组件传过来的值 这里又用到了v-model的实质 这里通过传递事件的方式 触发@input方法 并把我们的值传过去
组件内部绑定value值以及实现回调:
//绑定value值和input事件
<input
class="one-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)
}