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

之前我们在博客文章详细页使用了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;
}

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

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

1. 本站所有免费资源来源于用户上传和网络,因此不包含技术服务请大家谅解!如有侵权请邮件联系客服!
2. 本站不保证所提供下载的免费资源的准确性、安全性和完整性,免费资源仅供下载学习之用!如有链接无法下载、失效,请联系客服处理!
3. 您必须在下载后的24个小时之内,从您的电脑中彻底删除上述内容资源!如用于商业或者非法用途,与本站无关,一切后果请用户自负!
4. 如果您也有好的资源或技术教程,您可以投稿发布,成功分享后有站币奖励和额外收入!
5. 加入前端开发QQ群:565733884,我们大家一起来交流技术!
码云笔记 » P17:利用marked+highlight.js重构前台文章详细页面

发表评论

准备开启WordPress网站建设推广?

联系我们 定制开发