使用ReactJS、Twin Macro和Styled Components创建简单的Markdown预览器。 #
大家好!您是否想过使用ReactJS构建自己的Markdown预览器?今天是您的幸运日!我最近使用ReactJS、Twin Macro和styled-components构建了一个Markdown预览器,并且我认为创建一个逐步指南来帮助您构建一个也会很有趣。所以,拿起一杯咖啡(或者茶,如果您喜欢),让我们开始吧!
第一步:设置基本的React应用程序 #
首先,我们需要设置一个基本的React应用程序。如果您还没有安装Node.js和npm,请确保在继续之前安装它们。
打开终端并运行以下命令来创建一个新的React应用程序:
npx create-react-app markdown-previewer
全屏模式退出全屏模式
第二步:安装包 #
接下来,我们需要安装必要的包。转到您的项目文件夹并运行以下命令: 安装所需包的命令如下:
npm install styled-components twin.macro marked dompurify
第三步:导入重要的包 #
现在我们已经安装了我们的包,让我们了解一下代码中的导入语句。
import React, { useState } from 'react';
import styled from 'styled-components';
import tw from 'twin.macro';
import {marked} from 'marked';
import DOMPurify from 'dompurify';
- React, { useState } 从 'react' 包中导入。useState hook 用于在我们的函数组件中管理状态。
- styled 从 'styled-components' 包中导入。这使我们能够编写实际的 CSS 代码来样式化我们的组件。
- tw 从 'twin.macro' 导入。这是一个快速构建自定义设计的实用 CSS 框架。
- marked 从 'marked' 导入。 ## 步骤 4:为我们的组件设置样式
既然我们已经准备好导入语句,让我们使用styled-components
和twin.macro
为我们的组件设置样式。
const Container = styled.div`
${tw`container mx-auto mt-10 mb-20`}
`;
const Header = styled.div`
${tw`text-center text-xl font-bold`}
`;
const Row = styled.div`
${tw`flex mt-10`}
`;
const Column = styled.div`
${tw`flex-1 mx-5 h-[35rem] w-[35rem]`}
`;
const Textarea = styled.textarea`
${tw`w-full h-full p-3 border rounded-md transition-all duration-300 ease-in-out`}
&:focus {
${tw`border-blue-500 outline-none shadow-outline`}
}
`;
const Preview = styled.div`
${tw`h-full w-full overflow-y-scroll overflow-x-scroll p-3 border rounded-md bg-gray-100`}`;
输入完毕 在这里,我们使用styled-components
和twin.macro
定义了Container、Header、Row、Column、Textarea和Preview。Container是一个带有一些边距和填充的div
元素。Header是一个带有居中文本和粗体字体的div
元素。Row是一个带有弹性显示和一些顶部边距的div
元素。Column是一个具有弹性-1、边距、高度和宽度定义的div
元素。Textarea是一个具有全宽度、全高度、填充、边框、圆角和过渡效果的textarea
元素。Preview是一个具有全高度、全宽度、溢出滚动、填充、边框、圆角和灰色背景的div
元素。
第五步:处理Markdown输入和预览 #
现在我们已经定义了样式化的组件,让我们来处理Markdown的输入和预览:
const [markdown, setMarkdown] = useState('');
const handleMarkdo wnChange = (e) => {
setMarkdown(e.target.value);
};
const getSanitizedHTML = () => {
const rawHTML = marked(markdown);
return DOMPurify.sanitize(rawHTML);
}
在这段代码中,我们定义了一个markdown
状态和一个setMarkdown
函数来更新状态。handleMarkdownChange
函数用于在用户在Textarea
中输入时更新markdown状态。getSanitizedHTML
函数用于将markdown文本转换为HTML并使用DOMPurify
进行清理,以防止XSS攻击。
第6步:渲染组件 #
最后,让我们渲染我们的组件。下面是组件的返回语句:
return (
<Container>
<Header>Markdown预览器</Header>
<Row>
<Column>
<Header>Markdown输入</Header>
<Textarea value={markdown} onChange={handleMarkdownChange} />
</Column>
<Column>
<Header>预览</He import React, { useState } from 'react';
import styled from 'styled-components';
import tw from 'twin.macro';
import {marked} from 'marked';
import DOMPurify from 'dompurify';
const Container = styled.div`
${tw`container mx-auto`}
`;
const Header = styled.h1`
${tw`text-4xl font-bold text-center mb-8`}
`;
const Row = styled.div`
${tw`flex flex-wrap`}
`;
const Column = styled.div`
${tw`w-full md:w-1/2`}
`;
const Textarea = styled.textarea`
${tw`w-full h-64 p-4 mb-4`}
`;
const Preview = styled.div`
${tw`w-full p-4 bg-gray-200`}
`;
const MarkdownPreviewer = () => {
const [markdown, setMarkdown] = useState('');
const handleMarkdownChange = (event) => {
setMarkdown(event.target.value);
};
const getSanitizedHTML = () => {
const sanitizedHTML = DOMPurify.sanitize(marked(markdown));
return { __html: sanitizedHTML };
};
return (
<Container>
<Header>Markdown Previewer</Header>
<Row>
<Column>
<Textarea value={markdown} onChange={handleMarkdownChange} />
</Column>
<Column>
<Preview dangerouslySetInnerHTML={getSanitizedHTML()} />
</Column>
</Row>
</Container>
);
};
export default MarkdownPreviewer;
``` 转换以下Markdown为中文并删除第一级标题:o mt-10 mb-20`
`;
const Header = styled.div`
${tw`text-center text-xl font-bold`}
`;
const Row = styled.div`
${tw`flex mt-10`}
`;
const Column = styled.div`
${tw`flex-1 mx-5 h-[35rem] w-[35rem]`}
`;
const Textarea = styled.textarea`
${tw`w-full h-full p-3 border rounded-md transition-all duration-300 ease-in-out`}
&:focus {
${tw`border-blue-500 outline-none shadow-outline`}
}
`;
const Preview = styled.div`
${tw`h-full w-full overflow-y-scroll overflow-x-scroll p-3 border rounded-md bg-gray-100`}
`;
const MarkdownPreviewer = () => {
const [markdown, setMarkdown] = useState('');
const handleMarkdownChange = (e) => {
setMarkdown(e.target.value);
};
const getSanitizedHTML = () => {
const rawHTML = marked(markdown);
return DOMPurify.sanitize(rawHTML);
}
return (
<Container>
<Header>Markdown预览器</Header>
<Row>
<Column>
<Header>Markdown输入</Header>
<Textarea value={markdown} onChange={handleMarkdownChange} />
</Column>
<Column>
<Header>预览</Header>
<Preview dangerouslySetInnerHTML={{ __html: getSanitizedHTML() }} />
</Column>
</Row>
</Container>
);
};
export default MarkdownPreviewer; 以下是将上述Markdown翻译成中文并删除第一级标题的结果:
```jsx
import React, { useState } from "react";
import marked from "marked";
import { Container, Row, Column, Header, Preview } from "./styles";
const MarkdownPreviewer = () => {
const [markdown, setMarkdown] = useState("");
const handleChange = (e) => {
setMarkdown(e.target.value);
};
const getSanitizedHTML = () => {
const sanitizedMarkdown = marked(markdown);
return { __html: sanitizedMarkdown };
};
return (
<Container>
<Row>
<Column>
<Header>编辑</Header>
<textarea
value={markdown}
onChange={handleChange}
placeholder="在这里输入Markdown"
/>
</Column>
<Column>
<Header>预览</Header>
<Preview dangerouslySetInnerHTML={getSanitizedHTML()} />
</Column>
</Row>
</Container>
);
};
export default MarkdownPreviewer;
这是最终的结果🎉: