方法一:使用正则表达式校验(推荐)
1. 基础实现
<template>
<div>
<input
v-model="inputValue"
@input="validateChinese"
placeholder="只能输入汉字"
/>
<p v-if="error" style="color: red">{{ error }}</p>
</div>
</template>
<script>
export default {
data() {
return {
inputValue: '',
error: ''
}
},
methods: {
validateChinese() {
// 清除非汉字字符
this.inputValue = this.inputValue.replace(/[^\u4e00-\u9fa5]/g, '');
// 或者进行校验提示
const chineseRegex = /^[\u4e00-\u9fa5]+$/;
if (this.inputValue && !chineseRegex.test(this.inputValue)) {
this.error = '只能输入汉字';
} else {
this.error = '';
}
}
}
}
</script>
2. 使用自定义指令(更优雅)
<template>
<div>
<input v-model="text" v-chinese-only />
</div>
</template>
<script>
export default {
data() {
return {
text: ''
}
},
directives: {
'chinese-only': {
inserted(el) {
el.addEventListener('input', (e) => {
const value = e.target.value;
e.target.value = value.replace(/[^\u4e00-\u9fa5]/g, '');
// 触发input事件让v-model更新
e.target.dispatchEvent(new Event('input'));
});
}
}
}
}
</script>
方法二:使用修饰符
自定义修饰符
// 在main.js或单独的文件中
Vue.directive('chinese', {
bind(el, binding, vnode) {
const handler = (e) => {
const value = e.target.value;
const newValue = value.replace(/[^\u4e00-\u9fa5]/g, '');
if (value !== newValue) {
e.target.value = newValue;
vnode.elm.dispatchEvent(new Event('input'));
}
};
el.addEventListener('input', handler);
el._inputHandler = handler;
},
unbind(el) {
el.removeEventListener('input', el._inputHandler);
}
});
// 在组件中使用
<input v-model="text" v-chinese />
方法三:使用计算属性
<template>
<div>
<input
:value="chineseText"
@input="updateText($event.target.value)"
/>
</div>
</template>
<script>
export default {
data() {
return {
text: ''
}
},
computed: {
chineseText: {
get() {
return this.text;
},
set(value) {
// 过滤非汉字字符
this.text = value.replace(/[^\u4e00-\u9fa5]/g, '');
}
}
},
methods: {
updateText(value) {
this.chineseText = value;
}
}
}
</script>
方法四:表单验证(使用vee-validate或element-ui等UI库)
使用Element UI
<template>
<el-form :model="form" :rules="rules">
<el-form-item label="姓名" prop="name">
<el-input
v-model="form.name"
placeholder="请输入汉字"
></el-input>
</el-form-item>
</el-form>
</template>
<script>
export default {
data() {
const validateChinese = (rule, value, callback) => {
if (!value) {
callback(new Error('不能为空'));
} else if (!/^[\u4e00-\u9fa5]+$/.test(value)) {
callback(new Error('只能输入汉字'));
} else {
callback();
}
};
return {
form: {
name: ''
},
rules: {
name: [
{ required: true, message: '请输入姓名', trigger: 'blur' },
{ validator: validateChinese, trigger: 'blur' }
]
}
}
}
}
</script>
方法五:支持空格的汉字输入
如果需要允许汉字之间的空格:
// 允许汉字和全角空格
const chineseWithSpaceRegex = /^[\u4e00-\u9fa5\u3000]+$/;
// 允许汉字和普通空格
const chineseWithNormalSpaceRegex = /^[\u4e00-\u9fa5\s]+$/;
完整示例组件
<template>
<div class="chinese-input-demo">
<h3>汉字输入框示例</h3>
<!-- 方法1:实时过滤 -->
<div class="input-group">
<label>实时过滤(推荐):</label>
<input
v-model="realTimeValue"
@input="filterChinese"
placeholder="输入时自动过滤非汉字"
/>
</div>
<!-- 方法2:失焦校验 -->
<div class="input-group">
<label>失焦校验:</label>
<input
v-model="blurValue"
@blur="validateOnBlur"
placeholder="失焦时校验"
/>
<span v-if="blurError" class="error">{{ blurError }}</span>
</div>
</div>
</template>
<script>
export default {
data() {
return {
realTimeValue: '',
blurValue: '',
blurError: ''
}
},
methods: {
filterChinese() {
this.realTimeValue = this.realTimeValue.replace(/[^\u4e00-\u9fa5]/g, '');
},
validateOnBlur() {
const chineseRegex = /^[\u4e00-\u9fa5]+$/;
if (this.blurValue && !chineseRegex.test(this.blurValue)) {
this.blurError = '请输入纯汉字';
} else {
this.blurError = '';
}
}
}
}
</script>
<style scoped>
.chinese-input-demo {
padding: 20px;
}
.input-group {
margin: 15px 0;
}
label {
display: inline-block;
width: 150px;
}
input {
padding: 8px;
width: 200px;
border: 1px solid #ddd;
border-radius: 4px;
}
.error {
color: red;
margin-left: 10px;
}
</style>
注意事项
Unicode范围:\u4e00-\u9fa5 涵盖了基本汉字,但不包括:
如果需要更全面的汉字支持:
// 包括基本汉字和扩展A区
const chineseRegex = /^[\u4e00-\u9fa5\u3400-\u4DBF]+$/;
// 包括基本汉字、扩展A、B区
const fullChineseRegex = /^[\u4e00-\u9fa5\u3400-\u4DBF\u{20000}-\u{2A6DF}\u{2A700}-\u{2B73F}\u{2B740}-\u{2B81F}\u{2B820}-\u{2CEAF}\u{2CEB0}-\u{2EBEF}]+$/u;
3. **性能考虑**:对于实时过滤,建议使用防抖处理频繁的输入事件。
选择哪种方法取决于具体需求:
- 实时过滤:用户体验好,但可能不符合某些表单验证场景
- 失焦验证:更符合传统表单验证逻辑
- 自定义指令:适合在多个地方复用
- UI库集成:适合大型项目,统一验证逻辑