在讲述填空之前先思考如何修改后端返回的富文本呢,我们可以通过让后端将动态修改的部分进行变量的动态插值{ {xxx}},这样你将可以通过正则拿到/{ {(.*?)}}/g进行替换即可
const data = ref({
name: 'sun',
sex: '男',
age: '18'
})
// 例子(假设这是后端返回的富文本)
let html ='姓名:{
{name}},性别:{
{sex}},年龄{:{age}}等等......'
const newHtml = computed(() => {
return html.replace(/{
{(.*?)}}/g, (_, key) => `<span style="color: #2674EA;">${data.value[key.trim()]}</span>`)
})
// html 直接渲染
<div style="line-height: 1.5" v-html="newHtml"></div>
// 页面效果将是: 姓名:sun,性别:男,年龄:18等等......
值得注意的是我们虽然可以替换简单模板,但是不能替换相关组件,因为vue在渲染时只会当作字符串渲染,而v-html只会渲染并解析h5相关标签
// 会原样输出<el-input v-model="xxx" placeholder="请输入" />
const newHtml = computed(() => {
return html.replace(/{
{(.*?)}}/g, (_, key) => `<el-input v-model="${date.value[key.trim()]}" placeholder="请输入" />` )
})
因此我们可以通过component进行组件渲染
<template v-for="(item, index) in replacedHtml" :key="item.key">
<component :is="item.type" v-model="data[item.key]" />
<span v-if="item.type === 'text'" v-html="item.content"></span>
</template>
富文本替换部分
let arr = [
{ type: 'el-input', key: 'name' },
{ type: 'text', key: 'sex' },
{ type: 'text', key: 'age' },
]
function generateComponent(item) {
if (item.type === 'el-input') {
return {
type: 'el-input',
key: item.key,
value: data.value[item.key],
}
} else if (item.type === 'text') {
return {
type: 'text',
key: item.key,
content: data.value[item.key],
}
}
}
const replacedHtml = computed(() => {
const reg = /{
{(.*?)}}/g
const result = []
let match
let lastIndex = 0
let comIndex = 0
while ((match = reg.exec(html)) !== null) {
comIndex++
if (match.index > lastIndex) {
result.push({
type: 'text',
content: html.substring(lastIndex, match.index),
})
}
result.push(generateComponent(arr[comIndex - 1]))
lastIndex = match.index + match[0].length
}
if (lastIndex < html.length) {
result.push({
type: 'text',
content: html.substring(lastIndex),
})
}
return result
})
上述代码只是实现了将插值替换为对应文字或输入框并实现绑定,至于其他组件可以尝试通过component中的v-bind进行配置,对于复杂的来说还是前端数据写死处理相对简单
项目截图