react

封装的渲染富文本的组件: RenderRtf.tsx

import { useState, useEffect, useRef } from "react";
import parse from "html-react-parser";
import ReactDOM from "react-dom/client";
import Hello from "./Hello"; // 这里注册富文本中包含的自定义组件(也可以外部注册)
const regCompPublic = {
Hello,
}; // 渲染富文本
const RenderRtf = (props) => {
// 组件名字处理
const regCompTemp = { ...regCompPublic, ...props["regComp"] };
const regComp = {};
for (const key in regCompTemp) {
const keyStr = key.toLowerCase();
regComp[keyStr] = regCompTemp[key];
} // 子实例的根节点
const [root, setRoot] = useState<any>();
// 子实例的根节点的挂载点
const wrappNode = useRef(null);
// 子实例渲染
const rootRender = () => {
if (!root) {
console.warn("没有实例对象,此次实例无法重新render");
return false;
}
root.render(
parse(props.content, {
replace(domNode: any) {
if (Object.keys(regComp).indexOf(domNode.name) > -1) {
const Cmp = regComp[domNode.name];
return <Cmp {...domNode.attribs} />;
} else {
return domNode;
}
},
})
);
}; // 传入的内容更改 就需要重新渲染
useEffect(() => {
if (root) {
rootRender();
}
}, [props]); // 挂载第二(子)实例
useEffect(() => {
if (wrappNode.current && !root) {
const instanceRoot = ReactDOM.createRoot(wrappNode.current);
setRoot(instanceRoot);
rootRender();
}
}, [wrappNode]);
return (
<>
<div className="wrapp" ref={wrappNode}></div>
</>
);
}; export default RenderRtf;

页面中使用: App.tsx

import { useState } from "react";
import RenderRtf from "./components/RenderRtf";
import MarkdownIt from "markdown-it"; const md = MarkdownIt({
html: true,
linkify: true,
typographer: true,
});
function App() {
const [ipt, setIpt] = useState("你好 <Hello/>"); const onInput = (e: any) => {
setIpt(e.target.value);
}; return (
<>
<textarea value={ipt} onInput={onInput}/>
<RenderRtf content={md.render(ipt)} />
</>
);
} export default App;

html

基于此,vue我也实现了

封装的渲染富文本的组件: render-rtf.vue

<script setup lang="ts">
import { onMounted, ref, watch } from "vue";
import Hello from "@/components/HelloWorld.vue";
import * as Vue from "vue/dist/vue.esm-bundler.js"; const props = defineProps(["content"]);
let app: any = null;
const renRender = () => {
if (!showRtf.value) {
console.warn("没有子实例对象的挂载真实node,此次实例无法重新render");
return false;
}
// 不同于react,vue对外没有暴漏render函数,所以无法手动调用,只能更新整个实例来渲染
if (app) {
app.unmount();
}
showRtf.value.innerHTML = props.content;
app = Vue.createApp({
components: { //这里组测富文本中包含的vue组件
Hello,
},
});
app.mount(showRtf.value);
};
onMounted(() => {
renRender();
});
watch(
() => props.content,
(newVal) => {
renRender();
}
); const showRtf = ref();
</script> <template>
<div ref="showRtf"></div>
</template>

这里是使用 App.vue

<script setup lang="ts">
import {createApp} from 'vue';
import { ref, watch, computed } from "vue";
import MarkdownIt from "markdown-it";
import RenderRtf from '@/components/render-rtf.vue'; const md = MarkdownIt({
html: true,
linkify: true,
typographer: true,
});
const ipt = ref("哈哈<Hello/>");
</script> <template>
<textarea v-model="ipt"></textarea>
<render-rtf :content="md.render(ipt)"/>
</template>

结语

这样我们的markdwon不但可以使用官方规定的语法,还可以显示自定义组件。

这。。。这不就是第二个语雀了嘛?!

富文本里解析vue、react组件的更多相关文章

  1. 在循环列表的富文本里摘出每个item的img标签内容(适合vue渲染)

    昨天在做公司项目的社区动态内容.后台接口返回的数据是数组套对象,对象里有富文本,然后需要摘出富文本里的img标签在列表里分开渲染(即图片九宫格样式).最终效果如图: 这个是后盾接口返回的json数据 ...

  2. 富文本数据 解析HTML

    后台返回给前端的富文本数据如: { "status": 1, "info": "获取活动数据成功", "data": [ ...

  3. vue富文本(5版本)组件

    <template> <div> <div style="border: 1px solid #ccc; width: 500px"> < ...

  4. ckeditor5富文本编辑器在vue中的使用

    安装依赖: npm install --save @ckeditor/ckeditor5-vue @ckeditor/ckeditor5-build-classic 要创建编辑器实例,必须首先将编辑器 ...

  5. 处理后台传过来的json数据-显示到微信小程序的富文本里

    解析数据: JSON.parse(); 获取 加密的文章内容, 将解密文章内容, 将解密后的img标签的路径换成绝对地址(服务器) 调整图片的大小,

  6. 替换富文本里的px为rem

    var content = '23px' content = content.replace(/(\d+)px/g, function(s, t) { s = s.replace('px', ''); ...

  7. react 富文本编辑器

    5大富文本编辑器今天,富文本编辑器被用于许多应用中,包括简单的博客和复杂的内容管理系统.然而,选择一个并不容易,因为有很多具有不同功能的编辑器. 因此,在这篇文章中,我将评估5个React的富文本编辑 ...

  8. vue集成百度UEditor富文本编辑器

    在前端开发的项目中.难免会遇到需要在页面上集成一个富文本编辑器.那么.如果你有这个需求.希望可以帮助到你 vue是前端开发者所追捧的框架,简单易上手,但是基于vue的富文本编辑器大多数太过于精简.于是 ...

  9. Vue CLI 3+tinymce 5富文本编辑器整合

    基于Vue CLI 3脚手架搭建的项目整合tinymce 5富文本编辑器,vue cli 2版本及tinymce 4版本参考:https://blog.csdn.net/liub37/article/ ...

  10. Jquery会死吗?我为什么不用vue写富文本!

    一.事件背景: 我最近开源了一个个人耗时半年打造的富文本及一套适用于web后台的ui框架,在gitee上受到网友们的关注,部分网友对我采用jquery的技术栈提出了质疑.总结起来:无非是jquery已 ...

随机推荐

  1. 2025年BI工具趋势:DataFocus与FineBI的技术创新对比

    1. 摘要 DataFocus 和 FineBI 都是旨在帮助企业利用数据进行决策的商业智能 (BI) 产品.DataFocus 强调其下一代.基于搜索的 BI 方法,侧重于易用性和快速仪表板创建,尤 ...

  2. 为什么不推荐在 MySQL 中直接存储图片、音频、视频等大容量内容?

    在MySQL中直接存储图片.音频.视频等大容量内容(通常称为BLOB数据)通常不被推荐,主要原因包括以下几点: 1. 性能问题 存储效率:存储大容量文件(如图片.音频.视频等)会大幅增加数据库的存储负 ...

  3. K8s新手系列之资源清单(Manifests)

    Manifests的基本概念 在 Kubernetes 中,Manifests(清单)是用于定义集群中资源对象的声明式配置文件(通常以 YAML 或 JSON 格式编写,生产环境中通常以YAML编写) ...

  4. 解决NET Core发布iis项目覆盖原有的项目时"另一个程序正在使用此文件,进程无法访问"

    解决NET Core发布iis项目覆盖原有的项目时"另一个程序正在使用此文件,进程无法访问" 现在net core运用的多了,一系列的问题接踵而来,更新项目发布到iis时就有一个坑 ...

  5. 关闭windows10 Alt+Tab开打edge选项卡

    发现最近更新的windows10会使用快捷键Alt+Tab打开Edge的选项卡,很不适应,可喜的是微软提供了关闭的方法. 设置⚙->系统->多任务处理->Alt+Tab 设置为仅打开 ...

  6. 代码随想录第二十二天 | Leecode 77. 组合、216. 组合总和 III、17. 电话号码的字母组合

    Leecode 77. 组合 题目描述 给定两个整数 n 和 k,返回范围 [1, n] 中所有可能的 k个数的组合. 你可以按 任何顺序 返回答案. 示例 1: 输入:n = 4, k = 2 输出 ...

  7. 代码随想录第十一天 | Leecode 150. 逆波兰表达式求值、239. 滑动窗口最大值、347. 前k个高频词

    Leecode 150. 逆波兰表达式求值 题目链接:https://leetcode.cn/problems/evaluate-reverse-polish-notation/description ...

  8. 【HUST】网安|计算机网络|计算机网络自顶向下方法(原书第7版)第三章部分习题答案

    参考:英文版的原答案. 答案放gitee了,自取. 3-P18. 3.4.4 节我们学习的一般性 SR 协议中,只要报文可用(如果报文在窗口中) ,发送方就会不等待确认而传输报文.假设现在我们要求一个 ...

  9. Nacos源码—7.Nacos升级gRPC分析二

    大纲 5.服务变动时如何通知订阅的客户端 6.微服务实例信息如何同步集群节点 5.服务变动时如何通知订阅的客户端 (1)服务注册和服务订阅时发布的客户端注册和订阅事件的处理 (2)延迟任务的执行引擎源 ...

  10. LSTM 与 GRU

    弄完这块, 感觉对于 RNN (递归神经网络) 基本就接近尾声了. 相对于 之前的卷积神经网络, 我感觉 RNN 还是相对有意思一些, 也可能是在前面手推 CNN 公式时弄翻车的原因, 以及实在对图像 ...