首页 > javascript相关 > vue教程 > 正文

Element Input组件分析小结_vue.js

2018-11-10 10:00:34

input组件相对来说复杂一点,我们先从它用到的一个工具库calcTextareaHeight.js进行分析。

calcTextareaHeight.js

calcTextareaHeight.js使用来计算文本框的高度的,我们根据代码顺序从上往下进行分析。

HIDDEN_STYLE

HIDDEN_STYLE是一个常量,存储隐藏时候的css样式的。

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`;

CONTEXT_STYLE

CONTEXT_STYLE也是一个常量,用来存储要查询的样式名。

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'];

calculateNodeStyling

calculateNodeStyling用来获取结点的某些样式。

function calculateNodeStyling(node) { const style = window.getComputedStyle(node); // 获取结点的计算后的样式,即实际渲染的样式 const boxSizing = style.getPropertyValue('box-sizing'); // 获取 box-sizing 的值 // 上下的 padding 之和 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')) ); // 其他一些样式 const contextStyle = CONTEXT_STYLE  .map(name => `${name}:${style.getPropertyValue(name)}`)  .join(';'); return { contextStyle, paddingSize, borderSize, boxSizing };}

calcTextareaHeight

calcTextareaHeight是最终暴露出去的函数,用来计算文本域的高度。

export default function calcTextareaHeight( targetNode, // 要计算的结点 minRows = null, // 最小的行数 maxRows = null // 最大的行数) { if (!hiddenTextarea) { // 来创建一个隐藏的文本域,所有的计算都是在这上面进行的  hiddenTextarea = document.createElement('textarea');  document.body.appendChild(hiddenTextarea); } // 获取结点一些样式值 let {  paddingSize,  borderSize,  boxSizing,  contextStyle } = calculateNodeStyling(targetNode); // 设置相应的样式 hiddenTextarea.setAttribute('style', `${contextStyle};${HIDDEN_STYLE}`); // 设置内容,按优先级一次是 结点的 value, 结点的 placeholder, 以及空字符串 hiddenTextarea.value = targetNode.value || targetNode.placeholder || ''; // 获取滚动高度 let height = hiddenTextarea.scrollHeight; if (boxSizing === 'border-box') {  // 如果是 border-box,说明高度得加上边框  height = height + borderSize; } else if (boxSizing === 'content-box') {  // 如果是 content-box,说明得减去上下内边距  height = height - paddingSize; } // 计算单行高度,先清空内容 hiddenTextarea.value = ''; // 再用滚动高度减去上下内边距 let singleRowHeight = hiddenTextarea.scrollHeight - paddingSize; if (minRows !== null) { // 如果参数传递了 minRows  let minHeight = singleRowHeight * minRows; // 说明最少应当有这么多行的高度  if (boxSizing === 'border-box') { // 如果是 border-box,还得加上上下内边距和上下边框的宽度   minHeight = minHeight + paddingSize + borderSize;  }  height = Math.max(minHeight, height); // 取二者最大值 } if (maxRows !== null) { // 如果参数传递了 maxRows  let maxHeight = singleRowHeight * maxRows; // 说明最多只能有这么多行的高度  if (boxSizing === 'border-box') { // 如果是 border-box,还得加上上下内边距和上下边框的宽度   maxHeight = maxHeight + paddingSize + borderSize;  }  height = Math.min(maxHeight, height); // 取二者最小值 } // 返回文本域应当设置的高度 return { height: height + 'px'};};

input.vue

input组件较为繁琐,我们一点点分析。

生命周期

created

创建的时候会监听inputSelect事件,并调用inputSelect方法。

created() { this.$on('inputSelect', this.inputSelect);},

inputSelect方法会调用refs上的input的原生的select方法,来选中该input。

methods: { inputSelect() {  this.$refs.input.select(); },}

mounted

挂载的时候,会调用resizeTextarea方法来设置文本域的大小。

mounted() { this.resizeTextarea();}
methods: { resizeTextarea() {  if (this.$isServer) return; // 如果是服务端渲染,直接返回,不进行下面的逻辑  var { autosize, type } = this;  if (!autosize || type !== 'textarea') return; // 如果 autosize 是 false,或者当前不是文本域,也直接返回  const minRows = autosize.minRows; // 最少行数  const maxRows = autosize.maxRows; // 最大行数  this.textareaStyle = calcTextareaHeight(this.$refs.textarea, minRows, maxRows); // 计算文本域的高度,并赋值 },}

最外层

最外层是一个div,上面设置了一些动态的class。

<div :class="[ type === 'textarea' ? 'el-textarea' : 'el-input', size ? 'el-input--' + size : '', {  'is-disabled': disabled,  'el-input-group': $slots.prepend || $slots.append,  'el-input-group--append': $slots.append,  'el-input-group--prepend': $slots.prepend }]"></div>

type

type是一个prop,它默认设置为text,如果设置为textarea,表明当前是一个文本域。

props: { type: {  type: String,  default: 'text' },}

size

size也是一个prop,用来设置输入框的大小,在textarea下无效。

props: { size: String,}

disabled

disabled也是一个prop,用来设置是否可用。

props: { disabled: Boolean,}

prepend、append

这两个都是在设置输入框组的时候使用的,通过具名slot传入,分别放置于input的首和尾。

input

然后,根据type的不同使用v-if分别渲染input或者textarea,我们先分析input部分。

前置元素

前置元素直接通过具名slot传入。

<div class="el-input-group__prepend" v-if="$slots.prepend"> <slot name="prepend"></slot></div>

input 图标

图标也是通过具名slot传入的,也可以通过prop中的icon传入图标名。

<slot name="icon"> <i  class="el-input__icon"  :class="'el-icon-' + icon"  v-if="icon"  @click="handleIconClick"> </i></slot>

上面还绑定了一个handleIconClick的点击事件,它会触发click事件:

methods: { handleIconClick(event) {  this.$emit('click', event); },}

input

然后是最重要的input部分,上面大部分是prop,不进行讲解,其余的我们将一一讲解。

<input v-if="type !== 'textarea'" class="el-input__inner" :type="type" // 类型 :name="name" // 名字 :placeholder="placeholder" // 默认值 :disabled="disabled" // 是否禁用 :readonly="readonly" // 是否只读 :maxlength="maxlength" // 输入的最大长度 :minlength="minlength" // 输入的最小长度(暂时不支持) :autocomplete="autoComplete" // 自动补全 :autofocus="autofocus" // 自动聚焦 :min="min" // 允许输入的最小值(数字或者日期) :max="max" // 允许输入的最大值(数字或者日期) :form="form" // 绑定的表单(不是原生的) :value="currentValue" // 输入值 ref="input" // 引用 @input="handleInput" // 输入事件 @focus="handleFocus" // 获得焦点事件 @blur="handleBlur" // 失去焦点事件>

value

value改变的时候会调用setCurrentValue。

watch: { 'value'(val, oldValue) {  this.setCurrentValue(val); }},

而setCurrentValue是用来改变当前值的。

methods: { setCurrentValue(value) {  if (value === this.currentValue) return; // 如果新旧值一致直接返回  this.$nextTick(_ => {   this.resizeTextarea(); // 下一个DOM更新周期时,重新设置文本域大小  });  this.currentValue = value; // 改变当前值  this.$emit('input', value); // 触发 input 事件  this.$emit('change', value); // 触发 change 事件  this.dispatch('ElFormItem', 'el.form.change', [value]); // 向父级的派发 el.form.change 事件 }}

handleInput

处理输入事件。

methods: { handleInput(event) {  this.setCurrentValue(event.target.value); // 改变当前值 },}

handleFocus

handleFocus用来处理获得焦点的事件,会直接触发focus事件。

methods: { handleFocus(event) {  this.$emit('focus', event); },}

handleBlur

handleBlur用来处理失去焦点的事件。

methods: { handleBlur(event) {  this.$emit('blur', event); // 触发 blur 事件  this.dispatch('ElFormItem', 'el.form.blur', [this.currentValue]); // 向父组件派发 el.form.blur 事件 },}

loading

loading会根据计算属性validating来决定是否渲染。

computed: { validating() {  return this.$parent.validateState === 'validating'; }},
<i class="el-input__icon el-icon-loading" v-if="validating"></i>

后置元素

后置元素只能根据具名slot传入。

<div class="el-input-group__append" v-if="$slots.append"> <slot name="append"></slot></div>

Textarea

如果type设置为textarea则会渲染textarea,上面绑定的都和input类似,不再多说,多了一个textareaStyle,是根据calcTextareaHeight计算出来的。

<textarea v-else class="el-textarea__inner" :value="currentValue" @input="handleInput" ref="textarea" :name="name" :placeholder="placeholder" :disabled="disabled" :style="textareaStyle" :readonly="readonly" :rows="rows" :form="form" :autofocus="autofocus" :maxlength="maxlength" :minlength="minlength" @focus="handleFocus" @blur="handleBlur"></textarea>

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

  • 相关标签:vue教程
  • 本文发布HTML5中文学习网 ,转载请注明出处,感谢您!
  • 相关文章


  • 曝网友假装外国人写投诉信 ofo秒退押金并回函致歉
  • 苹果市值缩水逾2000亿美元 遭多家投行下调目标价
  • Asp.net Core与类库读取配置文件信息的方法_实用技巧
  • asp.net在Repeater嵌套的Repeater中使用复选框详解_实用技巧
  • 利用IIS调试ASP.NET网站程序的完整步骤_实用技巧
  • Asp.Net Core轻松学习系列之配置文件_实用技巧
  • ASP.NET 页生命周期概述(小结)_实用技巧
  • 详解ASP.NET Core WebApi 返回统一格式参数_实用技巧
  • 2018年网络流行语有哪些?2018年十大网络流行语盘点
  • 华为首席财务官孟晚舟被暂扣 深圳市政府要求加方立即放人!
  • 独孤九贱(4)_PHP视频教程

    江湖传言:PHP是世界上最好的编程语言。真的是这样吗?这个梗究竟是从哪来的?学会本课程,你就会明白了。 PHP中文网出品的PHP入门系统教学视频,完全从初学者的角度出发,绝不玩虚的,一切以实用、有用...

    独孤九贱(5)_ThinkPHP5视频教程

    ThinkPHP是国内最流行的中文PHP开发框架,也是您Web项目的最佳选择。《php.cn独孤九贱(5)-ThinkPHP5视频教程》课程以ThinkPHP5最新版本为例,从最基本的框架常识开始,将...

    独孤九贱(1)_HTML5视频教程

    《php.cn原创html5视频教程》课程特色:php中文网原创幽默段子系列课程,以恶搞,段子为主题风格的php视频教程!轻松的教学风格,简短的教学模式,让同学们在不知不觉中,学会了HTML知识。 ...

    ThinkPHP5实战之[教学管理系统]

    本套教程,以一个真实的学校教学管理系统为案例,手把手教会您如何在一张白纸上,从零开始,一步一步的用ThinkPHP5框架快速开发出一个商业项目。

    PHP入门视频教程之一周学会PHP

    所有计算机语言的学习都要从基础开始,《PHP入门视频教程之一周学会PHP》不仅是PHP的基础部分更主要的是PHP语言的核心技术,是学习PHP必须掌握的内容,任何PHP项目的实现都离不开这部分的内容,通...

    作者信息

    kevin

    永远在学习的路上!

    相关教程

  • javascript初级视频教程 javascript初级视频教程
  • jquery 基础视频教程 jquery 基础视频教程
  • javascript三级联动视频教程 javascript三级联动视频教程
  • 独孤九贱(3)_JavaScript视频教程 独孤九贱(3)_JavaScript视频教程
  • 独孤九贱(6)_jQuery视频教程 独孤九贱(6)_jQuery视频教程
  • 热门教程