求教 html 字符串替换 关键词 为 组件 怎样能得到 Jsx ?

2022-07-12 16:44:01 +08:00
 lqzhgood

我有一个 字符串 如下

// html 结构不确定,下面只是举个例子
const html = "
	<div>
            xxx
            <span>123</span>
            <p>
                xxx
                <span>456</span>
                xxx
            </p>
            xxx
        </div>";

我想替换其中的

<span>/\d+/</span>

为组件

<el-link href={k}>{k}</el-link>

得到最终的 Jsx

const Jsx = <div>
            	xxx
                <el-link href={123}>{123}</el-link>
                <p>
                    xxx
                    <el-link href={456}>{456}</el-link>
                    xxx
                </p>
                xxx
            </div>;

综合来看,就是求下面的 handle 函数 求教 谢谢。
也可能我的思路过于曲折,如果有更好的 A->Z 的方法也希望不吝赐教。

<template>
	<component :is="r()"></component>
</template>

export default {
	data: () => ({
    	html,
    }),
    methods:{
    	handle(){
        	...  求解
        },
     	r(){
            const jsx = this.handle(this.html);
            return {
                functional: true,
                render(h){
                    return jsx
                },
            };
        }
    }
}
 
1372 次点击
所在节点    Vue.js
13 条回复
GreatAuk
2022-07-12 16:56:52 +08:00
正则替换不行吗
duan602728596
2022-07-12 16:58:03 +08:00
reter
2022-07-12 17:00:12 +08:00
我的方法:将字符串解析成可处理的 HTML 对象, 找到标签 span, 检查内容是否符合条件,然后替换标签。替换结束,再序列化成字符串。

比如用 DOMParser 解析: https://developer.mozilla.org/en-US/docs/Web/API/DOMParser
lqzhgood
2022-07-12 17:10:51 +08:00
@GreatAuk 整体替换后是字符串,只能当成 html 处理,无法渲染 vue 子组件。
lqzhgood
2022-07-12 17:11:54 +08:00
@reter 你这是纯 DOM 的处理方式,关键是要替换为 vue 组件
dudubaba
2022-07-12 17:33:46 +08:00
用 createElement 写 jsx
lqzhgood
2022-07-12 17:45:39 +08:00
@dudubaba html 内容不确定啊,写一个 html 解析函数的工作量不就等于重写 jsx 的实现 么……
lqzhgood
2022-07-12 18:29:25 +08:00
蹲坑回来就有思路了~

html 和 自定义组件的 字符串混合解析不就是 vue template 所做的事么~
所以只要无脑拼接字符串,然后使用 Runtime + Compiler 的 vue 版本, 丢到 template 里面去拿到返回的 vue 组件即可。虽然丢失了一点点性能,但是方便太多了。



```
<template>
<component :is="r()"></component>
</template>

export default {
data: () => ({
html,
}),
methods:{
handle(html){
return html.replaceAll(/\d+/, k=>`<el-link href='${k}'>${k}</el-link>`)
},
r(){
const html= this.handle(this.html);
return {
template: html
};
}
}
}
```
musi
2022-07-13 09:12:55 +08:00
好家伙,用带 compiler 版本的 vue ,你要不看看 vue 的 h 函数?
lqzhgood
2022-07-13 14:37:09 +08:00
@musi 你要不先看看 标题 ?
musi
2022-07-13 14:53:03 +08:00
@lqzhgood 标题和你最后给的答案都不对,你最后答案只是想用 component 渲染出来,r 函数都传过去了你不用,你这明显是为了得到 c ,走了弯路 b ,放着捷径 a 不走
lqzhgood
2022-07-13 15:00:33 +08:00
> 也可能我的思路过于曲折,如果有更好的 A->Z 的方法也希望不吝赐教。
表明只要达到目的即可,中间的路径 A -> Z 越优越好~
templete 是我想到最优路径,所以这是我的答案。

----------------------------------------------------

用 h 函数写出来 100 话费送上

talk is easy, show me the code

提醒一下 html 内容不定
lqzhgood
2022-07-13 15:44:51 +08:00

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/865709

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX