<!-- 自定义Input组件 -->
<template>
<div class="input-container">
<el-input v-if="type === 'float'"
ref="floatInput"
v-model="inputModel"
class="my-number-input"
:maxlength="maxLength"
oninput="value=value.replace(/^\D*(\d*(?:\.\d{0,2})?).*$/g, '$1').trim()"
:size="size"
:readonly="readOnly"
:placeholder="placeholder"
@change.native="amountchange($event)"
@blur="checkValue(inputModel)"
@clear="checkValueClear(inputModel)">
<span v-if="unitString && unitString.length > 0"
slot="suffix"
class="el-input__icon">
{{ unitString }}
</span>
</el-input>
<el-input v-if="type === 'minus-float'"
ref="floatInput"
v-model="inputModel"
class="my-number-input"
:maxlength="maxLength"
oninput="
if (value.slice(0, value.indexOf('-') + 2)) {
if(isNaN (value.slice(1, value.indexOf('-') + 9999))) {
value = value.substring(0, value.length - 1)
}
let dotIndex = value.indexOf('.')
if(dotIndex !== -1) {
value = value.substring(0, dotIndex + 3)
}
}
if (value.indexOf('.') > 0) {
value = value.slice(0, value.indexOf('.') + 9999)
}
if (value.slice(0, value.indexOf('-') + 2) !== '-') {
if (isNaN(value)) {
value = value.substring(0, value.length - 1)
}
}
"
:size="size"
:readonly="readOnly"
:placeholder="placeholder"
@change.native="amountchange($event)"
@blur="checkValue(inputModel)"
@clear="checkValueClear(inputModel)">
<span v-if="unitString && unitString.length > 0"
slot="suffix"
class="el-input__icon">
{{ unitString }}
</span>
</el-input>
<el-input v-if="type === 'numberString'"
ref="numberStringInput"
v-model="inputModel"
class="my-number-input"
:maxlength="maxLength"
:size="size"
:readonly="readOnly"
:placeholder="placeholder"
@input="(val) => handleNumberStringInput(val)"
@change.native="amountchange($event)"
@blur="checkValue(inputModel)"
@clear="checkValueClear(inputModel)">
<span v-if="unitString && unitString.length > 0"
slot="suffix"
class="el-input__icon">
{{ unitString }}
</span>
</el-input>
<el-input v-if="type === 'number'"
ref="numberInput"
v-model="inputModel"
class="my-number-input"
oninput="value=value.replace(/[^\d]/g,'').trim()"
:size="size"
:readonly="readOnly"
:placeholder="placeholder"
:maxlength="maxLength"
@change.native="amountchange($event)"
@blur="checkValue(inputModel)"
@clear="checkValueClear(inputModel)">
<span v-if="unitString && unitString.length > 0"
slot="suffix"
class="el-input__icon">
{{ unitString }}
</span>
</el-input>
<el-input v-if="type === 'mobile'"
ref="mobileInput"
v-model="inputModel"
class="my-number-input"
maxlength="11"
oninput="value=value.replace(/[^\d]/g,'').trim()"
:size="size"
:readonly="readOnly"
:placeholder="placeholder"
:suffix-icon="suffixIcon"
@change.native="amountchange($event)" />
<div v-if="type === 'idCard'"
class="input-with-button">
<el-input ref="idCardInput"
v-model="inputModel"
class="my-number-input"
maxlength="18"
oninput="value = value.replace(/[^\dXx]/g, '').trim().toUpperCase()"
:size="size"
:placeholder="placeholder"
:readonly="readOnly || inputReadOnly"
@change.native="amountchange($event)"
@blur="emitReadCard" />
<el-button v-if="!readOnly"
:size="size"
:loading="buttonLoading"
type="primary"
@click="readIdCard">
读卡
</el-button>
</div>
<div v-if="type === 'oneCard'"
class="input-with-button">
<el-input ref="oneCardInput"
v-model="inputModel"
class="my-number-input"
maxlength="19"
oninput="value=value.replace(/[^\d]/g,'').trim()"
:size="size"
:placeholder="placeholder"
:readonly="readOnly || inputReadOnly"
@change.native="amountchange($event)" />
<el-button :size="size"
:loading="buttonLoading"
type="primary"
@click="readCard">
读卡
</el-button>
</div>
<div v-if="type === 'SpecaloneCard'"
class="input-with-button">
<el-input ref="oneCardInput"
v-model="inputModel"
class="my-number-input"
maxlength="19"
oninput="value=value.replace(/[^\d]/g,'').trim()"
:size="size"
:placeholder="placeholder"
:readonly="readOnly || inputReadOnly"
@blur="SpecalcheckValue(inputModel)"
@change.native="amountchange($event)" />
<el-button :size="size"
:loading="buttonLoading"
type="primary"
@click="readCard">
读卡
</el-button>
</div>
<div v-if="type === 'shotMessage'"
class="input-with-button">
<el-input ref="shotMessageInput"
v-model="inputModel"
class="my-number-input"
maxlength="6"
oninput="value=value.replace(/[^\d]/g,'').trim()"
:size="size"
:placeholder="placeholder"
:readonly="readOnly"
@change.native="amountchange($event)" />
<el-button :size="size"
:loading="buttonLoading"
type="primary"
:disabled="isMobileValidate"
@click="sendVerificationCode">
{{ numCodeText }}
</el-button>
</div>
<div v-if="type === 'qrCode'"
class="qrCode-area">
<div v-if="inputModel === null || inputModel === ''"
class="qrCode-area-div">
<span v-if="qrFocuseFlag">
<i class="el-icon-loading" />{{ qrCodeText }}
</span>
<span v-if="!qrFocuseFlag">
<i class="fa fa-terminal" />{{ qrCodeText }}
</span>
<el-button v-if="!qrFocuseFlag"
size="small"
type="text"
@click="resetQrCode">
重新扫描
</el-button>
</div>
<div v-if="inputModel && inputModel.length > 0"
class="qrCode-area-div">
<span> <i class="fa fa-qrcode" />{{ qrCodeText }} </span>
<el-button type="text"
size="small"
@click="resetQrCode">
重新扫描
</el-button>
</div>
<el-input ref="qrCodeInput"
v-model="inputModel"
class="my-number-input"
:size="size"
@change="emitQrCode"
@blur="qrCodeInputBlur" />
</div>
</div>
</template>
<script type="text/ecmascript-6">
import jsonp from 'jsonp'
import {
sendVerificationCode,
isUsableCards
} from '@/api/omnipotent-card/oneCard'
export default {
components: {},
props: {
point: {
type: Number,
default: 0
},
min: {
type: [String, Number],
default: null
},
max: {
type: [String, Number],
default: null
},
maxLength: {
type: Number,
default: 10
},
placeholder: {
type: String,
default: ''
},
value: {
type: [String, Number],
default: null
},
size: {
type: String,
default: 'small'
},
type: {
type: String,
default: 'float'
},
unitString: {
type: String,
default: ''
},
readOnly: {
type: Boolean,
default: false
},
inputReadOnly: {
type: Boolean,
default: false
},
buttonLoading: {
type: Boolean,
default: false
},
mobile: {
type: String,
default: ''
},
rangeType: { // 区间范围输入框 0:不是 1:是
type: Number,
default: 0
},
templateType: {
type: Number,
default: null
},
suffixIcon: {
type: String,
default: ''
}
},
data () {
return {
keyDownDel: false, // 判断键盘输入值
cardType: 0, // 0:一卡通 1:润通卡,7: 身份证
cardNo: '',
idCardName: '',
numCodeText: '发送验证码',
qrCodeText: '扫描二维码中……',
qrFocuseFlag: true
}
},
computed: {
inputModel: {
get: function () {
// 父组件==>子组件 发消息
return this.value
},
set: function (value) {
// console.log(this.$refs.floatInput.value)
if (this.type === 'float') {
// 解决首位直接输入 '0开头的数字'问题
if (value && value.length === 2 && value.charAt(0) === '0' && value.charAt(1) !== '.') {
this.setParentModeVal(value.charAt(1))
return
}
let max = this.max ? this.max : 10000000
if (Number(value) > Number(max)) {
this.$message.warning('输入值不能超过 ' + max)
value = max + ''
}
// console.log(`11:` + value)
}
this.setParentModeVal(value)
// this.$refs.input3
// 子组件==>父组件 发消息
// let val = this.$el.value
// let len = val.length
// console.log(val)
// 解决数字键盘可以输入输入多个小数点问题
// if (Math.abs(this.value) > 0 && val === '' && value === '') {
// if (this.keyDownDel) {
// this.$el.value = ''// 正常删除
// console.log('---正常删除---' + this.value)
// } else {
// this.$el.value = this.value// 多次输入小数点时
// console.log('---多次输入小数点---' + this.value)
// }
// this.setParentModeVal(this.$el.value)
// return
// }
// 解决开始就输入点问题
// if (this.value === '' && val === '' && value === '') {
// console.log('---22aa---' + this.value)
// this.$el.value = ''
// this.setParentModeVal('')
// return
// }
// 解决保留两位小数问题
// if (val) {
// let pointIndex = val.indexOf('.')
// if (this.point == 0 && len == 2 && val.charAt(pointIndex) == '.') {
// console.log('只能输入整数')
// this.$el.value = val.substr(0, pointIndex)
// this.setParentModeVal(this.$el.value)
// return
// }
// if (pointIndex > 0 && (len - pointIndex) > (this.point + 1)) {
// console.log('只能输入' + this.point + '位小数')
// this.$el.value = val.substr(0, pointIndex + this.point + 1)
// this.setParentModeVal(this.$el.value)
// return
// }
// }
// 解决输入最大值问题
// if (this.max > 0 && val > this.max) {
// console.log('---4---')
// this.$el.value = val.substr(0, len - 1)
// this.setParentModeVal(this.$el.value)
// return
// }
return
}
},
buttonLoadingModel: {
get: function () {
// 父组件==>子组件 发消息
return this.buttonLoading
},
set: function (value) {
this.$emit('update:buttonLoading', value)
}
},
isMobileValidate () {
const phoneReg = /^1[3|4|5|6|7|8|9][0-9]{9}$/
return !(this.mobile && this.mobile.length === 11 && phoneReg.test(this.mobile))
}
},
watch: {
inputModel (val) {
if (val && val.length > 0 && this.type === 'qrCode') {
this.qrCodeText = '扫描成功'
this.emitReadCard()
} else {
this.qrCodeText = '扫描二维码中……'
}
}
},
created () {
},
mounted () {
if (this.type === 'qrCode') {
this.$refs.qrCodeInput.focus()
}
// 判断键盘是否是删除动作
var that = this
window.document.onkeydown = function (event) {
let e = event || window.event
if (e.keyCode === 8 || e.keyCode === 46) {
that.keyDownDel = true
} else {
that.keyDownDel = false
}
}
},
methods: {
setParentModeVal (value) {
this.$emit('input', value)
},
checkValue (value) {
if (!this.readOnly) {
value = value !== null ? value + '' : value
if (value !== null && value.lastIndexOf('.') !== -1 && value.lastIndexOf('.') === value.length - 1) {
this.setParentModeVal(value.substr(0, value.lastIndexOf('.')))
}
if (this.rangeType === 0 || (this.rangeType === 1 && value !== null)) {
if (this.min !== null && (Number(value) < Number(this.min) || value === '')) {
if (Number(value) < Number(this.min)) {
this.$message.warning('输入值不能低于 ' + this.min)
}
this.setParentModeVal(this.min + '')
}
if (value !== '' && this.max !== null && (Number(value) > Number(this.max) || value === '')) {
if (Number(value) < Number(this.min)) {
this.$message.warning('输入值不能高于 ' + this.max)
}
this.setParentModeVal(this.max + '')
}
}
}
},
SpecalcheckValue (value) {
// console.log(value);
if (value) {
// console.log(value);
let params = {
cardCode: value
}
isUsableCards(params).then(res => {
console.log(res);
}).catch(err => {
console.log(err);
})
}
},
checkValueClear (value) {
if (this.min !== null) {
this.$message.warning('输入值不能低于 ' + this.min)
this.setParentModeVal(this.min + '')
}
this.$emit('clear')
},
readIdCard () {
this.buttonLoadingModel = true
let that = this
setTimeout(() => {
that.buttonLoadingModel = false
}, 20000)
jsonp('http://localhost:8989/api/ReadMsg', {
waitTime: 3,
readOnce: 0
}, (err, res) => {
that.buttonLoadingModel = false
if (err) {
that.$message.error(err)
return false
}
if (res.code === '0') {
that.cardType = 7
that.inputModel = res.cardno
that.cardNo = res.cardNo
that.idCardName = res.name
that.emitReadCard()
} else {
that.$message.error(res.retmsg)
}
})
},
readCard () {
this.buttonLoadingModel = true
let that = this
setTimeout(() => {
that.buttonLoadingModel = false
}, 20000)
jsonp('http://localhost:38080/readcard/getNo', {}, (err, res) => {
that.buttonLoadingModel = false
if (err) {
this.$message.error(err)
return false
}
if (res.code === '0') {
that.cardType = 0
that.inputModel = res.cardNo
that.cardNo = res.cardNo
that.emitReadCard()
} else {
that.$message.error('一卡通读卡器' + res.message)
}
})
},
emitReadCard () {
if (this.cardType === 0) {
this.$emit('emitReadCard', this.cardNo)
} else if (this.cardType === 1) {
this.$emit('emitReadCard', {
cardType: this.cardType,
cardNo: this.cardNo
})
} else if (this.cardType === 7) {
this.$emit('emitReadCard', {
idCardName: this.idCardName,
cardNo: this.cardNo
})
}
},
emitQrCode () {
console.log(`qr: ${this.inputModel}`)
this.$emit('emitQrCode', this.inputModel)
},
amountchange (e) {
if (e) {
this.inputModel = e.target.value
}
this.$emit('change', this.inputModel)
},
sendVerificationCode () { // 发送验证码
if (this.buttonLoadingModel) {
return
}
this.buttonLoadingModel = true
let startSecond = 60
this.numCodeText = `${startSecond} s`
let buttonInterval = setInterval(() => { // 开启60秒倒计时
startSecond--
this.numCodeText = `${startSecond} s`
}, 1000)
setTimeout(() => { // 60秒后关闭倒计时
this.buttonLoadingModel = false
clearInterval(buttonInterval)
buttonInterval = null
this.numCodeText = '发送验证码'
}, startSecond * 1000)
this.$once('hook:beforeDestroy', () => { // 页面关闭后清除计时器
clearInterval(buttonInterval)
buttonInterval = null
})
sendVerificationCode({
mobile: this.mobile,
templateCode: this.templateType
}).then(res => {
if (res.code === 0) {
this.$message.success('验证码发送成功!')
console.log(this.buttonLoadingModel)
} else {
this.$message.error(res.message)
}
}).catch(error => {
console.log(error)
})
},
resetQrCode () {
this.$refs.qrCodeInput.focus()
this.qrFocuseFlag = true
this.qrCodeText = '扫描二维码中……'
this.setParentModeVal(null)
},
qrCodeInputBlur () {
if (this.inputModel === null || this.inputModel === '') {
this.qrFocuseFlag = false
this.qrCodeText = '未扫描到付款码信息'
}
},
// 处理外层弹窗输入框问题
handleNumberStringInput (val) {
let result = ''
result = val.replace(/[\W]/g, '')
this.setParentModeVal(result)
}
}
}
</script>
<style rel='stylesheet/scss' lang='scss' scoped>
.input-container {
width: 100%;
height: 100%;
display: inline-block;
.input-with-button {
width: 100%;
height: 100%;
display: flex;
display: -webkit-flex;
flex-direction: row;
.el-button {
// width: calc(100% - 65px);
margin-left: 9px;
&.el-button--small {
height: 32px;
}
}
}
.qrCode-area {
height: 36px;
position: relative;
&-div {
height: 36px;
line-height: 36px;
font-size: 13px;
color: #909399;
display: flex;
display: -webkit-flex;
flex-direction: row;
align-items: center;
justify-content: space-between;
span {
display: flex;
display: -webkit-flex;
flex-direction: row;
align-items: center;
i {
display: inline-block;
font-size: 20px;
margin-right: 8px;
}
}
}
.el-input--small {
position: absolute;
top: 0;
left: 0;
opacity: 0;
width: 50%;
}
}
}
</style>
2使用
<el-col
v-if="item.discountConfigId === 2"
:span="18"
class="flex-row-align"
>
<Einput
v-model="item.smallDiscountYear"
:size="'small'"
:type="'number'"
:max="item.bigDiscountYear"
:placeholder="'最小年限'"
:unit-string="'年'"
/>
<span class="middle-text">至</span>
<Einput
v-model="item.bigDiscountYear"
:size="'small'"
:type="'float'"
:min="item.smallDiscountYear"
:placeholder="'最大年限'"
:unit-string="'年'"
/>
</el-col>