前端定义的数据:
data() {
return {
dialogVisible: false,
modifiedContent: [],
contentContainer: null,
status: null,
divradioCont: null,
inputNode: null,
params:{},
// input 修改了
Cstatus:null,
// input 没有修改
Setstatus:null,
Conter:[],
// 判断是否选中
isShow:false
};
},
如图:后端返回的数据,前端需要动态渲染ruleContent中的字段,并把带有{}的渲染成input,可以修改里的值并反给后端。
dataFromBackend:[
{
id:1,
ruleContent:'每条投诉,一级主人扣分:{40分},二级主人扣分:{20}分',
roctot:'',
status:1,
targetRuleId:'1'
},
{
id:2,
ruleContent:'{90}%以上加{10}分',
roctot:'',
status:1,
targetRuleId:'1'
},
{
id:3,
ruleContent:'每个台区线损率{9.2}%以上超过3天扣{10}分',
roctot:'',
status:1,
targetRuleId:'1'
}
],
思路:
1.先创建一个容器,里面塞这是后端返回的数据。
2.遍历后端返回的列表,动态操作dom如后台数据有1条,那就有一条dom层。
3.使用正则把特殊的字符给匹配出来。
4.使用 while 循环,检测出一个字段中包含几个{},则创建几个input框作为回显。
5.最后绑定input事件,及单选框事件。
6.对事件及数据进行处理。
this.$nextTick(() => {
const regex = /\{(.*?)\}/g;
const nodes = [];
let match;
let lastIndex = 0;
this.contentContainer = document.getElementsByClassName('lis')[0]
this.contentContainer.innerHTML = ''
this.modifiedContent.forEach(str => {
this.$set(str, 'isId', null)
// 使用正则表达式查找特殊字符包裹的内容
let match;
let lastIndex = 0;
const nodes = [];
const divContert = document.createElement('div');
this.divradioCont = document.createElement('input');
this.divradioCont.type = 'radio';
this.divradioCont.name = 'rulecontent'; // 所有单选框需要同一个name属性
this.divradioCont.value = str.isId; // 可以将值设置为item的某个属性
this.divradioCont.id = str.id; // 为每个单选框设置唯一的id
divContert.classList.add('my-class');
this.divradioCont.classList.add('my-Yinput');
// 创建标签元素并与单选框关联
const label = document.createElement('label');
label.htmlFor = this.divradioCont.id; // 关联单选框和标签
label.textContent = '启用';
label.classList.add('labelCar');
this.contentContainer.appendChild(divContert)
divContert.appendChild(this.divradioCont)
divContert.appendChild(label)
if (this.modifiedContent.length === 1) {
this.divradioCont.checked = true; // 如果只有一条数据,默认选中
this.divradioCont.value = 1
this.status = 1
}
// 当找到特殊字符包裹的内容时
while ((match = regex.exec(str.ruleContent)) !== null) {
// 创建一个文本节点,用于显示特殊字符之前的文本
const textNode = document.createTextNode(str.ruleContent.slice(lastIndex, match
.index));
nodes.push(textNode);
// 创建一个 input 文本框,用于编辑特殊字符包裹的内容
this.inputNode = document.createElement('input');
this.inputNode.classList.add('my-input');
this.inputNode.type = 'text';
this.inputNode.setAttribute('targetRuleId',str.targetRuleId);
this.inputNode.style.width = '60px';
this.inputNode.style.height = '30px';
this.inputNode.id = str.id;
this.inputNode.name = 'ruleScore';
this.inputNode.value = match[1]; // 设置 input 的初始值为特殊字符包裹的内容
// this.inputNode.dataset.originalValue = match[1];
this.inputNode.setAttribute('originalValue',match[1]);
nodes.push(this.inputNode);
// 更新 lastIndex,以便下一次循环可以处理下一个文本片段
lastIndex = regex.lastIndex;
}
// 如果字符串末尾还有文本,则创建一个文本节点
if (lastIndex < str.ruleContent.length) {
const textNode = document.createTextNode(str.ruleContent.slice(lastIndex));
nodes.push(textNode);
}
// 将所有节点添加到内容容器中
const fragment = document.createDocumentFragment();
nodes.forEach(node => fragment.appendChild(node));
divContert.appendChild(fragment);
let that = this
})
let that = this
// 为每个 input 添加 change 事件监听器
const inputs = this.contentContainer.getElementsByClassName('my-input');
const radios = this.contentContainer.getElementsByClassName('my-Yinput');
for (let i = 0; i < inputs.length; i++) {
for (let k = 0; k < radios.length; k++) {
inputs[i].addEventListener('change', function() {
if (radios[k].id == inputs[i].id) {
// 当input改变默认选中
radios[k].checked = true
// 双向绑定
inputs[i].value = this.value
// 获取前端input的id
that.Cstatus = inputs[i].id
// 当input修改了这个为空
that.Setstatus = null
// 不管(input改变还是不改变)如何操作都为1
that.status = 1
// 判断是否改变
that.isShow = true
}
})
radios[k].addEventListener('change', function() {
// 当按钮改变时状态改变
radios[k].checked = true
// 当按钮改变时value 为 1
radios[k].value = 1
// 当切换按钮恢复默认状态
inputs[i].value = inputs[i].getAttribute('originalValue')
// 没有修改的状态
that.Setstatus = radios[k].id
// 按钮切换恢复默认值
that.Cstatus = null
// 不管(按钮改变还是不改变)如何操作都为1
that.status = 1
// 判断是否改变
that.isShow = true
})
}
}
})
对数据处理完后,提交给后端。
if(this.isShow) {
const inputs = this.contentContainer.getElementsByClassName('my-input');
const radios = this.contentContainer.getElementsByClassName('my-Yinput');
for (let i = 0; i < inputs.length; i++) {
for (let k = 0; k < radios.length; k++) {
if(this.Setstatus == radios[k].id) {
if(this.Setstatus == inputs[i].id) {
let ruleScore = inputs[i].value
this.Conter.push(ruleScore)
const uniqueArray = [...new Set(this.Conter)];
const nameValue = uniqueArray.join(',');
this.params = {
id:this.Setstatus,
targetRuleId:inputs[i].getAttribute('targetruleid'),
status:this.status,
ruleScore:nameValue
}
console.log('我没有修改',inputs[i].value)
console.log('我没有修改radios',radios[k])
}
} else {
if(this.Cstatus == inputs[i].id) {
let ruleScore = inputs[i].value
this.Conter.push(ruleScore)
const uniqueArray = [...new Set(this.Conter)];
const nameValue = uniqueArray.join(',');
this.params = {
id:this.Cstatus,
targetRuleId:inputs[i].getAttribute('targetruleid'),
status:this.status,
ruleScore:nameValue
}
}
}
}
}
let page = []
page.push(this.params)
console.log('page',page)
this.dialogVisible = false
this.status = null
this.Cstatus = null
this.Setstatus = null
this.Conter = []
this.params = {}
this.contentContainer.innerHTML = ''
this.inputNode.innerHTML = ''
this.divradioCont.innerHTML = ''
} else {
console.log('page',this.params)
this.dialogVisible = false
}