V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
lqzhgood
V2EX  ›  Vue.js

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

  •  
  •   lqzhgood · 2022-07-12 16:44:01 +08:00 · 1351 次点击
    这是一个创建于 648 天前的主题,其中的信息可能已经有所发展或是发生改变。

    我有一个 字符串 如下

    // 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
                    },
                };
            }
        }
    }
     
    
    13 条回复    2022-07-13 15:44:51 +08:00
    GreatAuk
        1
    GreatAuk  
       2022-07-12 16:56:52 +08:00
    正则替换不行吗
    duan602728596
        2
    duan602728596  
       2022-07-12 16:58:03 +08:00
    reter
        3
    reter  
       2022-07-12 17:00:12 +08:00
    我的方法:将字符串解析成可处理的 HTML 对象, 找到标签 span, 检查内容是否符合条件,然后替换标签。替换结束,再序列化成字符串。

    比如用 DOMParser 解析: https://developer.mozilla.org/en-US/docs/Web/API/DOMParser
    lqzhgood
        4
    lqzhgood  
    OP
       2022-07-12 17:10:51 +08:00
    @GreatAuk 整体替换后是字符串,只能当成 html 处理,无法渲染 vue 子组件。
    lqzhgood
        5
    lqzhgood  
    OP
       2022-07-12 17:11:54 +08:00
    @reter 你这是纯 DOM 的处理方式,关键是要替换为 vue 组件
    dudubaba
        6
    dudubaba  
       2022-07-12 17:33:46 +08:00
    用 createElement 写 jsx
    lqzhgood
        7
    lqzhgood  
    OP
       2022-07-12 17:45:39 +08:00
    @dudubaba html 内容不确定啊,写一个 html 解析函数的工作量不就等于重写 jsx 的实现 么……
    lqzhgood
        8
    lqzhgood  
    OP
       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
        9
    musi  
       2022-07-13 09:12:55 +08:00
    好家伙,用带 compiler 版本的 vue ,你要不看看 vue 的 h 函数?
    lqzhgood
        10
    lqzhgood  
    OP
       2022-07-13 14:37:09 +08:00
    @musi 你要不先看看 标题 ?
    musi
        11
    musi  
       2022-07-13 14:53:03 +08:00
    @lqzhgood 标题和你最后给的答案都不对,你最后答案只是想用 component 渲染出来,r 函数都传过去了你不用,你这明显是为了得到 c ,走了弯路 b ,放着捷径 a 不走
    lqzhgood
        12
    lqzhgood  
    OP
       2022-07-13 15:00:33 +08:00
    > 也可能我的思路过于曲折,如果有更好的 A->Z 的方法也希望不吝赐教。
    表明只要达到目的即可,中间的路径 A -> Z 越优越好~
    templete 是我想到最优路径,所以这是我的答案。

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

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

    talk is easy, show me the code

    提醒一下 html 内容不定
    lqzhgood
        13
    lqzhgood  
    OP
       2022-07-13 15:44:51 +08:00
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   2783 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 35ms · UTC 14:44 · PVG 22:44 · LAX 07:44 · JFK 10:44
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.