vux的x-input的源码分析
<template>
<div class="vux-x-input weui-cell" :class="{'weui-cell_warn': showWarn}">
<div class="weui-cell__hd">
<div :style="labelStyles" v-if="hasRestrictedLabel">
<slot name="restricted-label"></slot>
</div>
<slot name="label">
<label class="weui-label" :class="labelClass" :style="{width: labelWidth || $parent.labelWidth || labelWidthComputed, textAlign: $parent.labelAlign, marginRight: $parent.labelMarginRight}" v-if="title" v-html="title"></label>
<inline-desc v-if="inlineDesc">{{inlineDesc}}</inline-desc>
</slot>
</div>
<div class="weui-cell__bd weui-cell__primary" :class="placeholderAlign ? `vux-x-input-placeholder-${placeholderAlign}` : ''">
<input
v-if="!type || type === 'text'"
class="weui-input"
:maxlength="max"
:autocomplete="autocomplete"
:autocapitalize="autocapitalize"
:autocorrect="autocorrect"
:spellcheck="spellcheck"
:style="inputStyle"
type="text"
:name="name"
:pattern="pattern"
:placeholder="placeholder"
:readonly="readonly"
:disabled="disabled"
v-model="currentValue"
@focus="focusHandler"
@blur="onBlur"
@keyup="onKeyUp"
ref="input"/>
<input
v-if="type === 'number'"
class="weui-input"
:maxlength="max"
:autocomplete="autocomplete"
:autocapitalize="autocapitalize"
:autocorrect="autocorrect"
:spellcheck="spellcheck"
:style="inputStyle"
type="number"
:name="name"
:pattern="pattern"
:placeholder="placeholder"
:readonly="readonly"
:disabled="disabled"
v-model="currentValue"
@focus="focusHandler"
@blur="onBlur"
@keyup="onKeyUp"
ref="input"/>
<input
v-if="type === 'email'"
class="weui-input"
:maxlength="max"
:autocomplete="autocomplete"
:autocapitalize="autocapitalize"
:autocorrect="autocorrect"
:spellcheck="spellcheck"
:style="inputStyle"
type="email"
:name="name"
:pattern="pattern"
:placeholder="placeholder"
:readonly="readonly"
:disabled="disabled"
v-model="currentValue"
@focus="focusHandler"
@blur="onBlur"
@keyup="onKeyUp"
ref="input"/>
<input
v-if="type === 'password'"
class="weui-input"
:maxlength="max"
:autocomplete="autocomplete"
:autocapitalize="autocapitalize"
:autocorrect="autocorrect"
:spellcheck="spellcheck"
:style="inputStyle"
type="password"
:name="name"
:pattern="pattern"
:placeholder="placeholder"
:readonly="readonly"
:disabled="disabled"
v-model="currentValue"
@focus="focusHandler"
@blur="onBlur"
@keyup="onKeyUp"
ref="input"/>
<input
v-if="type === 'tel'"
class="weui-input"
:maxlength="max"
:autocomplete="autocomplete"
:autocapitalize="autocapitalize"
:autocorrect="autocorrect"
:spellcheck="spellcheck"
:style="inputStyle"
type="tel"
:name="name"
:pattern="pattern"
:placeholder="placeholder"
:readonly="readonly"
:disabled="disabled"
v-model="currentValue"
@focus="focusHandler"
@blur="onBlur"
@keyup="onKeyUp"
ref="input"/>
</div>
<div class="weui-cell__ft">
<icon type="clear" v-show="!equalWith && showClear && currentValue && !readonly && !disabled" @click.native="clear"></icon> <icon class="vux-input-icon" type="warn" :title="!valid ? firstError : ''" v-show="showWarn"></icon>
<icon class="vux-input-icon" type="warn" v-if="!novalidate && hasLengthEqual && dirty && equalWith && !valid"></icon>
<icon type="success" v-show="!novalidate && equalWith && equalWith === currentValue && valid"></icon> <icon type="success" class="vux-input-icon" v-show="novalidate && iconType === 'success'"></icon>
<icon type="warn" class="vux-input-icon" v-show="novalidate && iconType === 'error'"></icon> <slot name="right"></slot>
</div>
</div>
</template> <script>
import Base from '../../libs/base'
import Icon from '../icon'
import InlineDesc from '../inline-desc' import isEmail from 'validator/lib/isEmail'
import isMobilePhone from 'validator/lib/isMobilePhone' import Debounce from '../../tools/debounce' const validators = {
'email': {
fn: isEmail,
msg: '邮箱格式'
},
'china-mobile': {
fn (str) {
return isMobilePhone(str, 'zh-CN')
},
msg: '手机号码'
},
'china-name': {
fn (str) {
return str.length >= && str.length <=
},
msg: '中文姓名'
}
}
export default {
name: 'x-input',
created () {
this.currentValue = (this.value === undefined || this.value === null) ? '' : this.value
if (!this.title && !this.placeholder && !this.currentValue) {
console.warn('no title and no placeholder?')
}
if (this.required && !this.currentValue) {
this.valid = false
}
this.handleChangeEvent = true
if (this.debounce) {
this._debounce = Debounce(() => {
this.$emit('on-change', this.currentValue)
}, this.debounce)
}
},
mounted () {
if (this.$slots && this.$slots['restricted-label']) {
this.hasRestrictedLabel = true
}
},
beforeDestroy () {
if (this._debounce) {
this._debounce.cancel()
}
},
mixins: [Base],
components: {
Icon,
InlineDesc
},
props: {
title: {
type: String,
default: ''
},
type: {
type: String,
default: 'text'
},
placeholder: String,
value: [String, Number],
name: String,
readonly: Boolean,
disabled: Boolean,
keyboard: String,
inlineDesc: String,
isType: [String, Function],
min: Number,
max: Number,
showClear: {
type: Boolean,
default: true
},
equalWith: String,
textAlign: String,
// https://github.com/yisibl/blog/issues/3
autocomplete: {
type: String,
default: 'off'
},
autocapitalize: {
type: String,
default: 'off'
},
autocorrect: {
type: String,
default: 'off'
},
spellcheck: {
type: String,
default: 'false'
},
novalidate: {
type: Boolean,
default: false
},
iconType: String,
debounce: Number,
placeholderAlign: String,
labelWidth: String
},
computed: {
labelStyles () {
return {
width: this.labelWidthComputed || this.$parent.labelWidth || this.labelWidthComputed,
textAlign: this.$parent.labelAlign,
marginRight: this.$parent.labelMarginRight
}
},
labelClass () {
return {
'vux-cell-justify': this.$parent.labelAlign === 'justify' || this.$parent.$parent.labelAlign === 'justify'
}
},
pattern () {
if (this.keyboard === 'number' || this.isType === 'china-mobile') {
return '[0-9]*'
}
},
labelWidthComputed () {
const width = this.title.replace(/[^x00-xff]/g, '').length / +
if (width < ) {
return width + 'em'
}
},
hasErrors () {
return Object.keys(this.errors).length >
},
inputStyle () {
if (this.textAlign) {
return {
textAlign: this.textAlign
}
}
},
showWarn () {
return !this.novalidate && !this.equalWith && !this.valid && this.firstError && (this.touched || this.forceShowError)
}
},
methods: {
reset (value = '') {
this.dirty = false
this.currentValue = value
this.firstError = ''
this.valid = true
},
clear () {
this.currentValue = ''
this.focus()
},
focus () {
this.$refs.input.focus()
},
blur () {
this.$refs.input.blur()
},
focusHandler ($event) {
this.$emit('on-focus', this.currentValue, $event)
},
onBlur ($event) {
this.setTouched()
this.validate()
this.$emit('on-blur', this.currentValue, $event)
},
onKeyUp (e) {
if (e.key === 'Enter') {
e.target.blur()
this.$emit('on-enter', this.currentValue, e)
}
},
getError () {
let key = Object.keys(this.errors)[]
this.firstError = this.errors[key]
},
validate () {
if (typeof this.equalWith !== 'undefined') {
this.validateEqual()
return
}
this.errors = {} if (!this.currentValue && !this.required) {
this.valid = true
return
} if (!this.currentValue && this.required) {
this.valid = false
this.errors.required = '必填哦'
this.getError()
return
} if (typeof this.isType === 'string') {
const validator = validators[this.isType]
if (validator) {
this.valid = validator[ 'fn' ](this.currentValue)
if (!this.valid) {
this.forceShowError = true
this.errors.format = validator[ 'msg' ] + '格式不对哦~'
this.getError()
return
} else {
delete this.errors.format
}
}
} if (typeof this.isType === 'function') {
const validStatus = this.isType(this.currentValue)
this.valid = validStatus.valid
if (!this.valid) {
this.errors.format = validStatus.msg
this.forceShowError = true
if (!this.firstError) {
this.getError()
}
return
} else {
delete this.errors.format
}
} if (this.min) {
if (this.currentValue.length < this.min) {
this.errors.min = `最少应该输入${this.min}个字符哦`
this.valid = false
if (!this.firstError) {
this.getError()
}
return
} else {
delete this.errors.min
}
} if (this.max) {
if (this.currentValue.length > this.max) {
this.errors.max = `最多可以输入${this.max}个字符哦`
this.valid = false
this.forceShowError = true
return
} else {
this.forceShowError = false
delete this.errors.max
}
} this.valid = true
},
validateEqual () {
if (!this.equalWith && this.currentValue) {
this.valid = false
this.errors.equal = '输入不一致'
return
}
let willCheck = this.dirty || this.currentValue.length >= this.equalWith.length
// 只在长度符合时显示正确与否
if (willCheck && this.currentValue !== this.equalWith) {
this.valid = false
this.errors.equal = '输入不一致'
return
} else {
if (!this.currentValue && this.required) {
this.valid = false
} else {
this.valid = true
delete this.errors.equal
}
}
}
},
data () {
let data = {
hasRestrictedLabel: false,
firstError: '',
forceShowError: false,
hasLengthEqual: false,
valid: true,
currentValue: ''
}
return data
},
watch: {
valid () {
this.getError()
},
value (val) {
this.currentValue = val
},
equalWith (newVal) {
if (newVal && this.equalWith) {
if (newVal.length === this.equalWith.length) {
this.hasLengthEqual = true
}
this.validateEqual()
} else {
this.validate()
}
},
currentValue (newVal) {
if (!this.equalWith && newVal) {
this.validateEqual()
}
if (newVal && this.equalWith) {
if (newVal.length === this.equalWith.length) {
this.hasLengthEqual = true
}
this.validateEqual()
} else {
this.validate()
}
this.$emit('input', newVal)
if (this._debounce) {
this._debounce()
} else {
this.$emit('on-change', newVal)
}
}
}
}
</script> <style lang="less">
@import '../../styles/weui/widget/weui_cell/weui_access';
@import '../../styles/weui/widget/weui_cell/weui_cell_global';
@import '../../styles/weui/widget/weui_cell/weui_form/weui_form_common';
@import '../../styles/weui/widget/weui_cell/weui_form/weui_vcode';
.vux-x-input .vux-x-input-placeholder-right input::-webkit-input-placeholder {
text-align: right;
}
.vux-x-input .vux-x-input-placeholder-center input::-webkit-input-placeholder {
text-align: center;
}
.vux-x-input .vux-input-icon {
font-size: 21px;
}
.vux-input-icon.weui-icon-warn:before, .vux-input-icon.weui-icon-success:before {
font-size: 21px;
}
.vux-x-input .weui-icon {
padding-left: 5px;
}
.vux-x-input.weui-cell_vcode {
padding-top: ;
padding-right: ;
padding-bottom: ;
}
</style>
1.学习到的props中继承的属性时,引用的时候没有必要在属性前添加:。
2.:class 和class可以并存。
3. 双引号中套单引号。

4.右边嵌入一个框的时候,:class中嵌入一个,在icon中嵌入一个。

5.
vux的x-input的源码分析的更多相关文章
- element-ui input组件源码分析整理笔记(六)
input 输入框组件 源码: <template> <div :class="[ type === 'textarea' ? 'el-textarea' : 'el-in ...
- element-ui 组件源码分析整理笔记目录
element-ui button组件 radio组件源码分析整理笔记(一) element-ui switch组件源码分析整理笔记(二) element-ui inputNumber.Card .B ...
- HashMap与TreeMap源码分析
1. 引言 在红黑树--算法导论(15)中学习了红黑树的原理.本来打算自己来试着实现一下,然而在看了JDK(1.8.0)TreeMap的源码后恍然发现原来它就是利用红黑树实现的(很惭愧学了Ja ...
- ABP源码分析十六:DTO的设计
IDTO:空接口,用于标注Dto对象. ComboboxItemDto:用于combobox/list中Item的DTO NameValueDto<T>/NameValueDto:用于na ...
- ABP源码分析十八:UI Inputs
以下图中描述的接口和类都在Abp项目的Runtime/Validation, UI/Inputs目录下的.在当前版本的ABP(0.83)中这些接口和类并没有实际使用到.阅读代码时可以忽略,无需浪费时间 ...
- Spark中决策树源码分析
1.Example 使用Spark MLlib中决策树分类器API,训练出一个决策树模型,使用Python开发. """ Decision Tree Classifica ...
- jQuery-1.9.1源码分析系列(十) 事件系统——事件体系结构
又是一个重磅功能点. 在分析源码之前分析一下体系结构,有助于源码理解.实际上在jQuery出现之前,Dean Edwards的跨浏览器AddEvent()设计做的已经比较优秀了:而且jQuery事件系 ...
- jQuery-1.9.1源码分析系列(二)jQuery选择器
1.选择器结构 jQuery的选择器根据源码可以分为几块 init: function( selector, context, rootjQuery ) { ... // HANDLE: $(&quo ...
- Struts2 源码分析——配置管理之PackageProvider接口
本章简言 上一章讲到关于ContainerProvider的知识.让我们知道struts2是如何注册相关的数据.也知道如何加载相关的配置信息.本章笔者将讲到如何加载配置文件里面的package元素节点 ...
- Spring源码分析——资源访问利器Resource之接口和抽象类分析
从今天开始,一步步走上源码分析的路.刚开始肯定要从简单着手.我们先从Java发展史上最强大的框架——Spring...旗下的资源抽象接口Resource开始吧. 我看了好多分析Spring源码的,每每 ...
随机推荐
- python网络编程及高并发问题
面试其他篇 目录: 1.1
- eclipse中的ctrl+H使用中的问题
一.问题背景 ctrl+H其实包含好几个search如果是FileSearch,在第一个输入框是要搜索的文字,第二个是文件名(支持通配符:*.js或者*.*),下面是选择搜索的范围,然后点seach. ...
- OO第三次博客作业---透过代码看设计
不得不说的JSF 经过前几次作业的煎熬.出租车的代码量不断地增多.而出租车问题在不断的完善,这也就牵涉到一个问题,那就是最初出租车程序的设计问题,如果一开始设计的就有问题的话,那么在后来的过程中就会遇 ...
- Codeforces 375C Circling Round Treasures - 最短路 - 射线法 - 位运算
You have a map as a rectangle table. Each cell of the table is either an obstacle, or a treasure wit ...
- 16 级高代 II 思考题九的七种解法
16 级高代 II 思考题九 设 $V$ 是数域 $\mathbb{K}$ 上的 $n$ 维线性空间, $\varphi$ 是 $V$ 上的线性变换, $f(\lambda),m(\lambda)$ ...
- XXXcannot be resolved to a type
编写自动化测试用例一个新创建的用例中类继承了其他类,由于未知原因,eclipse没能自动编译源代码到build/classes(或其他classes目录)代码一直报错XXX cannot be res ...
- topcoder srm 485 div1
problem1 link 枚举第一个数和第二个数即可确定公差. problem2 link 设高度为$n$,宽度为$m$,且$n \ge m$ 如果$m \ge 5$,那么答案为0.这个可以通过抽屉 ...
- dart基础语法
.关于 runApp() 上面的实例代码中使用了 runApp() 方法,runApp 方法接收的指定参数类型为 Widget,即: runApp(Widget).在 Flutter 的组件树(wid ...
- linux内核中宏likely和unlikely到底做了些什么?
1. 先看看它们长啥样吧!(它们有两种定义,第一种是使能了程序trace功能的宏定义,第二种是普通的宏定义,咱们分析普通宏定义吧) # define likely(x) __builtin_expec ...
- 【POJ1961】period
[POJ1961]period 题目描述 如果一个字符串S是由一个字符串T重复K次构成的,则称T是S的循环元.使K出现最大的字符串T称为S的最小循环元,此时的K称为最大循环次数. 现在给定一个长度为N ...