1.前言
现在的客户端与以往的有些区别,比如登录页面的输入框,大都废弃了之前的登录框样式,而采用只存在底边的输入框。还有就是输入框的错误信息都会采用浮层的形式提示,而不是瀑布流的方式去提示。
在借鉴了其他客户端的方式,做了一些调整,这些调整都需要对antdv
组件进行从新修正。因为我是用的是electron-vue
+antdv
的架构去构建的应用。
2.修改输入框的默认样式
先看一下效果图如下:
2.1 修改border仅保留底边
我们要做的事情就是:
- 修改输入框为只有底边
- 当输入框获取悬浮事件时,改变border的颜色
- 当输入框获取焦点事件时,修改边框的颜色
2.1.1 去除输入框其他边框
antdv
的处理方式和普通的输入框不一样,我们可以先设置一下输入框的border
,因为是antdv
提供的组件,所以我们需要F12查看输入框绑定的样式,然后去覆盖该样式的border
。
如上图所示,我们直接去覆盖ant-input
和ant-input-number
的样式。
.ant-input,
.ant-input-number {
width: 100%;
border: none !important;
border-bottom: 1px solid #e9e3e3 !important;
}
这样就可以实现只保留底边。
2.1.2 鼠标移动时改变边框
那么我们现在来做进一步的优化,就是当我们移动到上面时去改变边框的颜色,这个也简单只要设置ant-input
的hover
事件就行了。
.ant-input:hover,.ant-input-number:hover {
border-bottom: 1px solid #bebebe !important;
}
鼠标悬浮时,改变边框的颜色。
2.1.3 输入框获取焦点时改变输入框的颜色
我本来以为这个也简单,当输入框获取focus
时,直接改变底边的颜色即可。但是发现并非如此。
.ant-input:focus,
.ant-input-number:focus {
border: none;
border-bottom: 1px solid #12b7f5 !important;
}
可以发现,并没有生效。看了下网上说的,蓝色边框是输入框的外部轮廓,而不是border的问题。于是就设置输入框的outline:none
。并没有生效还是有蓝色边框。
.ant-input:focus,
.ant-input-number:focus {
border: none;
border-bottom: 1px solid #12b7f5 !important;
outline: none;
}
如果不是蓝色边框的慌,又不是轮廓的问题,那么只有一种可能了,那就是box-shadow
的问题,于是尝试了修改
.ant-input:focus,
.ant-input-number:focus {
border: none;
border-bottom: 1px solid #12b7f5 !important;
box-shadow: none;
}
确实获取焦点时,所谓的轮廓就没有了,看来是阴影的问题。到此,修改边框功能基本上实现了。只保留底边,鼠标悬浮时会改变底边的颜色,并且获取焦点时也可以去除阴影改变底边颜色。
但是还有一个问题,当获取焦点时同时会触发悬浮的事件,导致只有鼠标离开时才会变成获取焦点时的蓝色。
这个问题是由于权重相同导致的。怎么理解呢?因为我在获取焦点时,给的是!important
,而在悬浮时也是设置了!important
,所以导致了两个事件的权重一样,那么在输入框获取焦点时,颜色变为蓝色。当你鼠标移出输入框,但是光标还在输入框的情况下,触发了输入框的hover
事件,所以输入框底边就会变成灰色。
解决办法就是,删除悬浮时底边颜色的权重!importan
,这样获取焦点事件的权重比悬浮事件的权重要高,当鼠标离开输入框,在回到输入框时,也不会去覆盖获取焦点的颜色。
2.2 修改antdv表单校验提示
我发现现在大多数客户端的校验提示信息都不是瀑布流的方式(即在输入框下面留了一大片空白,来显示错误信息),而是通过浮层的方式去处理这个问题。
传统的方式:
这种在客户端尤其是只有底边的的情况下,会有很大的空白,页面显得大而宽泛。需要给登陆页面设置较大的宽和高。而正常的登陆基本上就是用户名密码登陆按钮这些,不需要太多留白。在antdv
中默认的留白是32px
吧,我记得是。所以为每一个表单项多留出32px
的空白,就显得这个页面不紧凑。所以我们需要重新去修改一下这种提示信息的位置。
而我们要实现的效果就是这种浮层的形式提示表单的错误信息:
于是研究了一下antdv
的表单,看看有没有关于表单校验信息的位置修改方法,研究之后,无果。又尝试能不能使用tooltip
来实现,发现并没有触发事件去触发这个tooltip
的显示。
于是决定自己写一个仿tooltip
校验的信息,写的话,我们需要先理一下思路。
- 首先这个提示信息应该是浮层,就是说脱离文档流,并且
z-index
高于其他元素- 创建一个div,里面包含两个小的div,一个是小三角,一个是提示信息
- 该div应该和input在同一父元素下
- 三角的实现应该是利用border去设置
- 小三角应该偏离一段距离,能对到我们的输入框,输入信息的起始位置
- 整个div应该可以显示隐藏,所以我们需要定义一个属性去控制显示隐藏,以及定义一个msg去显示错误的提示信息
好了这个思路我们理清了,那么操作起来就相对简单多了,把复杂的问题拆分成一个个小的问题,人后逐个攻破,就会容易的多了。
首先的第一个难点就是怎么创建一个小三角。如果你做过,当然就不难,如果没做过还是有一点难度的,当然现在网上有很多关于这方面的资料,感兴趣的可以搜一下。
我处理问题的习惯就是,一个新的东西,我会先脱离当前的项目,重新搞一个简单页面或者脚手架测试一下可行性。
<div style="width:300px;height: 300px;background-color: #bfa;">
</div>
<div style="position: absolute;top:20px">
<div style="width: 100px;
height: 100;
background-color: black;">
</div>
<!-- <div style="width: 200px;height: 20px;background-color: black;border-radius: 2px;">
</div> -->
</div>
然后我们将黑色div的都设为零,并且设置其border为一定的大小
<div style="width:300px;height: 300px;background-color: #bfa;">
</div>
<div style="position: absolute;top:20px">
<div style="width: 0;
height: 0;
border: 100px solid;
border-color: red black;margin-left: 10px;">
</div>
<!-- <div style="width: 200px;height: 20px;background-color: black;border-radius: 2px;">
</div> -->
</div>
然后将,这样我们只要把其他的边框设置透明就能让它只显示一块了
<div style="width:300px;height: 300px;background-color: #bfa;">
</div>
<div style="position: absolute;top:20px">
<div style="width: 0;
height: 0;
border: 100px solid;
border-color: transparent transparent black;margin-left: 10px;">
</div>
<!-- <div style="width: 200px;height: 20px;background-color: black;border-radius: 2px;">
</div> -->
</div>
接着,把border的大小改变一下
<div style="width:300px;height: 300px;background-color: #bfa;">
</div>
<div style="position: absolute;top:20px">
<div style="width: 0;
height: 0;
border: 5px solid;
border-color: transparent transparent black;margin-left: 10px;">
</div>
<!-- <div style="width: 200px;height: 20px;background-color: black;border-radius: 2px;">
</div> -->
</div>
这么一个小三角形就出来了,然后打开下面的那个div
<div style="width:300px;height: 300px;background-color: #bfa;">
</div>
<div style="position: absolute;top:20px">
<div style="width: 0;
height: 0;
border: 5px solid;
border-color: transparent transparent black;margin-left: 10px;">
</div>
<div style="width: 200px;height: 20px;background-color: black;border-radius: 2px;color:white;font-size: 12px;line-height: 20px;padding-left: 5px;">
请输入正确的用户名
</div>
</div>
是不是就有内个味了。
好了回到我们的项目中,需要在我们的表单输入框的父节点下,加上我们刚才的代码,并且添加控制显示影藏的属性
<a-form-model-item
:label-col="formItemLayout.labelCol"
:wrapper-col="formItemLayout.wrapperCol"
prop="username"
>
<a-input
v-model="loginVo.username"
placeholder="账号"
@change="changeUsername"
>
<a-icon slot="prefix" type="user" />
</a-input>
<div class="custom-tooltip" v-show=