頔言頔语:进步,一定要进步,进步是跟收入持平的本钱。
总有人问:前端开发中是哪些轮子值得实现一遍。但是你造过那些轮子呢?这是我造过的!
声明:本项目所有的UI,来自于方应航,我只做简单修改!
输入框 · 轱辘 · 语雀www.yuque.com所有的项目按照流程按照一下目录进行
- 需求分析
- UI设计
- 项目知识点
- 项目难点(在3中解决,用饮用块的方式标识)
1. 需求分析
1.1 input组件功能分析
- 1. 输入 - 输入之后报错(字长)- 输入前给提示(用英文)- 清空
- 2. 复制粘贴
- 3. 键盘 tap 定位
- 4. 在input 敲击回车
- 5. 不可输入
1.2 input状态分析
- 1. normal
- 2. focused
- 3. hovered
- 4. error 状态下的 normal/focused/error
- 5. disabled
- 6. readonly
- 1.3 input事件分析
1.change事件
2. input事件
2. UI设计展示
想看具体细节的可以参考如下链接:
输入框 · 轱辘 · 语雀www.yuque.com3. 项目知识点
3.1.项目目录结构展示
我将Input 独立作为一个公共组件,在main.js当中声明,在App.vue当中使用
代码如下:
import ginput from './components/Input.vue'
Vue.component('ginput',ginput)
<ginput value='小马頔' > </ginput>
3.2 我使用了新的icon 如下 i-error 和i-info
3.3 Input 组件讲解
Input 组件的优化是根据实现的 Input 的功能进步进行的
01 正常Input
就是一个input,默认状态
<input type="text" >
02 Input加样式
此时为Input组件加上了CSS,绑定value值。同时修改了input的hover还有focus的状态
<input type="text" :value="value" >
.warpper input:hover{border-color: var(--input-border-color-hover);}
.warpper input:focus{box-shadow: inset 0 1px 3px var(--input-box-shadow-color) ;outline: none;}
此时可以在App.vue当中使用input组件
<ginput value='小马頔13' > </ginput>
在focus的时候,去掉了默认的边框颜色,加上了阴影。
03 Input状态
03.1 Error
难点一:进行判定,如果出现错误信息,就出现error提示
但是这里有一个非常有意思的地方就是,error本身会出现icon和content两个内容。
我使用v-if进行两次判定,代码冗余。
使用div包裹icon和 span,这样会多出来一层DOM结构,并不优雅
有趣的是可以使用<template></template>标签进行包裹然后进行一次判定!这样解决,很甜!!!
<input type="text" :value="value" >
<template v-if= "error">
<gicon name= 'error' class="icon-error"> </gicon>
<span class="errorMessage">{{error}}</span>
</template>
props:{
value:{type:String },
error:{type:String}
}
<ginput value='error' error= '不爱马頔是不对的哦'> </ginput>
03.2 disabled/readonly
这两个我想放在一起写,因为他们两个其实没有明显区别。都是用户无法进行修改
但是readonly有focus状态但是disabled没有
写这两个状态其实就是给这两个状态写CSS,CSS信息如下
.warpper input[disabled]{border-color:#aaa;color:#aaa ;cursor: not-allowed;}
.warpper input[readonly]{border-color:#aaa;color:#aaa ;cursor: not-allowed;}
03 Input事件
input的事件,主要是写了change事件、input事件还有focus事件。通过自定义绑定的方式进行传值。
在input组件中声明自定义事件$emit,并且进行传值
<input type="text" :value="value" :disabled = "disabled" :readonly= "readonly"
@change= "$emit('change',$event.target.value)"
@input= "$emit('input',$event.target.value)"
@focus= "$emit('focus',$event.target.value)"
>
在App.vue中使用input组件时分别绑定change/input/focus 事件
<ginput value='change' @change ='inputChange'> </ginput>
<ginput value='input' @input ='inputInput'> </ginput>
<ginput value='focus' @focus ='inputFocus'> </ginput>
在App.vue的methods当中书写input组件绑定的方法,其中传过来的e就是$emit('focus',$event.target.value)这个自定义事件传过来的
methods:{
inputChange(e){console.log(e)},
inputInput(e){console.log(e)},
inputFocus(e){console.log(e)},
}
三个事件的区别是:
change事件当input在用户输入后,节点失去焦点的时候触发”change"事件
input事件当input在用户输入后就会触发input事件
focus事件当input在用户输入后,节点失去焦点再次获取焦点的时候会触发focus事件
04 Input组件实现v-model
众所周知,vue的双向数据绑定是伪造的,那我们的Input组件也伪造一个v-model出来
主要有以下两步:
:value="value"
@input= "$emit('input',$event.target.value)"
一件事是App 使用组件的传递的value 的变化同步到input.value
一件事是input.value的变化同步到App 组件当中的value
我们用页面展示出来:
<ginput v-model= 'inputmessage'> </ginput>
{{inputmessage}}
<button @click= "addOne">点击+1</button>
可以发现,两个值是同步变化的
并且我们在进行上边的操作的时候 ,状态变化还有事件变化都是绑定了的。就是说v-model是已经完成可以使用的!!!
关于这个项目,这就是我想说的
我的知识和文字不成熟,项目也不成熟,但是我在进步!
若有意见,欢迎留言指正 !!