最近再在做项目的过程中,产品在设计的输入的时候两种不同的交互。且中文算两个字符,input在输入的时候中文是一个字符,故maxlength属性不起作用,请看下面代码
效果图
vue+elementUI+ @keyup.native="limitStrLength"
场景一
<!-- -->
<template>
<div class="form-page">
<div class="form-box">
<el-form
:model="ruleForm"
:rules="rules"
ref="ruleForm"
label-width="100px"
class="demo-ruleForm"
>
<div class="tips">
两种交互方式,1超出8个字符限制输入,2输入超出8个字符提示错误;注意中文算两个字符
</div>
<el-form-item label="活动名称一" prop="name1">
<el-input
v-model="ruleForm.name1"
placeholder="最多输入4个中文"
></el-input>
</el-form-item>
<el-form-item label="活动名称二" prop="name2">
<el-input
v-model="ruleForm.name2"
@keyup.native="(e) => limitStrLength(e, ruleForm.name2)"
placeholder="最多输入4个中文"
/>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="submitForm('ruleForm')"
>立即创建</el-button
>
<el-button @click="resetForm('ruleForm')">重置</el-button>
</el-form-item>
</el-form>
</div>
</div>
</template>
<script>
export default {
components: {},
data() {
var validateName1 = (rule, value, callback) => {
if (value === "") {
callback(new Error("请输入活动名称一"));
} else {
//获取输入的字符串长度
let valLength = this.getStrLength(value);
if (valLength > 8) {
callback(new Error("活动名称一不能超出8个字符"));
} else {
callback();
}
}
};
return {
ruleForm: {
name1: "",
name2: "wadwad",
},
rules: {
name1: [{ required: true, validator: validateName1, trigger: "blur" }],
name2: [
{ required: true, message: "请输入活动名称二", trigger: "blur" },
],
},
dynamicValidateForm: {
domains: [
{
value: "",
},
],
},
};
},
watch: {},
mounted() {},
methods: {
//获取字符创长度
getStrLength(str) {
let length = str.length;
let res = 0;
for (var i = 0; i < length; i++) {
if (str.charCodeAt(i) < 27 || str.charCodeAt(i) > 126) {
// 全角
res += 2;
} else {
res++;
}
}
return res;
},
limitStrLength(e, data) {
let input = e.target;
let split = input.value.split("");
// 计算已输入的长度
let map = split.map((s, i) =>
input.value.charCodeAt(i) >= 0 && input.value.charCodeAt(i) <= 128
? 1
: 2
);
//如果输入”我爱你520“ map = ['2','2','2','1','1','1']
// 这里设置想要限制的长度
let maxLength = 8;
let n = 0;
//获取输入的长度 charLength
let charLength =
map.length > 0 &&
map.reduce((accumulator, currentValue, index) => {
if (accumulator === maxLength || accumulator === maxLength - 1) {
n = index;
}
return accumulator + currentValue;
});
if (charLength > maxLength) {
input.value = split.slice(0, n).join("");
}
data = input.value; // data 传过来不是数据双向绑定
this.$set(this.ruleForm, "name2", data); // this.ruleForm.name2 = data;
},
submitForm(formName) {
this.$refs[formName].validate((valid) => {
if (valid) {
console.log("this.ruleForm.name2--------end", this.ruleForm.name2);
} else {
console.log("error submit!!");
return false;
}
});
},
resetForm(formName) {
this.$refs[formName].resetFields();
},
},
};
</script>
<style lang="scss" scoped>
.form-page {
width: 100%;
height: 100%;
display: flex;
align-items: center;
justify-content: center;
.form-box {
width: 800px;
height: 600px;
display: flex;
flex-wrap: wrap;
align-items: center;
justify-content: center;
.el-form {
width: 100%;
height: 100%;
}
}
.tips {
height: 60px;
line-height: 60px;
}
}
</style>
遇到的坑
在输入限制的时候,输出超出在输入框并没有显示,但是console.log(this.ruleForm.name2)你会发现字符超过了,eg:输入顺口溜123,在input框显示‘顺口溜12’,打印出来的数据‘顺口溜123’ 解决办法---重新赋值 this.ruleForm.name2 = input.value;
limitStrLength(e) {
let input = e.target;
let split = input.value.split("");
// 计算已输入的长度
let map = split.map((s, i) =>
input.value.charCodeAt(i) >= 0 && input.value.charCodeAt(i) <= 128 ? 1 : 2
);
//如果输入”我爱你520“ map = ['2','2','2','1','1','1']
// 这里设置想要限制的长度
let maxLength = 8;
let n = 0;
//获取输入的长度 charLength
let charLength = map.length > 0 && map.reduce((accumulator, currentValue, index) => {
if (accumulator === maxLength || accumulator === maxLength - 1) {
n = index;
}
return accumulator + currentValue;
});
if (charLength > maxLength) {
input.value = split.slice(0, n).join("");
}
this.ruleForm.name2 = input.value;
},
场景二,循坏
<!-- -->
<template>
<div class="form-page">
<div class="form-box">
<!-- 表单2 -->
<el-form
:model="dynamicValidateForm"
ref="dynamicValidateForm"
label-width="100px"
class="demo-dynamic"
>
<el-form-item
v-for="(domain, index) in dynamicValidateForm.domains"
:label="'名称' + index"
:key="domain.key"
:prop="'domains.' + index + '.value'"
:rules="{
required: true,
message: '名称不能为空',
trigger: 'blur',
}"
>
<el-input v-model="domain.value" @keyup.native="(e)=>limitStrLength(e,index)"></el-input
><el-button style="margin-left:10px" @click.prevent="removeDomain(domain)">删除</el-button>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="submitForm('dynamicValidateForm')"
>提交</el-button
>
<el-button @click="addDomain">新增名称</el-button>
<el-button @click="resetForm2('dynamicValidateForm')">重置</el-button>
</el-form-item>
</el-form>
</div>
</div>
</template>
<script>
export default {
components: {},
data() {
return {
dynamicValidateForm: {
domains: [
{
value: "",
},
],
},
};
},
watch: {},
mounted() {},
methods: {
//获取字符创长度
getStrLength(str) {
let length = str.length;
let res = 0;
for (var i = 0; i < length; i++) {
if (str.charCodeAt(i) < 27 || str.charCodeAt(i) > 126) {
// 全角
res += 2;
} else {
res++;
}
}
return res;
},
limitStrLength(e, index) {
let input = e.target;
let split = input.value.split("");
// 计算已输入的长度
let map = split.map((s, i) =>
input.value.charCodeAt(i) >= 0 && input.value.charCodeAt(i) <= 128
? 1
: 2
);
//如果输入”我爱你520“ map = ['2','2','2','1','1','1']
// 这里设置想要限制的长度
let maxLength = 8;
let n = 0;
//获取输入的长度 charLength
let charLength =
map.length > 0 &&
map.reduce((accumulator, currentValue, index) => {
if (accumulator === maxLength || accumulator === maxLength - 1) {
n = index;
}
return accumulator + currentValue;
});
if (charLength > maxLength) {
input.value = split.slice(0, n).join("");
}
// let obj = this.dynamicValidateForm.domains.find((item,index1) => index1 == index );
// obj.value = input.value;
this.$set(this.dynamicValidateForm.domains[index],'value',input.value)
console.log("this.dynamicValidateForm.domains[index]--end",this.dynamicValidateForm.domains[index])
},
submitForm(formName) {
this.$refs[formName].validate((valid) => {
if (valid) {
alert("submit!");
} else {
console.log("error submit!!");
return false;
}
});
},
resetForm2(formName) {
this.$refs[formName].resetFields();
},
removeDomain(item) {
var index = this.dynamicValidateForm.domains.indexOf(item);
if (index !== -1) {
this.dynamicValidateForm.domains.splice(index, 1);
}
},
addDomain() {
this.dynamicValidateForm.domains.push({
value: "",
key: Date.now(),
});
},
},
};
</script>
<style lang="scss">
.el-form-item__content {
display: flex !important;
}
</style>
数据双向未绑定
数据双向绑定
// let obj = this.dynamicValidateForm.domains.find((item,index1) => index1 == index );
// obj.value = input.value;
this.$set(this.dynamicValidateForm.domains[index],'value',input.value)
console.log("this.dynamicValidateForm.domains[index]--end",this.dynamicValidateForm.domains[index])