<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          前端Markdown渲染(In React)

          共 5666字,需瀏覽 12分鐘

           ·

          2023-09-15 18:53

          這里是終于還有兩個(gè)頁(yè)面就要寫(xiě)完項(xiàng)目的丹星,這篇也是講述掘金網(wǎng)頁(yè)項(xiàng)目中用到的比較重要的一個(gè)技術(shù)——markdown的前端渲染。
          提起markdown很多人會(huì)想到Typora,這也是我常用的markdown編輯器,下面是Typora的界面。
                  其實(shí)Typora是將markdown語(yǔ)法編譯成為了HTML,然后展現(xiàn)了出來(lái),比如單個(gè)#號(hào)編譯為了H1標(biāo)簽。

                  掘金和CSDN這類網(wǎng)頁(yè)也提供了markdown寫(xiě)作的功能。那么前端如何做一個(gè)markdown的富文本編輯器并且呈現(xiàn)實(shí)時(shí)預(yù)覽呢?

                  一套簡(jiǎn)單的技術(shù)棧是:marked.js實(shí)現(xiàn)markdown文本轉(zhuǎn)HTML,highlight.js對(duì)代碼進(jìn)行高亮。

          但是如果你是一名React選手,那么你可以使用:

          • 富文本編輯以及預(yù)覽:md-editor-rt
          • markdown文本解析:react-markdown
          • 使markdown支持HTML語(yǔ)法:rehype-raw
          • 劃線、表、任務(wù)列表和直接url等的語(yǔ)法擴(kuò)展:remark-gfm
          • 代碼高亮:react-syntax-highlighter
          • 目錄提取與跳轉(zhuǎn):markdown-navbar

          沒(méi)錯(cuò),我就是組件小子

          下面來(lái)體驗(yàn)一下React的強(qiáng)大生態(tài)。

          md-editor-rt富文本編輯器

          下載

          yarn add md-editor-rt

          在React Hooks中,只需要非常簡(jiǎn)單的引入,使用useState配合Editor的兩個(gè)API,就可以實(shí)現(xiàn)輸入markdown并且實(shí)時(shí)渲染。

          import React, { useState } from 'react';
          // 導(dǎo)入組件
          import Editor from 'md-editor-rt';
          // 引入樣式
          import 'md-editor-rt/lib/style.css';  

          export default function Md({
            const [text, setText] = useState('hello md-editor-rt!');
            return <Editor modelValue={text} onChange={setText} />;
          }

          并且md-editor-rt自帶了Toolbar,也就是編輯框上方的輔助欄,可以幫助用戶更好的編輯。

          React-markdown的渲染

                  上面說(shuō)的是markdown編輯器以及渲染,如果后端傳來(lái)了一個(gè)markdown文本,我們需要把它渲染到網(wǎng)頁(yè)上,就像我們點(diǎn)進(jìn)CSDN和掘金看文章,這時(shí)候需要對(duì)markdown做一個(gè)渲染,就可以用到react-markdown。下載

          yarn add react-markdown

                  只需要把markdown的文本放到ReactMarkdown雙標(biāo)簽的組件就可以啦

          import ReactMarkdown from "react-markdown";
          <ReactMarkdown># Hello, *World*!</ReactMarkdown>

                  上方的Hello World!被解析為了一個(gè)h1標(biāo)簽。如果是單標(biāo)簽的話,我們可以把markdown的文本傳入children參數(shù)中。

          import ReactMarkdown from "react-markdown";
          <ReactMarkdown children={markdownText} />

          引入插件支持

                  react-markdown并不支持所有的Markdown語(yǔ)法,但是我們可以使用插件來(lái)添加對(duì)這些語(yǔ)法的支持。

          • remake-plugin增加了對(duì)腳注、劃線、表、任務(wù)列表、自動(dòng)鏈接文字或直接url的支持
          • rehype-raw增加了對(duì)HTML原生語(yǔ)法的支持
          import gfm from "remark-gfm";
          import rehypeRaw from 'rehype-raw'
          import gfm from 'remark-gfm';
          <ReactMarkdown
            children={text}
            rehypePlugins={[rehypeRaw]}
            remarkPlugins={[gfm]}
          />

          react-syntax-highlighter

                  markdown中代碼會(huì)轉(zhuǎn)為code標(biāo)簽,但是HTML中對(duì)code其實(shí)沒(méi)有很好的樣式支持,所以我們需要額外的組件進(jìn)行代碼高亮。

                  我們可以定義一個(gè)組件(component),加入到react-markdown中。

          import gfm from "remark-gfm";
          import rehypeRaw from 'rehype-raw'
          import gfm from 'remark-gfm';
          <ReactMarkdown
            children={text}
            rehypePlugins={[rehypeRaw]}
            remarkPlugins={[gfm]}
            components={CodeBlock}
          />

                  其中CodeBlock是我們定義的插件。

                  首先,我們導(dǎo)入react-syntax-highlighter和一個(gè)代碼主題,這里是atomDark,你也可以選擇別的主題。

          import { Prism as SyntaxHighlighter } from 'react-syntax-highlighter';
          import { atomDark } from 'react-syntax-highlighter/dist/esm/styles/prism';

          const CodeBlock = {
            code({ node, inline, className, children, ...props }) {
              const match = /language-(\w+)/.exec(className || '');
              return !inline && match ? (
                <SyntaxHighlighter
                  children={String(children).replace(/\n$/, '')}
                  style={atomDark} // theme
                  language={match[1].toLowerCase()}
                  PreTag="section" // parent tag
                  {...props}
                />

              ) : (
                <code className={className} {...props}>
                  {children}
                </code>

              );
            },
          };

                  下面的這一串code({ node, inline, className, children, ...props }) 可以看成是模板(因?yàn)槲乙膊惶芸吹枚呛竺娴拇a其實(shí)比較容易理解。

                  這里的match其實(shí)是抽取了代碼塊的代碼語(yǔ)言,match[1]的位置其實(shí)就是指定的語(yǔ)言,這里一個(gè)踩坑的點(diǎn):最好把字符串小寫(xiě)化。因?yàn)橛脩艨赡茌斎氲氖?code style="font-size: 14px;overflow-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;color: rgb(30, 107, 184);background-color: rgba(27, 31, 35, 0.05);font-family: "Operator Mono", Consolas, Monaco, Menlo, monospace;word-break: break-all;">Java,但是SyntaxHighlighter其實(shí)只能識(shí)別java,所以會(huì)出現(xiàn)代碼沒(méi)有高亮的情況。

                  返回三元字符串的意思是如果語(yǔ)言支持,則使用SyntaxHighlighter高亮,如果不支持則直接返回code標(biāo)簽包裹。

          markdown-navbar目錄提取

                  仍然是一個(gè)無(wú)腦的組件,你只需要將markdown文本傳入source參數(shù),就可以自動(dòng)提取標(biāo)題,并且點(diǎn)擊標(biāo)題可以實(shí)現(xiàn)跳轉(zhuǎn)和目錄高亮。

          import MarkNav from 'markdown-navbar';
          <MarkNav source={text} />

          網(wǎng)頁(yè)案例

                  好了,你現(xiàn)在以及會(huì)markdown的渲染操作了,去寫(xiě)一個(gè)博客網(wǎng)頁(yè)的案例吧,只需要再加一點(diǎn)點(diǎn)細(xì)節(jié)。




          歡迎關(guān)注這個(gè)摸魚(yú)更新的公眾號(hào)


          瀏覽 792
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  亚洲一级无码视频 | 日本和韩国的黄色一级视频 | 欧美熟女BB | 午夜小视频网站 | 久久久婷婷 |