<template> <div class="input-unit" :id="maxlengthAppendId"> <InputNumber v-if="type === 'number'" :id="numberId" :placeholder="placeholder" :size="size" :precision="precision" v-model="CurrentVal" :disabled="disabled ? true : false" :active-change="false" @on-blur="blur" @on-focus="focus" ></InputNumber> <i-input v-else :placeholder="placeholder" :maxlength="maxlength" :show-word-limit="showWordLimit" :size="size" :type="type" :rows="rows" :autosize="autoSize" v-model="CurrentVal" :disabled="disabled ? true : false" :element-id="textareaId" @on-enter="enter" @on-blur="blur" @on-focus="focus" > <template v-if="append" #append> <span>{{ append }}</span> </template> <template v-if="prepend" #prepend> <span>{{ prepend }}</span> </template> </i-input> <div class="unit-text">{{unit}}</div> </div> </template> <script lang="ts"> import { Vue, Component, Prop, Model, Emit } from "vue-property-decorator"; import { Subject } from "rxjs"; import { debounceTime, distinctUntilChanged } from "rxjs/operators"; @Component({}) export default class InputBox extends Vue { /** * 双向绑定值 * @type {any} * @memberof InputBox */ @Model("change") readonly itemValue?: any; /** * 生命周期 (多行文本十行高度问题) * @type {any} * @memberof InputBox */ public created() { if(this.editorType && this.editorType == "TEXTAREA_10") { this.rows = 10; } if(this.minRows){ this.autoSize.minRows = this.minRows; } if(this.maxRows){ this.autoSize.maxRows = this.maxRows; } } /** * 生命周期 (多行文本十行高度问题) * @type {any} * @memberof InputBox */ public mounted(){ this.addEvent(); if(this.textareaId){ let textarea :any= document.getElementById(this.textareaId); if(textarea){ textarea.style=this.textareaStyle; } } if(this.showWordLimit && (this.append || this.prepend)){ this.setAppendStyle(); } } /** * 单位 * @type {String} * @memberof InputBoxUnit */ @Prop() public unit?: string; /** * 多行文本十行 特殊参数样式(模型高度自带) * @type {String} * @memberof InputBoxUnit */ @Prop() public textareaStyle?: string; /** * 多行文本十行 特殊参数id(模型高度自带) * @type {String} * @memberof InputBoxUnit */ @Prop() public textareaId?: string; /** * 大小 * @type {String} * @memberof InputBoxUnit */ @Prop() public size?: string; /** * 编辑器样式 * @type {String} * @memberof InputBoxUnit */ @Prop() public editorType?: string; /** * 文本行数 * @type {String} * @memberof InputBoxUnit */ public rows: number = 2; /** * placeholder值 * @type {String} * @memberof InputBox */ @Prop() public placeholder?: string; /** * 是否禁用 * @type {boolean} * @memberof InputBox */ @Prop() public disabled?: boolean; /** * 属性类型 * * @type {string} * @memberof InputBox */ @Prop() public type?: string; /** * 精度 * * @type {number} * @memberof InputBox */ @Prop({default: 0}) public precision?: number; /** * 输入内容最大长度 * * @type {string} * @memberof InputBox */ @Prop() public maxlength?: number; /** * 输入内容前缀 * * @type {string} * @memberof InputBox */ @Prop() public prepend?: any; /** * 输入内容后缀 * * @type {string} * @memberof InputBox */ @Prop() public append?: any; /** * 是否显示输入内容最大长度 * * @type {string} * @memberof InputBox */ @Prop() public showWordLimit?: boolean; /** * 多行文本类型下最小行数 * * @type {string} * @memberof InputBox */ @Prop() public minRows?: number; /** * 多行文本类型下最大行数 * * @type {string} * @memberof InputBox */ @Prop() public maxRows?: number; /** * 多行文本行数 * * @type {string} * @memberof InputBox */ public autoSize: any = {}; /** * 数值框numberId */ public numberId :string= this.$util.createUUID(); //当同时存在最长长度与后缀词时,input的id public maxlengthAppendId: string = this.$util.createUUID(); /** * 当前值 * * @memberof InputBox */ get CurrentVal() { if(Object.is(this.type, 'number') && this.itemValue && !isNaN(this.itemValue)){ return Number(Number(this.itemValue).toFixed(this.precision)); }else{ return this.itemValue; } } /** * 值变化 * * @memberof InputBox */ set CurrentVal(val: any) { let _data: any = val; if (Object.is(this.type, "number") && val && !isNaN(val)) { try { _data = isNaN(Number(val)) ? null : Number(val); } catch (error) {} } if (Object.is(_data, "")) { _data = null; } this.$emit("change", _data); } /** * 回车事件 * * @param {*} $event * @memberof InputBox */ @Emit() public enter($event: any) { if (!$event || $event.keyCode !== 13) { return; } return $event; } /** * 输入框失焦 * * @memberof InputBox */ public blur(){ this.$emit('blur',this.itemValue) } /** * 输入框聚焦 * * @memberof InputBox */ public focus(){ this.$emit('focus',this.itemValue) } /** * 给数值框中的箭头按钮添加事件 * * @memberof InputBox */ public addEvent(){ if(Object.is(this.type, "number")){ // 整个页面渲染完之后再去执行 this.$nextTick(() => { let inputNumber :any = document.getElementById(this.numberId); let handlerWrap :any = inputNumber.firstElementChild; handlerWrap.onmouseover=()=>{ inputNumber.style.paddingRight="15px"; inputNumber.style.transition="all 0.2s linear"; } handlerWrap.onmouseout=()=>{ inputNumber.style.paddingRight="0px"; } }); } } /** * 当同时设置了前缀(或后缀词)与显示最长长度时,动态重新设置样式,iview原本的样式有异常 * * @memberof InputBox */ public setAppendStyle() { if (Object.is(this.type, 'text') || Object.is(this.type, 'textarea')) { this.$nextTick(() => { let input: any = document.getElementById(this.maxlengthAppendId); if (input) { let appendEle = input.querySelector('.ivu-input-group-append'); let maxlengthEle = input.querySelector('.ivu-input-word-count'); let unitEle = input.querySelector('.unit-text'); let appendEleWidth = null; let maxlengthEleWidth = null; if (appendEle) { appendEleWidth = window.getComputedStyle(appendEle).getPropertyValue('width'); } if (maxlengthEle) { maxlengthEleWidth = window.getComputedStyle(maxlengthEle).getPropertyValue('width'); } const setEleStyle = (ele: any) => { ele.style.paddingRight = '5px'; ele.style.marginRight = '1px'; ele.style.zIndex = '10'; }; if (appendEleWidth && maxlengthEleWidth) { const width = Number(appendEleWidth.slice(0,-2)) + Number(maxlengthEleWidth.slice(0,-2)); maxlengthEle.style.right = appendEleWidth; unitEle.style.right = width + 'px'; } else if (appendEleWidth) { unitEle.style.right = appendEleWidth; } else if (maxlengthEleWidth) { maxlengthEle.style.right = maxlengthEleWidth; } setEleStyle(unitEle); setEleStyle(maxlengthEle); if (this.prepend) { maxlengthEle.style.zIndex = '10'; } } }); } } } </script> <style lang='less'> @import "./input-box.less"; </style>