开发人员用记事本编码,博客只用HTML显示代码块的日子已经一去不复返了。突出显示的代码更赏心悦目,也更容易阅读。
在本教程中,我们将创建一个React代码编辑器和语法高亮器,这样你就可以输入你的代码并看到它是如何被高亮显示的。我们还将在编辑器中提供互动性,这意味着用户将能够在多种语言和主题之间切换。
源代码将在这里提供,供参考。
React代码编辑器和语法高亮器的线框设计
首先,让我们创建一个简单的线框来设计组件的布局。
整个应用程序将驻留在App
,它将是我们应用程序的主要封装器。
在App
内,将有ControlsBox
和PanelsBox
组件。
ControlsBox
我们还将包括两个 组件。一个用于选择输入语言,另一个用于选择突出显示的主题。Dropdown
设置React代码编辑器项目
为了创建一个项目模板,我们将使用Create React App,它将在一分钟或更短的时间内设置一个完全配置的React项目。
要做到这一点,打开你的终端并运行以下命令。
npx create-react-app syntax-highlighter
然后通过运行cd syntax-highlighter
,切换到新创建的文件夹,通过运行npm start
,启动React开发服务器。
这应该会自动打开你的浏览器。你应该看到一个React默认的应用程序在端口3000
。
打开src
文件夹,删除所有文件,除了App.js
,App.css
,index.js
, 和index.css
。然后删除每个文件中的内容,因为我们将完全从头开始重写每个文件。
创建基础
首先,我们将创建我们项目的基础结构。
让我们从index.js
开始,它将渲染我们的应用程序。打开它并包含以下代码。
javascript
import ReactDOM from "react-dom";
import "./index.css";
import App from "./App";
ReactDOM.render(
<React.StrictMode>
<App />
</React.StrictMode>,
document.getElementById("root")
);
为了渲染,我们首先导入了ReactDOM
组件。然后,我们导入了一个扩展的样式表,来为基座设计样式。最后,我们导入了App
组件,并对它进行了设置,使它在DOM树内的root
元素中被渲染。
现在,打开index.css
文件并包含以下样式。
css
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
width: 100vw;
min-height: 100vh;
font-family: sans-serif;
background-color: #ffdee9;
background-image: linear-gradient(0deg, #ffdee9 0%, #b5fffc 100%);
}
我们首先为margin
,padding
, 和box-sizing
创建了重置规则,所以我们不必担心以后这些浏览器的默认值问题。这是很常见的做法,建议你在任何项目中从头开始建立。
我们还为body
创建了特定的规则,以便它总是充满整个屏幕的视口。我们还设置了一个特定的字体家族和一个渐变的背景。
打开App.js
,我们的应用程序的所有逻辑都在这里。包括以下代码。
javascript
import "./App.css";
export default function App() {
return (
<div className="App">
<div className="ControlsBox"></div>
<div className="PanelsBox"></div>
</div>
);
}
首先,我们为App.js
,导入一个外部样式表。
然后我们创建了一个App
函数,它将在先前创建的index.js
中呈现。在它里面,我们创建了一个App
div元素,这将是我们应用程序的主要包装器。此外,在App
包装器内,将有ControlsBox
和PanelsBox
组件。
现在,打开App.css
文件并添加以下样式。
css
.App {
max-width: 1200px;
margin: 0 auto;
padding: 20px;
}
.ControlsBox {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 20px;
}
.PanelsBox {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(400px, 1fr));
gap: 20px;
margin-top: 20px;
}
在这里,我们确保App
包装器不会超过特定的宽度。我们还把它放在视口的中心位置,并在里面添加了填充物。
对于ControlsBox
,我们将网格布局设置为两列,每列的宽度相同。我们还在两列之间添加了一个间隙。
PanelsBox
子节点也将使用两列的网格布局,两列之间有间隙。如果子节点的宽度小于400px
,布局将自动切换到一列,这意味着包含的Editor
和Highlighter
组件将显示在彼此的下方。
为了将PanelsBox
和ControlsBox
分开,我们在顶部添加了一个空白。
在React中用useState
钩子设置状态
数据将发生变化,因为在我们的应用程序中,将有用户选择语言和主题而触发的用户互动。为了在屏幕上正确显示它们,我们将需要把它们存储到状态变量中。
为此,我们将使用React内置的useState钩子,这是React生态系统中的一种标准处理方式。
打开App.js
,添加以下代码。
javascript
import React, { useState } from "react";
import "./App.css";
export default function App() {
const [input, setInput] = useState("");
const [language, setLanguage] = useState("");
const [theme, setTheme] = useState("");
return (
<div className="App">
<div className="ControlsBox"></div>
<div className="PanelsBox"></div>
</div>
);
}
首先,我们导入React的useState
钩子,然后在App
函数中包含input
,language
, 和theme
变量。
input
将跟踪用户在 中的输入, 将跟踪用户选择的编程语言, 将跟踪用户选择的高亮主题。Editor
language
theme
创建组件
为了将应用程序的构件从应用程序的逻辑中划分出来,我们将创建几个组件,以便以后导入到App.js
。
我们将在项目的根目录下创建一个单独的文件夹,称为components
,并为Dropdown
、Editor
、Highlighter
等组件创建单独的JS和CSS文件。
你可以手动创建这些文件,也可以使用终端命令mkdir components && cd components && touch Dropdown.js Dropdown.css Editor.js Editor.css Highlighter.js Highlighter.css
来节省时间。
Dropdown
组件
我们将使用Dropdown
组件进行语言和主题选择。唯一改变的变量将是我们将传入的数据。
打开Dropdown.js
文件,添加以下代码。
javascript
import "./Dropdown.css";
export const Dropdown = ({ defaultTheme, onChange, data }) => {
return (
<select className="select" defaultValue={defaultTheme} onChange={onChange}>
{Object.keys(data)
.sort()
.map((theme, index) => {
return (
<option key={index} value={theme}>
{theme}
</option>
);
})}
</select>
);
};
在这个代码块中,我们首先导入了Dropdown.js
的外部样式表。
我们使用了select
元素,然后通过我们将从App
收到的data
道具进行循环,以显示可用的主题选项。然后我们按字母顺序对这些选项进行排序。
我们还使用了defaultProp
,这样我们以后就可以设置初始启动时显示的默认主题选项,以及onChange
道具,这样我们以后就可以控制当用户选择一个特定的主题时发生什么。
现在,切换到DropDown.css
文件,添加以下样式。
css
.select {
height: "100px";
border: none;
border-radius: 5px;
padding: 5px 0;
background-color: #ffffff;
width: 100%;
}
对于Select
组件,我们设置了具体的高度,去掉了默认的边框,圆了角,在里面添加了填充物,将背景设置为白色,并确保它在水平方向上使用了父体的所有可用空间。
创建Editor
组件
Editor
组件将是一个文本区域,用户将在这里输入代码。打开Editor.js
文件并添加以下代码。
javascript
import "./Editor.css";
export const Editor = ({ placeHolder, onChange, onKeyDown }) => {
return (
<textarea
className="editor"
placeholder={placeHolder}
onChange={onChange}
></textarea>
);
};
注意我们首先导入了Editor.js
的外部样式表。
然后我们返回了textarea
元素,并包含了placeholder
道具,它将在初始启动时显示占位符值。我们还包括了onChange
道具,这样我们就可以控制用户输入代码时发生的情况。
让我们给Editor
组件添加一些样式。打开Editor.css
,包括以下样式。
css
.editor {
border: none;
min-height: 300px;
padding: 10px;
resize: none;
}
对于Editor
组件,我们删除了默认的边框,设置了最小高度,并添加了填充。
我们还确保了编辑块不能被用户手动调整大小。它仍然会根据用户输入的内容自动调整其高度。
添加 react-syntax-highlighter 包
为了突出代码块,我们将使用react-syntax-highlighter包。要安装它,在你的终端上运行以下命令。
npm i react-syntax-highlighter
然后打开Highlighter.js
文件,包括以下代码。
javascript
import SyntaxHighlighter from "react-syntax-highlighter";
import "./Highlighter.css";
export const Highlighter = ({ language, theme, children }) => {
return (
<SyntaxHighlighter
language={language}
style={theme}
className="highlighter"
>
{children}
</SyntaxHighlighter>
);
};
我们首先导入了SyntaxHighlighter
组件,然后为Highlighter.js
,导入了一个外部样式表。
SyntaxHighlighter
需要language
和style
。一旦我们将Highlighter
导入到App.js
,我们将把这些传入。
接下来,打开Highlighter.css
文件并添加以下样式规则。
css
.highlighter {
min-height: 300px;
}
这将确保Highlighter
组件总是使用最小高度,如果没有内容,这将很有用(避免组件自动缩小)。
创建应用程序的逻辑
在这一阶段,我们将把所有东西放在一起,使应用程序发挥作用。
打开App.js
文件,添加以下代码。
javascript
import React, { useState } from "react";
import { Dropdown } from "../components/Dropdown";
import { Editor } from "../components/Editor";
import { Highlighter } from "../components/Highlighter";
import * as themes from "react-syntax-highlighter/dist/esm/styles/hljs";
import * as languages from "react-syntax-highlighter/dist/esm/languages/hljs";
import "./App.css";
const defaultLanguage = <code>${"javascript" || Object.keys(languages).sort()[0]}<code>;
const defaultTheme = <code>${"atomOneDark" || Object.keys(themes).sort()[0]}<code>;
export default function App() {
const [input, setInput] = useState("");
const [language, setLanguage] = useState(defaultLanguage);
const [theme, setTheme] = useState(defaultTheme);
return (
<div className="App">
<div className="ControlsBox">
<Dropdown
defaultTheme={defaultLanguage}
onChange={(e) => setLanguage(e.target.value)}
data={languages}
/>
<Dropdown
defaultTheme={defaultTheme}
onChange={(e) => setTheme(e.target.value)}
data={themes}
/>
</div>
<div className="PanelsBox">
<Editor
placeHolder="Type your code here..."
onChange={(e) => setInput(e.target.value)}
/>
<Highlighter language={language} theme={themes[theme]}>
{input}
</Highlighter>
</div>
</div>
);
}
让我们来分解一下这个代码块。
首先,我们从react-syntax-highlighter导入Dropdown
、Editor
、Highlighter
组件,以及所有支持的主题和语言。
然后我们将defaultLanguage
变量设置为javascript
。如果它在我们导入的语言列表中不可用,我们就将defaultlanguage
设置为导入的语言列表中的第一个可用语言。对于defaultTheme
也是如此。
我们还将defaultTheme
变量设置为atomOneDark
。如果它在导入的主题列表中不可用,defaultTheme
的值将被设置为导入的主题列表中的第一个可用主题。
对于Dropdown
组件,我们设置了defaultLanguage
和defaultTheme
,一旦应用程序首次渲染,它们就会显示。
请注意,当用户从下拉菜单中进行选择时,onChange
行为将更新language
和theme
的变量状态。
最后,我们传入了生成下拉选项列表的data
道具。
对于Editor
组件,我们设置了placeHolder
组件,以便在应用程序首次呈现时要求用户输入一些信息。它还设置了onChange
函数,在用户每次在Editor
中写东西时更新input
状态变量。
最后,对于Highlighter
组件,我们传入了language
变量状态--所以它知道要渲染哪种语言--以及themes
变量状态,所以它知道如何进行样式设计。
剩下的最后一件事就是测试我们的应用程序了!检查你的终端,看看开发服务器是否仍在运行(如果没有,请运行npm start
),然后打开浏览器。
你应该看到功能代码编辑器和高亮显示。
结论
在本教程中,我们学习了如何为一个应用程序创建一个线框,使用状态,创建组件,对它们进行样式设计,以及创建应用程序的逻辑。
从现在开始,每次你需要挑选最合适的主题时,你都不需要再建立一个测试应用程序。现在,你将拥有自己的工具,可以使用!
在未来,你可以通过添加认证系统和数据库来进一步定制该项目,以便用户可以保存他们的片段,创建一个全栈的游乐场。
我希望你能从这个教程中学到一两点东西。谢谢你的阅读!
The postBuilding a React code editor and syntax highlighter from scratchappeared first onLogRocket Blog.