百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 技术文章 > 正文

实现一个超有趣的 Material-UI 风格 Input 框

zhezhongyun 2024-12-25 16:47 87 浏览

最近看到一个组件库叫做 Material-UI,它里面有一个 Input 框的效果非常有意思,效果如下

所以想自己实现一遍,并分享给大家~

基础组件代码

这个效果有两个动画点:

  • 1、提示文本移动到上分
  • 2、下方滑动条

提示文本可以使用绝对定位,将它移动到 input 的上方,并且要跟 input 的 placeholder水平一致

可以先设置 input 的 placeholder,然后慢慢调整 top 定位,直到水平对齐,再去掉 placeholder

至于滑动条,直接放置在容器底部即可~

现在可以得到基础的组件效果

动画效果

两个动画效果:

  • 1、提示文本移动到上分
  • 2、下方滑动条

这两个动画效果的触发时机都是:input 框聚焦的时候

所以需要监听 input 的聚焦事件,去触发动画效果,第一个动画效果改动的是top: 1px -> -30px、left: 5px -> 0px,第二个动画效果改动的是width: 0 -> 100%

所以我们需要给这两个节点样式先设置对应样式的 transition

设置好transition就要开始去触发动画效果了,需要监听 input 的聚焦事件

注意:失焦时需要恢复默认样式

现在就能达到我们想要的动画效果了~

检测 Input 的值

有一个小优化点就是,当 input 框有值的时候,提示文本不应该恢复原状,不然就会导致重叠效果,如下

只需要在失焦的时候判断拦截一下即可

最终效果 & 完整代码

<template>
    <label class="input-container">
      <div ref="label" class="label">Enter Your Username</div>
      <input class="input" v-model="value"  @focus="onFocus" @blur="onBlur"></input>
      <div class="line" ref="line"></div>
    </label>
  </template>
  
<script lang="ts" setup>
  import { ref } from 'vue'
  
  const value = ref('')
  const label = ref<HTMLDivElement | null>(null)
  const line = ref<HTMLDivElement | null>(null)
  const onFocus = () => {
      // 聚焦时,修改样式
      const labelEle = label.value
      const lineEle = line.value
      if (labelEle && lineEle)  {
          lineEle.style.width = '100%'
          labelEle.style.left = '0px'
          labelEle.style.top = '-30px'
         
      }
  }
  const onBlur = () => {
      // 如果有值,则不恢复
      if (value.value) return
      // 失焦时,恢复原装
      const labelEle = label.value
      const lineEle = line.value
      if (labelEle && lineEle)  {
          lineEle.style.width = '0px'
          labelEle.style.left = '5px'
          labelEle.style.top = '-4px'
          
      }
  }
</script>
  
<style lang="less" scoped>
  .input-container {
    display: block;
    position: relative;
    width: 100%;
    border-bottom: 1px solid black;
    .input {
      font-size: 16px;
      padding: 5px;
      width: 100%;
    }
    .label {
      font-size: 20px;
      position: absolute;
      left: 5px;
      top: 1px;
      user-select: none;
      font-weight: 500;
    }
    .line {
      height: 3px;
      width: 0;
      background-color: black;
    }
  }
</style>

相关推荐

perl基础——循环控制_principle循环

在编程中,我们往往需要进行不同情况的判断,选择,重复操作。这些时候我们需要对简单语句来添加循环控制变量或者命令。if/unless我们需要在满足特定条件下再执行的语句,可以通过if/unle...

CHAPTER 2 The Antechamber of M de Treville 第二章 特雷维尔先生的前厅

CHAPTER1TheThreePresentsofD'ArtagnantheElderCHAPTER2TheAntechamber...

CHAPTER 5 The King&#39;S Musketeers and the Cardinal&#39;S Guards 第五章 国王的火枪手和红衣主教的卫士

CHAPTER3TheAudienceCHAPTER5TheKing'SMusketeersandtheCardinal'SGuard...

CHAPTER 3 The Audience 第三章 接见

CHAPTER3TheAudienceCHAPTER3TheAudience第三章接见M.DeTrévillewasatt...

别搞印象流!数据说明谁才是外线防守第一人!

来源:Reddit译者:@assholeeric编辑:伯伦WhoarethebestperimeterdefendersintheNBA?Here'sagraphofStea...

V-Day commemorations prove anti-China claims hollow

People'sLiberationArmyhonorguardstakepartinthemilitaryparademarkingthe80thanniversary...

EasyPoi使用_easypoi api

EasyPoi的主要特点:1.设计精巧,使用简单2.接口丰富,扩展简单3.默认值多,writelessdomore4.springmvc支持,web导出可以简单明了使用1.easypoi...

关于Oracle数据库12c 新特性总结_oracle数据库12514

概述今天主要简单介绍一下Oracle12c的一些新特性,仅供参考。参考:http://docs.oracle.com/database/121/NEWFT/chapter12102.htm#NEWFT...

【开发者成长】JAVA 线上故障排查完整套路!

线上故障主要会包括CPU、磁盘、内存以及网络问题,而大多数故障可能会包含不止一个层面的问题,所以进行排查时候尽量四个方面依次排查一遍。同时例如jstack、jmap等工具也是不囿于一个方面的问题...

使用 Python 向多个地址发送电子邮件

在本文中,我们将演示如何使用Python编程语言向使用不同电子邮件地址的不同收件人发送电子邮件。具体来说,我们将向许多不同的人发送电子邮件。使用Python向多个地址发送电子邮件Python...

提高工作效率的--Linux常用命令,能够决解95%以上的问题

点击上方关注,第一时间接受干货转发,点赞,收藏,不如一次关注评论区第一条注意查看回复:Linux命令获取linux常用命令大全pdf+Linux命令行大全pdf为什么要学习Linux命令?1、因为Li...

linux常用系统命令_linux操作系统常用命令

系统信息arch显示机器的处理器架构dmidecode-q显示硬件系统部件-(SMBIOS/DMI)hdparm-i/dev/hda罗列一个磁盘的架构特性hdparm-tT/dev/s...

小白入门必知必会-PostgreSQL-15.2源码编译安装

一PostgreSQL编译安装1.1下载源码包在PostgreSQL官方主页https://www.postgresql.org/ftp/source/下载区选择所需格式的源码包下载。cd/we...

Linux操作系统之常用命令_linux系统常用命令详解

Linux操作系统一、常用命令1.系统(1)系统信息arch显示机器的处理器架构uname-m显示机器的处理器架构uname-r显示正在使用的内核版本dmidecode-q显示硬件系...

linux网络命名空间简介_linux 网络相关命令

此篇会以例子的方式介绍下linux网络命名空间。此例中会创建两个networknamespace:nsa、nsb,一个网桥bridge0,nsa、nsb中添加网络设备veth,网络设备间...