这是刚看到的一个需求,大概意思就是从后台获取的数据是个字符串,字符串中会包含有{}这样的特殊字符,有几个也不确定,我们要把这个字符串动态渲染出来,没有{}的部分就正常展示文字即可,通过{}包含的要渲染成输入框且可编辑的,编辑完最终还要提交给后台(以相同的格式)
举个栗子:
现在有这么个字符串:'我叫{王大锤},今年{18岁}了',我们要将它渲染为
这样的,文本框可编辑,修改完之后假设是:
那么提交的时候就是获取到数据: '我叫{王阿牛},今年{16岁}了'。当然这只是个示例,大概意思是这样。
先说下思路吧,
1. 首先从后台获取到数据后,我们要正则去把{}中的内容匹配出来,可以拿到一个数组,以上面为例就是:['{王大锤}', '{18岁}']
2. 然后去遍历这个数组,每遍历的时候将原来的字符串中的{内容}通过replace方法替换成input标签,并将内容设置为input对应的value
3. 最后去渲染这个字符串的就可以了,如果是js的话就innerHTML就可以,如果用的vue的话也可以用v-html标签
提交的时候其实也是差不多的,我们拿到dom元素的innerHTML,也是个字符串,然后通过正则将<>内容匹配出来(就是input标签),然后遍历,拿到当前的value值,通过replace将原来的input标签 替换掉就可以了。
正则匹配:
var regex1 = /\((.+?)\)/g; //()小括号
var regex2 = /\[(.+?)\]/g; //[]中括号
var regex3 = /\{(.+?)\}/g; //{}花括号
const arr = str.match(regex3) // 将{}匹配出来
下面上完整代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div id="render-dynamic-str"></div>
<button id="submit">提交数据</button>
<script>
// 模拟请求
function getData() {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve({
success: true,
code: 0,
msg: '操作成功',
data: '订单号:{10110101010},交易商品:{001},初步估价:{2}元'
})
}, 500)
})
}
// 获取数据
getData().then(res => {
if(res.success) {
let str = JSON.parse(JSON.stringify(res.data))
const regex = /\{(.+?)\}/g // 匹配花括号
const braces = str.match(regex) // ['{10110101010}', '{001}', '{2}']
braces.forEach(brace => {
const curBraceData = brace.slice(1, -1)
str = str.replace(brace, `<input value="${curBraceData}" type="text">`)
})
document.getElementById('render-dynamic-str').innerHTML = str
}
})
document.getElementById('submit').addEventListener('click', doSubmit)
// 提交数据
function doSubmit() {
let domHtml = document.getElementById('render-dynamic-str').innerHTML
// 匹配尖括号
const regex = /\<(.+?)\>/g // 匹配尖括号
const angles = domHtml.match(regex) // ['<input value="10110101010" type="text">', '<input value="001" type="text">', '<input value="2" type="text">']
angles.forEach(angle => {
angle.split(' ').forEach(item => {
if(item.indexOf('value') >= 0) {
let curValue = item.split('value=')[1].slice(1, -1)
domHtml = domHtml.replace(angle, `{${curValue}}`)
}
})
})
console.log(domHtml, '提交的数据-->>')
}
</script>
</body>
</html>
效果: