<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.

最新文章

  1. 解决 android 高低版本 webView 里内容 自适应屏幕的终极方法
  2. 通过通知监听键盘的状态来改变View的位置
  3. Eclipse中启动tomcat报错:A child container failed during start
  4. angularJs 使用中遇到的问题小结【二:购物车引起的问题思考】
  5. 高级I/O函数(3)-tee、fcntl函数
  6. PowerShell_零基础自学课程_5_自定义PowerShell环境及Powershell中的基本概念
  7. Object 保存到文件中
  8. Refused to set unsafe header &quot;Connection&quot;
  9. 从Chrome源码看JS Array的实现
  10. git使用3
  11. [leetcode-507-Perfect Number]
  12. spring boot整合mybatis方式一
  13. 【Python学习】iterator 迭代器小练习
  14. win7系统标准用户恢复administrator账号方法
  15. 【Python】【BugList12】python自带IDLE执行print(req.text)报错:UnicodeEncodeError: &#39;UCS-2&#39; codec can&#39;t encode characters in position 93204-93204
  16. R语言修改标题、坐标轴刻度、坐标轴名称的大小(cex.axis、cex.lab、cex.main函数)
  17. SSL证书没有绿锁您与此网站建立的连接并非完全安全解决办法
  18. OpenGL ES 2 for Android - A Quick Start Guide
  19. UNITY_委托和事件
  20. NUC131的系统管理

热门文章

  1. windows 10下oracle相关异常及处理方法
  2. GitHub客户端使用
  3. Debian\CentOS Linux配置管理
  4. linux homebrew skill 技巧
  5. AnswerOpenCV(0826-0901)一周佳作欣赏
  6. Codeforces 839B Game of the Rows - 贪心
  7. XcodeProj,使用Ruby更改工程文件
  8. 压测freeswitch--安装sipp
  9. ODAC(V9.5.15) 学习笔记(四)TOraQuery (1)
  10. CodeForces 430A Points and Segments (easy)(构造)题解