
Snipaste_2026-02-28_16-13-59.jpg
script
const formData = ref{
content: '各分公司资产管理岗:\n 根据《通知》每月报送相关信息的要求,现将报送 {{数据期间}} 营业职场情况通知如下:\n 一、时间要求:请务必于 {{填报截止日期}} 前报送并核对完毕。过时将关闭系统,无法修改。\n 二、报送说明\n 1. 此次统计在财务数据服务中心进行,统计范围为当月租赁面积减少或有节省费用的职场,换租后租赁面积不变且未节省费用的无需填报。\n 2. 此表仅二级机构填报,仅填报当月新增,无需重复填报之前已填报内容。'
}
const myContent = document.querySelector('#myContent')
// 选择方法
const selectContent = (event) => {
if (timer) {
clearTimeout(timer)
timer = null
}
const selectionStart = event.target.selectionStart
const selectionEnd = event.target.selectionEnd
let text = formData.value.content
const regex = /\{{([^}]+)\}}/g
const matches = [...text.matchAll(regex)]
const results = matches.map(i => ({
content: i[0],
startIndex: i.index,
endIndex: i.index + i[0].length
}))
for (let i of results) {
if (selectionStart === selectionEnd) {
if (selectionStart >= i.startIndex && selectionEnd <= i.endIndex) {
// 当光标处于变量词组内部,选中整个词组
timer = setTimeout(() => {
myContent.setSelectionRange(i.startIndex, i.endIndex)
}, 200)
}
} else if ((selectionStart >= i.startIndex && selectionStart <= i.endIndex) || (selectionEnd >= i.startIndex && selectionEnd <= i.endIndex)) {
// 当光标处于变量词组内部,选中整个词组
timer = setTimeout(() => {
myContent.setSelectionRange(i.startIndex, i.endIndex)
}, 200)
}
}
}
// 插入变量
const insertText = async (myValue) => {
if (myContent.selectionStart || myContent.selectionStart === 0) {
const startPos = myContent.selectionStart
const endPos = myContent.selectionEnd
formData.value.content = myContent.value.substring(0, startPos) + myValue + myContent.value.substring(endPos, myContent.value.length)
await nextTick() // 这里是重点
myContent.setSelectionRange(endPos + myValue.length, endPos + myValue.length)
} else {
formData.value.content += myValue
}
}
template
<a-textarea v-model:value="formData.content" id="myContent" autoSize @keyup="selectContent" @click="selectContent" />
<a-button @click="insertText(' {{数据期间}} ')">插入变量</a-button>