P17:利用marked+highlight.js重构前台文章详细页面

目录
文章目录隐藏
  1. 安装 marked 和 highlight.js
  2. 重构detailed.js文件
  3. CSS 样式的更换

之前我们在博客文章详细页使用了react-markdown模块,但是这个插件的配置项还是太少了,而且我也没做太多的技术调研,所以我决定转回我目前项目中使用的一套方案marked+highlight.js。这个方案是比较成熟的,目前公司的开发文档程序就是基于这个开发的。

安装 marked 和 highlight.js

这两个模块需要先安装,这里我们就使用npm来进行安装。打开终端,进入到blog目录下,然后使用下面命令进行安装。

npm install --save marked
npm install --save highlight.js

当然也可使用yarn来进行安装

yarn add marked
yarn add highlight.js

我目前的版本是 marked 是 1.2.5,highlight 是 10.4.0。如果版本有变化,导致代码没法运行,可自行查看 API 进行修改。

重构detailed.js文件

这里的重构主要就是替换以前的Markdown解决方案。在代码顶部用import引入刚才安装的markedhighlight.js

引入模块

import marked from 'marked'
import hljs from "highlight.js";
import 'highlight.js/styles/monokai-sublime.css';

引入设置一下marked.setOptions,里边的属性比较多,我在这里详细的介绍一下。

const renderer = new marked.Renderer();
marked.setOptions({
  renderer: renderer, 
  gfm: true,
  pedantic: false,
  sanitize: false,
  tables: true,
  breaks: false,
  smartLists: true,
  smartypants: false,
  highlight: function (code) {
    return hljs.highlightAuto(code).value;
  }
}); 

let html = marked(props.article_content);
  • gfm:启动类似 Github 样式的 Markdown,填写 true 或者 false
  • pedatic:只解析符合 Markdown 定义的,不修正 Markdown 的错误。填写 true 或者 false
  • sanitize: 原始输出,忽略 HTML 标签,这个作为一个开发人员,一定要写 flase
  • tables: 支持 Github 形式的表格,必须打开 gfm 选项
  • breaks: 支持 Github 换行符,必须打开 gfm 选项,填写 true 或者 false
  • smartLists:优化列表输出,这个填写 ture 之后,你的样式会好看很多,所以建议设置成 ture
  • highlight: 高亮显示规则 ,这里我们将使用 highlight.js 来完成

增加 Code 的高亮显示

在设置setOptions属性时,可以直接设置高亮显示,代码如下:

highlight: function (code) {
  return hljs.highlightAuto(code).value;
}

设置完成后,你在浏览器检查代码时就可以出现 hljs 的样式,说明你的效果加成功了,实现了高亮显示代码。

detailed.js 所有代码

import React,{useState} from 'react'
import Head from 'next/head'
import axios from 'axios'
import {Row, Col, Space, Breadcrumb, Affix} from 'antd'
import {ClockCircleOutlined,VideoCameraOutlined,FireOutlined} from '@ant-design/icons'
import MarkNav from 'markdown-navbar';
import 'markdown-navbar/dist/navbar.css';
import marked from 'marked'
import hljs from "highlight.js";
import 'highlight.js/styles/monokai-sublime.css';

import Header from '../components/Header'
import Author from '../components/Author'
import Advert from '../components/Advert'
import Footer from '../components/Footer'

const Detailed = (props) => {
  const IconText = ({ icon, text }) => (
    <Space>
      {React.createElement(icon)}
      {text}
    </Space>
  );
  const renderer = new marked.Renderer();
  marked.setOptions({
    renderer: renderer, 
    gfm: true,
    pedantic: false,
    sanitize: false,
    tables: true,
    breaks: false,
    smartLists: true,
    smartypants: false,
    highlight: function (code) {
      return hljs.highlightAuto(code).value;
    }
  }); 

  let html = marked(props.article_content);
  
  return (
    <>
      <Head>
        <title>博客详细页</title>
      </Head>
      <Header />
      <Row className="comm-main" type="flex" justify="center">
        <Col className="comm-left" xs={24} sm={24} md={16} lg={18} xl={14}  >
            <div>
              <div className="bread-div">
                <Breadcrumb>
                  <Breadcrumb.Item><a href="/">首页</a></Breadcrumb.Item>
                  <Breadcrumb.Item>教程列表</Breadcrumb.Item>
                  <Breadcrumb.Item>xxxx</Breadcrumb.Item>
                </Breadcrumb>
              </div>
             <div>
                <div className="detailed-title">
                React 实战教程笔记-码云笔记开发
                </div>
                <div className="list-icon center">
                  <IconText icon={ClockCircleOutlined} text="2020-12-01" key="list-vertical-star-o" />
                  <IconText icon={VideoCameraOutlined} text="前端教程" key="list-vertical-like-o" />
                  <IconText icon={FireOutlined} text="5498 人" key="list-vertical-message" />
                </div>

                <div className="detailed-content"
                 dangerouslySetInnerHTML={{__html:html}}
                 >
                </div>
             </div>
            </div>
        </Col>

        <Col className="comm-right" xs={0} sm={0} md={7} lg={5} xl={4}>
          <Author />
          <Advert />
          <Affix offsetTop={5}>
            <div className="detailed-nav comm-box">
              <div className="nav-title">文章目录</div>
              <MarkNav
                className="article-menu"
                source={html}
                ordered={false}
              />
            </div>
          </Affix>
        </Col>
      </Row>
      <Footer/>
   </>
  )
}

Detailed.getInitialProps = async(context) => {
  let id = context.query.id;

  const promise = new Promise((resolve)=>{
    axios('http://127.0.0.1:7001/default/getArticleById/' + id).then((res) => {
      console.log(res)
      resolve(res.data.data[0])
    })
  })

  return await promise
}

export default Detailed

CSS 样式的更换

都设置好以后,是不是又觉的现在样式也不是很好看,所以可以继续设置一下 CSS 样式。因为笔记中我不讲解 CSS 样式部分,但是我给你提供了我detailed.css所有代码

.bread-div{
    padding: .5rem;
    border-bottom:1px solid #eee;
    background-color: #e1f0ff;
}
.detailed-title{
    font-size: 1.8rem;
    text-align: center;
    padding: 1rem;
}
.center{
    text-align: center;
}
.detailed-content{
    padding: 1.3rem;
    font-size: 1rem;
}
pre{
    display: block;
    background-color:#f3f3f3;
     padding: .5rem !important;
     overflow-y: auto;
     font-weight: 300;
     font-family: Menlo, monospace;
     border-radius: .3rem;
}
pre{
    background-color: #283646 !important;
}
pre >code{
    border:0px !important;
    background-color: #283646 !important;
    color:#FFF;

}
code {
    display: inline-block ;
    background-color:#f3f3f3;
    border:1px solid #fdb9cc;
    border-radius:3px;
    font-size: 12px;
    padding-left: 5px;
    padding-right: 5px;
    color:#4f4f4f;
    margin: 0px 3px;

}

.title-anchor{
    color:#888 !important;
    padding:4px !important;
    margin: 0rem !important;
    height: auto !important;
    line-height: 1.2rem !important;
    font-size: .7rem !important;
    border-bottom: 1px dashed #eee;
    overflow: hidden;
    text-overflow:ellipsis;
    white-space: nowrap;
}
.active{
    color:rgb(30, 144, 255) !important;
}
.nav-title{
    text-align: center;
    color: #888;
    border-bottom: 1px solid rgb(30, 144, 255);

}
.article-menu{
    font-size:12px;
}
iframe{
    height: 34rem;
}
.detailed-content  img{
    width: 100%;
    border:1px solid #f3f3f3;
}
.title-level3{
    display: none !important;
}
.ant-anchor-link-title{
    font-size: 12px !important;
}
.ant-anchor-wrapper{
    padding: 5px !important;
}

样式复制完,我们再到浏览器中预览一下,应该就可以出现更漂亮的效果了。

本文内容就到这里,下节我们把右侧的导航也重新完善一下,实现对文章章节的导航效果。学习是一定要跟着作,如果不作你也许什么都学不会。

「点点赞赏,手留余香」

0

给作者打赏,鼓励TA抓紧创作!

微信微信 支付宝支付宝

还没有人赞赏,快来当第一个赞赏的人吧!

声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。
码云笔记 » P17:利用marked+highlight.js重构前台文章详细页面

发表回复