element-ui input 组件源码分享

今日简单分享 input 组件的实现原理,主要从以下五个方面来分享:

1、input 组件的页面结构

2、input 组件的属性

3、input 组件的 slot

4、input 组件的事件

5、input 组件的方法

一、input 组件的页面结构。

二、input 组件的属性。

2.1 type 属性,类型 string,默认 text。

2.1.1 type 的值一般为 textarea、text 及原生 input 标签 type 值。

2.1.2 type 取值逻辑。

2.2 value / v-model 属性,类型 string,无默认值。

2.3 maxlength 属性,原生属性,最大输入长度,类型 number,无默认值。

2.4 minlength 属性,原生属性,最小输入长度,类型 number,无默认值。

小结:vm.$attrs 的作用,接受父组件传递过来的自定义属性,并将其渲染到 dom 节点上,如下图:

2.5 show-word-limit 属性,是否显示输入字数统计,只在 type = "text" 或 type = "textarea" 时有效,类型 boolean,默认 false。

页面显示效果如下:

2.6 placeholder 属性,输入框占位文本,类型 string,无默认值。

源码当中的 props 属性中并未有 placeholder 属性,此属性是通过 v-bind="$attrs" 的方式来传递到 input 标签上的。

2.7 clearable 属性,是否可清空,类型 boolean,默认 false。

2.8 disabled 属性,禁用,类型 boolean,默认 false。

2.9 size 属性,输入框尺寸,只在 type!="textarea" 时有效,类型 string,medium / small / mini,无默认值。

2.10 prefix-icon 属性,输入头部图标,类型 string,无默认值。

2.11 suffix-icon 属性,输入框尾部图标,类型 string,无默认值。

挂载后置图标时,多了一个计算属性的判断:

2.12 rows 属性,输入框行数,只对 type="textarea" 有效,类型 number,默认 2。

源码当中的 props 中并未传递此属性,此属性是 html 原生的属性,通过 v-bind="$attrs" 挂载到标签上的。

2.13 autosize 属性,自适应内容高度,只对 type="textarea" 有效,可传入对象,如,{ minRows: 2, maxRows: 6 },类型 boolean / object,默认 false。

autoSize 是对 rows 的特殊处理,如下图。

calcTextareaHeight 方法,计算 textarea 的高度,实现在最大行数之前高度的自适应。

let hiddenTextarea;

const HIDDEN_STYLE = `
  height:0 !important;
  visibility:hidden !important;
  overflow:hidden !important;
  position:absolute !important;
  z-index:-1000 !important;
  top:0 !important;
  right:0 !important
`;

const CONTEXT_STYLE = [
  'letter-spacing',
  'line-height',
  'padding-top',
  'padding-bottom',
  'font-family',
  'font-weight',
  'font-size',
  'text-rendering',
  'text-transform',
  'width',
  'text-indent',
  'padding-left',
  'padding-right',
  'border-width',
  'box-sizing',
];

function calculateNodeStyling(targetElement) {
  // targetElement: textarea dom
  // window.getComputedStyle: 获取元素对 style,返回的是一个对象
  const style = window.getComputedStyle(targetElement);

  // style.getPropertyValue:从 style 对象中获取 box-sizing 的值
  const boxSizing = style.getPropertyValue('box-sizing');

  const paddingSize =
    parseFloat(style.getPropertyValue('padding-bottom')) +
    parseFloat(style.getPropertyValue('padding-top'));

  const borderSize =
    parseFloat(style.getPropertyValue('border-bottom-width')) +
    parseFloat(style.getPropertyValue('border-top-width'));

  // 拼装 style 样式
  const contextStyle = CONTEXT_STYLE.map(
    (name) => `${name}:${style.getPropertyValue(name)}`
  ).join(';');

  return { contextStyle, paddingSize, borderSize, boxSizing };
}

export default function calcTextareaHeight(
  targetElement,
  minRows = 1,
  maxRows = null
) {
  if (!hiddenTextarea) {
    // 存储创建的隐藏域文本,作用:测量文本高度;应用样式;考虑边框和内边距;支持最小和最大行数;重置和清理
    hiddenTextarea = document.createElement('textarea');
    document.body.appendChild(hiddenTextarea);
  }

  let {
    paddingSize,
    borderSize,
    boxSizing,
    contextStyle,
  } = calculateNodeStyling(targetElement);

  // 设置 style
  hiddenTextarea.setAttribute('style', `${contextStyle};${HIDDEN_STYLE}`);
  hiddenTextarea.value = targetElement.value || targetElement.placeholder || '';

  let height = hiddenTextarea.scrollHeight;
  const result = {};

  // ie 盒模型的高度计算 高度不包含 padding border
  if (boxSizing === 'border-box') {
    height = height + borderSize;
  } else if (boxSizing === 'content-box') {
    // 标准盒模型的高度计算 高度包含 padding border
    height = height - paddingSize;
  }

  hiddenTextarea.value = '';
  // 单行文本的高度
  let singleRowHeight = hiddenTextarea.scrollHeight - paddingSize;

  if (minRows !== null) {
    let minHeight = singleRowHeight * minRows;
    if (boxSizing === 'border-box') {
      minHeight = minHeight + paddingSize + borderSize;
    }
    height = Math.max(minHeight, height);
    result.minHeight = `${minHeight}px`;
  }
  if (maxRows !== null) {
    let maxHeight = singleRowHeight * maxRows;
    if (boxSizing === 'border-box') {
      maxHeight = maxHeight + paddingSize + borderSize;
    }
    height = Math.min(maxHeight, height);
  }
  result.height = `${height}px`;
  hiddenTextarea.parentNode &&
    hiddenTextarea.parentNode.removeChild(hiddenTextarea);
  hiddenTextarea = null;
  // result { height:'',minHeight:'' }
  return result;
}

2.14 autocomplete 原生属性,自动补全,类型 string,默认 off。

2.15 name 属性,原生属性,类型 string,无默认值。

源码 props 中无此属性,通过 v-bind="$attrs" 传递到页面中的。设置 name 的作用,表单项的唯一标识,可读性更高。

2.16 readonly 属性,原生属性,只读,类型 boolean,默认 false。

2.17 max 属性,原生属性,设置最大值,类型 number,无默认值。

2.18 min 属性,原生属性,设置最小值,类型 number,无默认值。

2.19 step 属性,原生属性,设置输入字段的合法数字间隔,类型 number,无默认值。

上面三个属性,在源码的 props 当中都无此属性,使用过 v-bind="$attrs" 的方式进行传递的。

2.20 resize 属性,控制是否能被用户缩放,类型 string,有这些值 none, both, horizontal, vertical,无默认值。

2.21 autofocus 属性,原生属性,自动获取焦点,类型 boolean,默认 false。

在源码的 props 当中都无此属性,使用过 v-bind="$attrs" 的方式进行传递的。

2.22 form 属性,原生属性,类型 string,无默认值。

<form id="myForm" action="/submit_form">  
    <!-- 其他表单元素 -->  
</form>  
  
<input type="text" name="username" form="myForm">

2.23 label 属性,输入框关联的label文字,类型 string,无默认值。

2.24 tabindex 属性,输入框的tabindex,类型 string,无默认值。

tabindex 全局属性指示其元素是否可以聚焦,以及它是否/在何处参与顺序键盘导航(通常使用Tab键,因此得名)。

2.25 validate-event 属性,输入时是否触发表单的校验,类型 boolean,默认 true。

三、input 组件的 slot 挂载。

提供 slot 插槽,运行用户在指定位置挂载用户自定义的内容。

3.1 prefix slot,输入框头部内容,只对 type="text" 有效。

3.2 suffix slot,输入框尾部内容,只对 type="text" 有效。

3.3 prepend slot,输入框前置内容,只对 type="text" 有效。

3.4 append slot,输入框后置内容,只对 type="text" 有效。

四、input 组件的事件。

4.1 blur 事件,在 Input 失去焦点时触发,(event: Event)。

4.2 focus 事件,在 Input 获得焦点时触发,(event: Event)。

4.3 change 事件,仅在输入框失去焦点或用户按下回车时触发,(value: string | number)。

4.4 input 事件,在 Input 值改变时触发,(value: string | number)。

重点解决 isComposing 这个变量,它是通过下面这三个时间来实现的,主要解决在输入拼音时,所触发的事假何时执行的问题。

compositionstart:文本合成系统如 input method editor(即输入法编辑器)开始新的输入合成时会触发 compositionstart 事件。例如,当用户使用拼音输入法开始输入汉字时,这个事件就会被触发。

参考链接:compositionstart - Web API 接口参考 | MDN

compositionupdate:事件触发于字符被输入到一段文字的时候(这些可见字符的输入可能需要一连串的键盘操作、语音识别或者点击输入法的备选词)。

参考链接:compositionupdate - Web API 接口参考 | MDN

compositionend:当文本段落的组成完成或取消时,compositionend 事件将被触发 (具有特殊字符的触发,需要一系列键和其他输入,如语音识别或移动中的字词建议)。

参考链接:compositionend - Web API 接口参考 | MDN

对应源码部分:

compositionstart 部分:

compositionupdate 部分:

compositionend 部分:

4.4 clear 事件,在点击由 clearable 属性生成的清空按钮时触发。

五、input 组件的方法。父组件可以通过 ref 的形式,调用组件内部的方法。

5.1 focus,使 input 获取焦点。

5.2 focus,使 input 失去焦点。

5.3 select,选中 input 中的文字。

方法使用部分:

展示效果:

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/491272.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Eclipse新建java类的操作流程

一、在左侧空白区域&#xff0c;点击鼠标右键。 二、点击new&#xff0c;选择Java Project &#xff08;由于这里不知道怎么截图&#xff0c;就用手机拍了一张&#xff0c;希望不要介意&#xff09; 三、 给project文件起个名字&#xff0c;其他都不用管&#xff0c;点击Finis…

Aspose.PDF功能演示:在 JavaScript 中合并两个 PDF 文件

在 Web 应用程序的世界中&#xff0c;处理和操作文档是一项常见的要求。当谈到 PDF 文件时&#xff0c;开发人员经常发现自己需要将 PDF 合并为单个 PDF 文件。因此&#xff0c;在这篇博文中&#xff0c;我们将探索如何使用强大的 PDF 库在 JavaScript 中轻松合并两个 PDF 文件…

LVS负载均衡(load balance)

一 LVS LVS&#xff1a;Linux Virtaul Server&#xff0c;该软件的功能是实现 LB&#xff08;load balance&#xff09; 二LVS 的三种工作模式 1.NAT 模式&#xff08;NAT&#xff09; LVS 服务器同时充当一台 NAT 网关&#xff0c;拥有公有 IP &#xff0c;同时负责将针对此…

开源博客项目Blog .NET Core源码学习(11:App.Core项目结构分析)

开源博客项目Blog的App.Core项目主要定义数据库表对应的数据类&#xff0c;同时定义配置文件读取、日志记录、辅助缓存等辅助类。App.Core项目安装的Nuget包不多&#xff0c;仅包括SqlSugarCore和Microsoft.Extensions.DependencyInjectio两类。   App.Core项目的顶层文件夹如…

负氧离子监测站:创造健康生活环境

TH-FZ5在蓝天白云之下&#xff0c;那一座座高耸的全彩屏负氧离子监测站&#xff0c;如同一支支科技的绿芽&#xff0c;静静破土而出&#xff0c;为这片土地带来了新的生命力。这些现代化的设备不仅美化了环境&#xff0c;更是我们呼吸健康守护者&#xff0c;它们的存在让我们的…

OpenHarmony内核编程实战

在正式开始之前&#xff0c;对于刚接触OpenHarmony的伙伴们&#xff0c;面对大篇幅的源码可能无从下手&#xff0c;不知道怎么去编码写程序&#xff0c;下面用一个简单的例子带伙伴们入门。 ▍任务 编写程序&#xff0c;让开发板在串口调试工具中输出”Hello&#xff0c;Open…

TS函数类型

函数类型表达式 function hello(x: string) {console.log(x) } //greeter函数的参数是一个函数fn&#xff0c;fn也有一个string类型参数&#xff0c;无返回值。 function greeter(fn: (a: string) > void) {fn(hello) } greeter(hello)也可以把定义参数类型的语句单独提取出…

Ubuntu20.04下PCL安装,查看,卸载等操作

Ubuntu20.04下PCL安装&#xff0c;查看&#xff0c;卸载等操作 项目来源 https://github.com/PointCloudLibrary/pclhttps://pointclouds.org/documentation/modules.htmlhttps://pcl.readthedocs.io/projects/tutorials/en/master/ 点云学习&#xff1a; https://github.c…

Day57-Nginx反向代理与负载均衡初步应用

Day57-Nginx反向代理与负载均衡初步应用 1. Nginx代理介绍2. Nginx代理常见模式2.1 正向代理2.2 反向代理2.3 正向与反向代理区别 3. Nginx代理支持协议4. Nginx反向代理场景实践5. lb01安装部署nginx 1. Nginx代理介绍 1&#xff09;在没有代理的情况下&#xff0c;都是客户端…

苹果与百度合作,将在iPhone 16中使用生成式AI

3月25日&#xff0c;《科创板日报》消息&#xff0c;苹果将与百度进行技术合作&#xff0c;为今年即将发布的iPhone16、Mac系统和iOS 18提供生成式AI&#xff08;AIGC&#xff09;功能。 据悉&#xff0c;苹果曾与阿里巴巴以及另外一家国产大模型厂商进行了技术合作洽谈。最终…

信号处理--基于混合CNN和transfomer自注意力的多通道脑电信号的情绪分类的简单应用

目录 关于 工具 数据集 数据集简述 方法实现 数据读取 ​编辑数据预处理 传统机器学习模型(逻辑回归&#xff0c;支持向量机&#xff0c;随机森林) 多层感知机模型 CNNtransfomer模型 代码获取 关于 本实验利用结合了卷积神经网络 (CNN) 和 Transformer 组件的混合…

Qt 作业 24/3/26

1、实现闹钟 #ifndef WIDGET_H #define WIDGET_H#include <QWidget> #include <QTime> #include <QLineEdit>QT_BEGIN_NAMESPACE namespace Ui { class Widget; } QT_END_NAMESPACEclass Widget : public QWidget {Q_OBJECTpublic:Widget(QWidget *parent …

FPGA之状态机学习

作为一名逻辑工程师&#xff0c;掌握和应用状态机设计是必不可少的。能够灵活的应用状态机是对逻辑工程师最基本的要求&#xff0c;状态机设计的好坏能够直接影响到设计系统的稳定性&#xff0c;所以学会状态机是非常的重要。 1.状态机的概念 状态机通过不同的状态迁移来完成特…

STM32之HAL开发——串口配置(源码)

串口收发原理框图&#xff08;F1系列&#xff09; 注意&#xff1a;数据寄存器有俩个一个是收一个是发&#xff0c;但是在标准库或者HAL库中没有特别区分开来是俩个寄存器&#xff01; USART 初始化结构体详解 HAL 库函数对每个外设都建立了一个初始化结构体&#xff0c;比如 …

如何快速在ESXi中嵌套部署一台ESXi服务器?

正文共&#xff1a;1234 字 26 图&#xff0c;预估阅读时间&#xff1a;2 分钟 我们之前介绍过VMWare ESXi服务器镜像的定制&#xff08;VMware ESXi部署镜像定制&#xff09;和部署&#xff08;惠普VMware ESXI 6.7定制版部署&#xff09;&#xff0c;但是还没有介绍过ESXi版本…

YOLOv8改进 | 主干篇 | 修复官方去除掉PP-HGNetV2的通道缩放功能(轻量又涨点,全网独家整理)

一、本文介绍 本文给大家带来的改进机制是大家在跑RT-DETR提供的HGNetV2时的一个通道缩放功能&#xff08;官方在前几个版本去除掉的一个功能&#xff09;&#xff0c;其中HGNetV2当我们将其集成在YOLOv8n的模型上作为特征提取主干的时候参数量仅为230W 计算量为6.7GFLOPs该网…

【机器学习之---数学】随机游走

every blog every motto: You can do more than you think. https://blog.csdn.net/weixin_39190382?typeblog 0. 前言 随机游走 1. 概念 1.1 例1 在你的饮食俱乐部度过了一个富有成效的晚上后&#xff0c;你在不太清醒的状态下离开了。因此&#xff0c;你会醉醺醺地在展…

【opencv】实时位姿估计(real_time_pose_estimation)—3D模型注册

相机成像原理图 物体网格、关键点&#xff08;局内点、局外点&#xff09;图像 box.ply resized_IMG_3875.JPG 主程序main_registration.cpp 主要实现了利用OpenCV库进行3D模型的注册。主要步骤包括加载3D网格模型、使用鼠标事件选择对应的3D点进行2D到3D的注册、利用solvePnP算…

在django中使用kindeditor出现转圈问题

在django中使用kindeditor出现转圈问题 【一】基础检查 【1】前端检查 确保修改了uploadJson的默认地址 该地址需要在路由层有映射关系 确认有加载官方文件 kindeditor-all-min.js确保有传递csrfmiddlewaretoken 或者后端关闭了csrf验证 <textarea name"content&qu…

无人驾驶矿卡整体解决方案(5g物联网通信方案)

​无人驾驶矿卡是智能矿山的重要组成部分,通过远程操控替代人工驾驶,可以显著提高采矿效率和作业安全性。但要实现无人驾驶矿卡,需要依赖于可靠高效的通信网络,来传输现场视频、控制指令和运行数据。以下是某大型煤矿在部署无人驾驶矿卡时,所采用的星创易联物联网整体解决方案。…