当前位置: 首页 > news >正文

vue ElementUI textarea在光标位置插入指定变量及校验

需求

项目需求:TTS功能(文本转语音),需要在文本中添加变量,也就是一个固定模版,通过不同变量完成来改变模版内容,例如:【你好,{姓名}】(这里的{姓名}在传往后端时会转为{name}) ===》【你好,李伟】或【你好,孟浩然】等等。(项目是vue2项目ElementUI)。
要求:大括号不能嵌套,大括号数量不能超过5对。

效果

在这里插入图片描述

代码

HTML模块

<template><el-form ref="form":model="form":rules="rules"label-width="55px"v-loading="loading">...<el-form-item label="内容"prop="contextStr"><el-input v-model.trim="form.contextStr"type="textarea"ref="textarea"show-word-limitmaxlength="150":autosize="{ minRows: 4, maxRows: 6}"@blur="blurEvent"></el-input><div class="tab-box"><el-tag v-for="item in customKeyList":key="item.name"color="#6a7aee"size="small"style="cursor: pointer; border-color: #6a7aee; color: #fff;"@click="onClickTab(item)">{{ item.id }}</el-tag></div></el-form-item>...<el-form-item><el-button size="small"type="primary"@click="onSubmit">确 认</el-button></el-form-item></el-form>
</template>

JS模块

export default {data() {return {...customKeyList: [{id: "名称", name: "name"},{id: "号码", name: "phone"},{id: "自定义字段1", name: "customize1"},{id: "自定义字段2", name: "customize2"},{id: "自定义字段3", name: "customize3"},{id: "自定义字段4", name: "customize4"},],form: {...context: '', // 内容contextStr: '', // 内容...},rules: {...contextStr: [{ required: true, message: '请输入内容', trigger: 'blur' },{ min: 1, max: 150, message: '长度在1到150个字符', trigger: 'blur' }]...}...}},methods:{// 获取光标所在位置的indexblurEvent(e) {this.blurIndex = e.srcElement.selectionStart // 光标所在的位置},onClickTab(obj) {if (this.form.contextStr.length >= 150) {this.$message.error('内容长度不能超过 150 个字符')return}const message = this.isCorrectBracket(this.form.contextStr) // 判断括号是否正确if (message) {this.$message.error(message)return}const right = this.form.contextStr.slice(0, this.blurIndex).lastIndexOf('}' )const left = this.form.contextStr.slice(0, this.blurIndex).lastIndexOf('{')if (left >= 0 && right >= 0) { // 两个都存在if (left > right) {this.$message.error('当前光标聚焦的位置不对,或‘{}’不对称!')return}} else if (left >= 0 || right >= 0) { // 有一个不存在this.$message.error('当前光标聚焦的位置不对,或‘{}’不对称!')return}this.form.contextStr = this.form.contextStr.slice(0, this.blurIndex) + '{' + obj.id + '}' + this.form.contextStr.slice(this.blurIndex)this.blurIndex = this.blurIndex + obj.id.length + 2this.$refs.form.validateField('contextStr')},isCorrectBracket(str, bool) { // 判断括号是否正确 括号不可嵌套且需成对出现 参数bool位 true校验是否正确 false或null判断是否可添加let errorMsg = ''const BracketsDic = {'{': '}'}let leftBracket = nulllet leftBracketIndex = nulllet index = 1let countL = 0 // 左大括号数量let countR = 0 // 右大括号数量for (const char of str) {// 是否左括号if (char === '{') {countL++ // 记录存在多少个右括号// 是否已有左括号if (leftBracket) {errorMsg = `因括号不可嵌套,第${leftBracketIndex}个字符 ${leftBracket} 在匹配右括号前,不能出现第${index}个字符 ${char} `break} else {leftBracket = charleftBracketIndex = index}} else {// 是否右括号if (char === '}') {countR++// 是否已有左括号if (leftBracket) {// 是否匹配左括号if (BracketsDic[leftBracket] === char) {leftBracket = nullleftBracketIndex = null} else {errorMsg = `${leftBracketIndex}个字符 ${leftBracket} 与第${index}个字符 ${char} 不匹配`break}} else {errorMsg = `${index}个字符 ${char} 前缺少左括号`break}}}index++}if (!errorMsg) {if (leftBracket) {errorMsg = `${leftBracketIndex}个字符 ${leftBracket} 后缺少右括号`}}if ((countL === countR)) {if (bool) {if (countL > 10) {errorMsg = `最多只能存在10对大括号,当前大括号数量${countL}`}} else {if (countL >= 10) {errorMsg = `最多只能存在10对大括号,当前大括号数量${countL}`}}}return errorMsg},setContext() { // 设置contextStr对应的context字段this.form.context = this.form.contextStrthis.customKeyList.forEach(element => {this.form.context = this.form.context.replaceAll('{' + element.id + '}', '{' + element.name + '}')})},onSubmit() {const message = this.isCorrectBracket(this.form.context_str, true)if (message) {this.$message.error(message)return} else {this.setContext() // 设置contextStr}this.$refs.form.validate((valid) => {....})}}
}

CSS模版

.el-tag {margin-right: 10px;user-select: none;
}

文章转载自:

http://T8K1cYbH.xqzrg.cn
http://xjBUIPHA.xqzrg.cn
http://3Q2QgDIy.xqzrg.cn
http://HpgVzgqE.xqzrg.cn
http://kOhlh7hu.xqzrg.cn
http://0ZfoUSwX.xqzrg.cn
http://WArxe7rJ.xqzrg.cn
http://L9MUSJYS.xqzrg.cn
http://H1lfHKb3.xqzrg.cn
http://PYLI3uCM.xqzrg.cn
http://LkfdGD3A.xqzrg.cn
http://HKeJ9cbX.xqzrg.cn
http://vhWxojuM.xqzrg.cn
http://dDMvdb8s.xqzrg.cn
http://W1KFdIoh.xqzrg.cn
http://zHPv4MRT.xqzrg.cn
http://8JNQ6dSV.xqzrg.cn
http://262C4agJ.xqzrg.cn
http://QSztn8vW.xqzrg.cn
http://zVn8K9ai.xqzrg.cn
http://C85fUFo4.xqzrg.cn
http://VI9IeoMQ.xqzrg.cn
http://CEM2K9Et.xqzrg.cn
http://vMvxdsxY.xqzrg.cn
http://E18AFZTV.xqzrg.cn
http://xwyG4m2U.xqzrg.cn
http://HQk4bePV.xqzrg.cn
http://JMPLQglc.xqzrg.cn
http://exnk7jAT.xqzrg.cn
http://R3WIvkWl.xqzrg.cn
http://www.dtcms.com/a/384562.html

相关文章:

  • 边缘人工智能计算机
  • 亚远景侯亚文老师受邀出席PTC中国数字化转型精英汇,分享汽车研发破局“三擎”之道
  • K8S结合Istio深度实操
  • 【SQLMap】POST请求注入
  • 【C++实战⑪】解锁C++结构体:从基础到实战的进阶之旅
  • SAP-ABAP:SAP业务伙伴角色查询:BAPI_BUPA_ROLES_GET_2 详解与实践
  • 【openGLES】帧缓冲区对象frameBufferObject(FBO)
  • 端口转发神器Rinetd:轻量级安装与配置指南
  • Cursor+Claude编程+工作体会
  • [数据结构——lesson12.希尔排序]
  • Field II 超声成像仿真 1--得到Bmode图像
  • SpringBoot整合RustFS:全方位优化文件上传性能
  • 硬件(十一):EPIT、GPT、UART 外设配置
  • 趣味学RUST基础篇(OOP)
  • 微服务网关的bug
  • Rust 与 C/C++ 的特性对比
  • mac 安装hive
  • Nginx 从入门到进阶:反向代理、负载均衡与高性能实战指南
  • 微服务-nacos服务中心
  • uniApp开发XR-Frame微信小程序 | 动态加载与删除模型
  • AR 巡检在工业的应用|阿法龙XR云平台
  • eureka微服务注册问题
  • 【LangChain指南】大语言模型(LLMs)
  • 一台设备管理多个 GitHub 账号:从配置到切换的完整指南
  • K - 近邻(KNN)算法:基于约会数据集的分类任务全流程
  • 机器学习实战第四章 线性回归
  • 概率统计面试题2:随机抛掷两点到圆心距离较小值的期望
  • 什么是 OFDM?它如何解决频率选择性衰落?
  • 第一部分:VTK基础入门(第3章:VTK架构与核心概念)
  • 基于深度学习的中文方言识别模型训练实战