vue3 自定义输入框字符的占位符

需求说明:两个系统不同数据库数据交互时,由于数据库存储字节长度不同导致定义字节长度参差不齐,后端无法修改,所以重任落到了前端头上从源头上限制传给后端的字符长度,普通后端定义长度为 1 字符前端限制字符长度为 1 就行,现在需要改成 数字英文占一个字符,中文占两个字符其他占四个字符。

首先在 main.js 写入

// 输入框千分位符处理
var desc = Object.getOwnPropertyDescriptor(HTMLInputElement.prototype, 'value')
Object.defineProperty(HTMLInputElement.prototype, 'value', {
    ...desc,
    set(v) {
		if (this.getAttribute('data-maxCharShow') === 'true') {
			let maxCharlength = Number(this.getAttribute('data-maxCharlength')) || 0
			let span = this.parentNode.parentNode.nextElementSibling
			let b = 0 // 输入的字符数
			for (var i = 0, length = v.length; i < length; i++) {
				var c = v.charAt(i);
				if (/^[`!¥……()——\{}|《》?:“”【】、;‘',。、\s+]$/.test(c)) {
					b += 4;
				} else if (/^[\u4e00-\u9fa5]$/.test(c)) {
					b += 2;
				} else {
					b++;
				}
				
				if (b > maxCharlength) {
					if (/^[`!¥……()——\{}|《》?:“”【】、;‘',。、\s+]$/.test(c)) {
						b-=4
					} else if (/^[\u4e00-\u9fa5]$/.test(c)){
						b -= 2;
					} else {
						b--;
					}
					break
				}
			}
			span.innerText = b + ' / ' + maxCharlength
		}
		desc.set.call(this, v)
    }
})

 输入框加上特殊属性 data-maxCharShow="true"  data-maxCharlength="10"

 data-maxCharShow: 是否触发字符长度重新计算

data-maxCharlength:可输入字符最大长度

<el-input v-model="ruleForm.name" placeholder="请填写企业名称" v-maxlength data-maxCharShow="true" data-maxCharlength="10" maxlength="10" class="inputDesc"></el-input>

添加自定义指令,监听是否获取焦点转换字符长度,由于@change和@input都无法再输入框被赋值时触发所以需要 Object.getOwnPropertyDescriptor()和Object.defineProperty() 方法

// 根据字节判断长度
app.directive('maxlength', {
	beforeMount(el, binding, vnode) {
		let input = el.children[0].children[0]
		input.addEventListener('focus', function(ev) {
			// 修改是否转换属性为false
			input.setAttribute('data-maxCharShow', 'false')
		})
		// 非直接输入开始
		input.addEventListener('compositionstart', function(ev) {
			input.setAttribute('data-open', 'false')
		})
		// 非直接输入结束
		input.addEventListener('compositionend', function(ev) {
			input.setAttribute('data-open', 'true')
			var target = input;
			let e = target.value
			var maxCharlength = target.getAttribute("data-maxCharlength")
			var num = Number(target.getAttribute("data-maxCharlength"))
			let b = 0 // 输入的字符数
			for (var i = 0, length = e.length; i < length; i++) {
				var c = e.charAt(i);
				if (/^[`!¥……()——\{}|《》?:“”【】、;‘',。、\s+]$/.test(c)) {
					b += 4;
					num -= 2
				} else {
					if (/^[\u4e00-\u9fa5]$/.test(c)) {
						b += 2;
						num-=1
					} else {
						b++;
					}
				}
				
				if (b > maxCharlength) {
					if (/^[`!¥……()——\{}|《》?:“”【】、;‘',。、\s+]$/.test(c)) {
						b -= 4;
						num+=2
					} else {
						if (/^[\u4e00-\u9fa5]$/.test(c)) {
							b -= 2;
							num+=1
						} else {
							b--;
						}
					}
					break
				}
			}
			target.value=e
			target.setAttribute("maxlength", num)
			if (target.tagName.toLowerCase() == 'input') {
				let span = target.parentNode.parentNode.nextElementSibling
				span.innerText = b + ' / ' + maxCharlength
			}
		})
		input.addEventListener('input', function(ev) {
			if (input.getAttribute('data-open')==='false') return
			var target = input;
			let e = target.value
			// 获取总长度判断回显
			var maxCharlength = target.getAttribute("data-maxCharlength")
			// 获取总长度 改变 maxlength 属性 用原生控制不可输入
			var num = Number(target.getAttribute("data-maxCharlength"))
			let b = 0 // 输入的字符数
			for (var i = 0, length = e.length; i < length; i++) {
				var c = e.charAt(i);
				if (/^[`!¥……()——\{}|《》?:“”【】、;‘',。、\s+]$/.test(c)) {
					b += 4;
					num-=2
				} else {
					if (/^[\u4e00-\u9fa5]$/.test(c)) {
						b += 2;
						num-=1
					} else {
						b++;
					}
				}
				
				if (b > maxCharlength) {
					if (/^[`!¥……()——\{}|《》?:“”【】、;‘',。、\s+]$/.test(c)) {
						b -= 4;
						num+=2
					} else {
						if (/^[\u4e00-\u9fa5]$/.test(c)) {
							b -= 2;
							num+=1
						} else {
							b--;
						}
					}
					break
				}
			}
			target.value=e
			target.setAttribute("maxlength", num)
			if (target.tagName.toLowerCase() == 'input') {
				let span = target.parentNode.parentNode.nextElementSibling
				span.innerText = b + ' / ' + maxCharlength
			}
		})
		input.addEventListener('blur', function(ev) {
			// 修改是否转换属性为false
			input.setAttribute('data-maxCharShow', 'true')
		})
	}
})

最后代码如下

<el-input v-model="ruleForm.name" placeholder="请填写企业名称" v-maxlength data-maxCharShow="true" data-maxCharlength="10" maxlength="10" class="inputDesc"></el-input>
<span class="input-count">0 / 10</span>

 span 里面数字会跟着输入的字符也一起变化。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值