目录
[input 组件封装](#input 组件封装)
input 组件封装
首先input组件的基本框架和样式:
html
<div class="miao-input">
<input class="miao-input_inner" >
</div>
css
<style lang="scss" scoped>
.miao-input {
width: 100%;
position: relative;
font-size: 14px;
display: inline-block;
.miao-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;
}
}
}
// 后面加suffix的意思是后面如果有后缀的话,触发该样式
.miao-input_suffix {
.miao-input_inner {
padding-right: 30px;
}
.miao-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);
}
}
}
</style>
v-model用在组件上
首先app.vue里:
html
<miao-input v-model="username">
</miao-input>
javascript
data(){
return {
username:'ss'
}
}
在input.vue里:
javascript
props:{
value:{
type:String,
default:''
}
}
html
<input class="miao-input_inner"
:class="{'is-disabled': disabled}"
:placeholder="placeholder" :type="type" :name="name"
:disabled="disabled"
:value="value"
>
除了value之外还要触发事件
html
@input="handleinput"
javascript
methods:{
handleinput(e){
// this.value=e.target.value是不行的因为直接改了父组件传的参数
this.$emit('input',e.target.value)
// 触发这个事件
}
}
添加图标
html
<span class="miao-input_suffix">
<i class="miao-input_icon miao-icon-cancel" v-if="clearable" @click="clear"></i>
<i class="miao-input_icon miao-icon-visible" v-if="showPassword"></i>
</span>
html
<div class="miao-input" :class="{'miao-input_suffix': showSuffix}">
javascript
computed:{
showSuffix(){
return this.clearable || this.showPassword
}
},
点击图标清空内容:
javascript
clear(){
this.$emit('input','')
// 父组件就会清空
}
显示和隐藏密码
html
<i class="miao-input_icon miao-icon-visible" v-if="showPassword" @click="handlePassword"></i>
javascript
:type="showPassword ? (passwordVisible ? 'text':'password'):type"
如果传来show-password判断是否需要切换密码显示,如果不传不判断
封装switch组件
只要是表单元素都支持name属性
switch初始模版:
html
<template>
<div class="one-switch">
<span class="one-switch_core">
<span class="one-switch_button"></span>
</span>
</div>
</template>
css:
css
.miao-switch {
display: inline-block;
align-items: center;
position: relative;
font-size: 14px;
line-height: 20px;
vertical-align: middle;
.miao-switch_core {
margin: 0;
display: inline-block;
position: relative;
width: 40px;
height: 20px;
border: 1px solid #dcdfe6;
outline: none;
border-radius: 10px;
box-sizing: border-box;
background: #dcdfe6;
cursor: pointer;
transition: border-color .3s, background-color .3s;
vertical-align: middle;
.miao-switch_button {
position: absolute;
top: 1px;
left: 1px;
border-radius: 100%;
transition: all .3s;
width: 16px;
height: 16px;
background-color: #fff;
}
}
}
// 选中样式
.is-checked {
.miao-switch_core {
border-color: #409eff;
background-color: #409eff;
.miao-switch_button {
transform: translateX(20px);
}
}
}
// 隐藏input标签
.miao-switch_input {
position: absolute;
width: 0;
height: 0;
opacity: 0;
margin: 0;
}
v-model绑定组件里的value和触发的事件:
javascript
props:{
value:{
type:Boolean,
default:false
}
},
methods:{
handleClick(){
this.$emit('input',!this.value)
}
}
实现转换的功能
html
<label class="miao-switch" :class="{'is-checked': value}" @click="handleClick">
css
// 选中样式
.is-checked {
.miao-switch_core {
border-color: #409eff;
background-color: #409eff;
.miao-switch_button {
transform: translateX(20px);
}
}
}
根据传入switch.vue的两个颜色来控制:
nexttick是基于promsie的封装,这里用语法糖async和await,用nexttick等数据修改后dom更新完毕再更改按钮颜色
javascript
methods:{
async handleClick(){
this.$emit('input',!this.value)
//点击时候还要修改背景色
//等待value发生变化再setcolor
//把数据改了发生更新
//nexttick基于promise封装
//数据修改后等待dom更新再修改按钮颜色
await this.$nextTick()
this.setColor()
},
setColor() {
//修改开关颜色,必须传入其一的颜色
if (this.activeColor || this.inactiveColor) {
let color = this.value ? this.activeColor : this.inactiveColor
this.$refs.core.style.borderColor = color
this.$refs.core.style.backgroundColor = color
}
}
},
mounted(){
this.setColor()
}
设置checkbox
用户使用switch组件实际上当成表单元素使用,可能用到name属性,需要在switch组件中添加一个checkbox,当值改变时候,需要设置checkbox的value值
同步checkbox里的checked值,一进来mounted和切换时候设置值
点击label相当于点击input框
html
<!-- 外面的大框架如果用label会触发两次,抵消了 -->
<input class="miao-switch_input" type="checkbox" :name="name" ref="input">
javascript
async handleClick(){
this.$emit('input',!this.value)
//点击时候还要修改背景色
//等待value发生变化再setcolor
//把数据改了发生更新
//nexttick基于promise封装
//数据修改后等待dom更新再修改按钮颜色
await this.$nextTick()
this.setColor()
this.$refs.input.checked = this.value
},
javascript
mounted(){
this.setColor()
//控制checkbox的值
this.$refs.input.checked=this.value
//input值和value同步
}
具体代码: