React 实现一个markdown[1]
「这是我参与2022首次更文挑战的第19天,活动详情查看:2022首次更文挑战」
我想实现类似我们掘金的一个文章发布的markdown,这是我们最后实现的结果
使用组件
React的markdown组件有很多我们这里用到的是react-markdown-editor-lite。他是对 MarkdownIt的再次封装。我们其他的Markdown右半部分的效果展示,是需要我们自己去实现的。这个插件会自动许渲染出右边的效果。
npm地址:https://www.npmjs.com/package/react-markdown-editor-lite
演示地址:https://harrychen0506.github.io/react-markdown-editor-lite/
标题
实现一下我们的标题输入部分,左部分是一个输入框Input,右边是一个div里面里面有一个提交按钮。
return (
<div className={style.markdown}>
<div className={style.header}>
{/* onChange(e) e.target.value */}
<Input
className={style.input}
size="middle"
onChange={e => setSubmitParams({ ...submitParams, title: e.target.value })}
/>
<div className={style.btn_con}>
<Button type="primary" onClick={showDrawer}>
发布
</Button>
</div>
</div>
</div>
)
对应的样式
.header{
display:flex;
}
.input{
width:70%;
border:0px;
font-size:24px;
font-weight: bold;
}
.btn_con{
width:30%;
padding:20px;
text-align: right;
background-color:#FFFFFF;
}
添加markedown
需要导入一下内容
import MarkdownIt from 'markdown-it';
import 'react-markdown-editor-lite/lib/index.css';
import MdEditor from 'react-markdown-editor-lite';
return (
<div className={style.markdown}>
<div className={style.header}>
{/* onChange(e) e.target.value */}
<Input
className={style.input}
size="middle"
// 改变提交参数的title
onChange={e => setSubmitParams({ ...submitParams, title: e.target.value })}
/>
<div className={style.btn_con}>
// 展示抽屉
<Button type="primary" onClick={showDrawer}>
发布
</Button>
</div>
</div>
<MdEditor
value={text}
// 给markdown一个高
style={{ height: '500px' }}
// 这个必传 用于右边展示效果的渲染
renderHTML={text => mdParser.render(text)}
// 改变markdown内容触发 函数 handleEditorChange
onChange={handleEditorChange}
// 配置html md是否渲染
config={{
view: {
menu: true,
md: true,
html: true,
},
}}
/>
</div>
)
全屏问题
点击这个全屏图标进入全屏后,发现我们刚才的标题部分不见了
审查元素发现是这个Markdown给我们的title内容遮盖住了。这个Markdown的class名是full
因此给full添加一个样式,让他距离顶部一个title内容的高度
:global{
.full {
top:70px !important;
}
}
完善组件功能
上面的代码只是在样式上实现了,我们来继续完善功能。
用到的变量
提交参数
这是我们整个页面提交到后端的参数。对应我们的Markdown的有markedown和html
// 提交参数
const [submitParams, setSubmitParams] = useState<SubmitParams>({
html: '',
markedown: '',
user_id: '2',
desc: '',
title: '',
user: 'ss',
date: new Date(),
type: '',
column: '',
cover: '',
publish: false,
});
Markdown用到的参数
// Markdown文本
const [text, setText] = useState();
// MarkDown HTML
const [html, setHtml] = useState();
方法
我们看一下上面的<MdEditor>
组件。看他用到的方法
<MdEditor
value={text}
style={{ height: '500px' }}
// 用于右边展示效果的渲染
renderHTML={text => mdParser.render(text)}
onChange={handleEditorChange}
config={{
view: {
menu: true,
md: true,
html: true,
},
}}
/>
mdParser
这个方法是对Markdown的内容处理之后再渲染。这里最后对Markdown中的code内容进行了高亮处理。
// 声明Markdown组件
const mdParser = new MarkdownIt({
html: true,
linkify: true,
typographer: true, // 设置代码高亮的配置
highlight(code, language) {
if (language && hljs.getLanguage(language)) {
try {
return `<pre><code class="hljs language-${language}">${hljs.highlight(code, { language }).value}</code></pre>`;
} catch (__) {}
}
return `<pre class="hljs"><code>${mdParser.utils.escapeHtml(code)}</code></pre>`;
},
});
这里需要引入一些样式样式
npm install github-markdown-css
// react-markdown-editor-lite中自带了,如果没有需要下载
import hljs from 'highlight.js'; // 引入highlight.js库 代码高亮
import 'highlight.js/styles/github.css'; // 引入github风格的代码高亮样式
// 这个dark风格跟我的有些样式冲突 所以没使用
// import 'highlight.js/styles/dark.css'
实现效果如下
handleEditorChange
这是Markdown内容改变触发的函数,html和text分别是Markdown对应的标签和md格式。
// 文本编辑器内容变化
const handleEditorChange = ({ html, text }) => {
//给变量赋值
setText(text);
setHtml(html);
// 这里我们提取标签中的文字然后作为文字简介
const reg = /<[^<>]+>/g; // 1、全局匹配g肯定忘记写 2、<>标签中不能包含标签实现过滤HTML标签
const text2 = html.replace(reg, '').replace(/[\r\n]/g,"");
// 这里将html和desc(文章简介)赋值给提交参数
// desc进行了截取处理
setSubmitParams({ ...submitParams, html, desc: text2.slice(0, 100) });
};
如图我们写一个表格,其对应的html 和 text如下
完善上传图片
到这里,我们基本实现了一个Markdown,但是对于Markdown的图片,其实还是需要上传到后端,后端再返回给前端一个地址的
- onImageUpload={handleImageUpload} 上传图片是触发函数handleImageUpload
- imageUrl:
'https://octodex.github.com/images/minion.png'
如果上传图片失败返回一个默认图片地址。
<MdEditor
value={text}
style={{ height: '500px' }}
// 用于右边展示效果的渲染
renderHTML={text => mdParser.render(text)}
onChange={handleEditorChange}
onImageUpload={handleImageUpload}
config={{
view: {
menu: true,
md: true,
html: true,
},
imageUrl: 'https://octodex.github.com/images/minion.png',
}}
/>
handleImageUpload
async function handleImageUpload(file, callback) {
const formData = new FormData();
formData.append('file', file);
//走接口
await UploadImage(formData).then(res => {
callback(res.url);
});
const reader = new FileReader();
// reader.onload = () => {
// };
reader.readAsDataURL(file);
}
相关文章
- Jgit的使用笔记
- 利用Github Action实现Tornadofx/JavaFx打包
- 叹息!GitHub Trending 即将成为历史!
- 微软软了?开源社区讨论炸锅,GitHub CEO 亲自来答
- GitHub Trending 列表频现重复项,前后端都没去重?
- Photoshop Elements 2021版本软件安装教程(mac+windows全版本都有)
- (ps全版本)Photoshop 2020的安装与破解教程(mac+windows全版本都有)
- (ps全版本)Photoshop cc2018的安装与破解教程(mac+windows全版本,包括2023
- 环境搭建:Oracle GoldenGate 大数据迁移到 Redshift/Flat file/Flume/Kafka测试流程
- 每个开发人员都要掌握的:最小 Linux 基础课
- 来撸羊毛了!Windows 环境下 Hexo 博客搭建,并部署到 GitHub Pages
- 超实用!手把手入门 MongoDB:这些坑点请一定远离
- 【GitHub日报】22-10-09 zustand、neovim、webtorrent、express 等4款App今日上新
- 【GitHub日报】22-10-10 brew、minio、vite、seaweedfs、dbeaver 等8款App今日上新
- 【GitHub日报】22-10-11 cobra、grafana、vue、ToolJet、redwood 等13款App今日上新
- Photoshop 2018 下载及安装教程(mac+windows全版本都有,包括最新的2023)
- Photoshop 2017 下载及安装教程(mac+windows全版本都有,包括最新的2023)
- Photoshop 2020 下载及安装教程(mac+windows全版本都有,包括最新的2023)
- Photoshop 2023 资源免费下载(mac+windows全版本都有,包括最新的2023)
- 最新版本Photoshop CC2018软件安装教程(mac+windows全版本都有,包括2023