You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
importReactMarkdownfrom'react-markdown';constinput='# This is a header\n\nAnd this is a paragraph';ReactDOM.render(<ReactMarkdownsource={input}/>,document.getElementById('container'));
如果是marked,这样做:
importmarkedfrom'marked';constinput='# This is a header\n\nAnd this is a paragraph';constoutput=marked(input);
学习 React 的过程中实现了一个个人主页,没有复杂的实现和操作,适合入门 ~
这个项目其实功能很简单,就是常见的主页、博客、demo、关于我等功能。
页面样式都是自己写的,黑白风格,可能有点丑。不过还是最低级的 CSS ,准备到时候重构 ~
如果有更好的方法,或者是我的想法有偏差的,欢迎大家交流指正
欢迎参观:http://axuebin.com/react-blog
Github:https://github.com/axuebin/react-blog
预览图
首页
博客页
文章内容页
Demo页
关键技术
准备工作
由于不是使用 React 脚手架生成的项目,所以每个东西都是自己手动配置的。。。
模块打包器
打包用的是
webpack 2.6.1
,准备入坑webpack 3
。官方文档:https://webpack.js.org/
中文文档:https://doc.webpack-china.org/
对于
webpack
的配置还不是太熟,就简单的配置了一下可供项目启动:webpack
有几个重要的属性:entry
、module
、output
、plugins
,在这里我还没使用到插件,所以没有配置plugins
。module
中的loaders
:包管理
包管理现在使用的还是
NPM
。官方文档:https://docs.npmjs.com/
关于
npm
,可能还需要了解dependencies
和devDependencies
的区别,我是这样简单理解的:代码检查
项目使用现在比较流行的
ESLint
作为代码检查工具,并使用Airbnb
的检查规则。ESLint:https://github.com/eslint/eslint
eslint-config-airbnb:https://www.npmjs.com/package/eslint-config-airbnb
在
package.json
中可以看到,关于ESLint
的包就是放在devDependencies
底下的,因为它只是在开发的时候会使用到。使用
webpack
配置中加载eslint-loader
:.elintrc
文件:然后在运行
webpack
的时候,就会执行代码检查啦,看着一堆的warning
、error
是不是很爽~这里有常见的ESLint规则:http://eslint.cn/docs/rules/
数据源
由于是为了练习
React
,暂时就只考虑搭建一个静态页面,而且现在越来越多的大牛喜欢用Github Issues
来写博客,也可以更好的地提供评论功能,所以我也想试试用Github Issues
来作为博客的数据源。API在这:https://developer.github.com/v3/issues/
我也没看完全部的API,就看了看怎么获取
Issues
列表。。https://api.github.com/repos/axuebin/react-blog/issues?creator=axuebin&labels=blog
通过控制参数
creator
和labels
,可以筛选出作为展示的Issues
。它会返回一个带有issue
格式对象的数组。每一个issue
有很多属性,我们可能不需要那么多,先了解了解底下这几种:异步请求数据
项目中使用的异步请求数据的方法时
fetch
。关于
fetch
:https://segmentfault.com/a/1190000003810652使用起来很简单:
markdown 渲染
在
Github
上查找关于如何在React
实现markdown
的渲染,查到了这两种库:使用起来都很简单。
如果是
react-markdown
,只需要这样做:如果是
marked
,这样做:这里有点不太一样,我们获取到了一个字符串
output
,注意,是一个字符串,所以我们得将它插入到dom
中,在React
中,我们可以这样做:由于我们的项目是基于
React
的,所以想着用react-markdown
会更好,而且由于安全问题React
也不提倡直接往dom
里插入字符串,然而在使用过程中发现,react-markdown
对表格的支持不友好,所以只好弃用,改用marked
。代码高亮
代码高亮用的是
highlight.js
:https://github.com/isagalaev/highlight.js它和
marked
可以无缝衔接~只需要这样既可:
highlight.js
是支持多种代码配色风格的,可以在css
文件中进行切换:在这可以看到每种语言的高亮效果和配色风格:https://highlightjs.org/
React
state 和 props 是什么
可以看之前的一篇文章:#8
关于React组件的生命周期
可以看之前的一篇文章:#9
前端路由
项目中前端路由用的是
React-Router V4
。官方文档:https://reacttraining.com/react-router/web/guides/quick-start
中文文档:http://reacttraining.cn/
基本使用
注意:一定要在根目录的
Route
中声明exact
,要不然点击任何链接都无法跳转。2级目录跳转
比如我现在要在博客页面上点击跳转,此时的
url
是localhost:8080/blog
,需要变成localhost:8080/blog/article
,可以这样做:这样就可以跳转到
localhost:8080/blog/article
了,而且还传递了一个number
参数,在article
中可以通过this.props.params.number
获取。HashRouter
当我把项目托管到
Github Page
后,出现了这样一个问题。通过了解,知道了原因是这样,并且可以解决:
Cannot GET /
错误。<Router>
→<HashRouter>
。<HashRouter>
借助URL上的哈希值(hash)来实现路由。可以在不需要全屏刷新的情况下,达到切换页面的目的。路由跳转后不会自动回到顶部
当前一个页面滚动到一定区域后,点击跳转后,页面虽然跳转了,但是会停留在滚动的区域,不会自动回到页面顶部。
可以通过这样来解决:
状态管理
项目中多次需要用到从
Github Issues
请求来的数据,因为之前就知道Redux
这个东西的存在,虽然有点大材小用,为了学习还是将它用于项目的状态管理,只需要请求一次数据即可。官方文档:http://redux.js.org/
中文文档:http://cn.redux.js.org/
简单的来说,每一次的修改状态都需要触发
action
,然而其实项目中我现在还没用到修改数据2333。。。关于状态管理这一块,由于还不是太了解,就不误人子弟了~
主要组件
React是基于组件构建的,所以在搭建页面的开始,我们要先考虑一下我们需要一些什么样的组件,这些组件之间有什么关系,哪些组件是可以复用的等等等。
首页
可以看到,我主要将首页分成了四个部分:
博客页
博客页就是很中规中矩的一个页面吧,这部分是整个项目中代码量最多的部分,包括以下几部分:
文章列表
文章列表其实就是一个
list
,里面有一个个的item
:对于每一个
item
,其实是这样的:一个文章item组件它可能需要包括:
如果用
DOM
来描述,它应该是这样的:所以,我们可以有很多个组件:
<ArticleList />
<ArticleItem />
<ArticleLabel />
它们可能是这样一个关系:
分页
对于分页功能,传统的实现方法是在后端完成分页然后分批返回到前端的,比如可能会返回一段这样的数据:
也就是后端会返回分好页的数据,含有表示总数据量的
total
、当前页数的page
,以及属于该页的数据data
。然而,我这个页面只是个静态页面,数据是放在Github Issues上的通过API获取的。(Github Issues的分页貌似不能自定义数量...),所以没法直接返回分好的数据,所以只能在前端强行分页~
分页功能这一块我偷懒了...用的是
antd
的翻页组件<Pagination />
。官方文档:https://ant.design/components/pagination-cn/
文档很清晰,使用起来也特别简单。
前端渲染的逻辑(有点蠢):将数据存放到一个数组中,根据当前页数和每页显示条数来计算该显示的索引值,取出相应的数据即可。
翻页组件中:
当页数发生改变后,会触发从父组件传进
<ArticlePaging />
的方法handlePageChange
,从而将页数传递到父组件中,然后传递到<ArticleList />
中。父组件中:
列表中:
label
在
Github Issues
中,可以为一个issue
添加很多个label
,我将这些对于博客内容有用的label
分为三类,分别用不同颜色来表示。这里说明一下,
label
创建后会随机生成一个id
,虽然说id
是不重复的,但是文章的类别、标签会一直在增加,当新加一个label
时,程序中可能也要进行对应的修改,当作区分label
的标准可能就不太合适,所以我采用颜色来区分它们。blog
的issue
才能显示在页面上,过滤bug
、help
等即使有新的
label
,也只要根据颜色区分是属于哪一类就好了。类别
在这里的思路主要就是:遍历所有
issues
,然后再遍历每个issue
的labels
,找出属于类别的label
,然后计数。这样实现得要经历三次循环,复杂度有点高,感觉有点蠢,有待改进,如果有更好的方法,请多多指教~
标签
这里的思路和类别的思路基本一样,只不过不同的显示方式而已。
本来这里是想通过字体大小来体现每个标签的权重,后来觉得可能对于我来说,暂时只有那几个标签会很频繁,其它标签可能会很少,用字体大小来区分就没有什么意义,还是改成排序的方式。
文章页
文章页主要分为两部分:
文章内容
有两种方式获取文章具体内容:
issue number
重新发一次请求直接获取内容最后我选择了后者。
文章是用
markdown
语法写的,所以要先转成html
然后插入页面中,这里用了一个React
不提倡的属性:dangerouslySetInnerHTML
。除了渲染
markdown
,我们还得对文章中的代码进行高亮显示,还有就是定制文章中不同标签的样式。章节目录
首先,这里有一个
issue
,希望大家可以给一些建议~文章内容是通过
markdown
渲染后插入dom
中的,由于React
不建议通过document.getElementById
的形式获取dom
元素,所以只能想办法通过字符串匹配的方式获取文章的各个章节标题。由于我不太熟悉正则表达式,曾经还在sf上咨询过,就采用了其中一个答案:
这样可以获取到所有的
#
的字符串,也就是markdown
中的标题,result[1].length
表示有几个#
,其实就是几级标题的意思,title
就是标题内容了。这里还有一个问题,本来通过
<a target="" />
的方式可以实现点击跳转,但是现在渲染出来的html
中对于每一个标题没有独一无二的标识。。。归档页
按年份归档:
按类别归档:
按标签归档:
问题
基本功能是已经基本实现了,现在还存在着以下几个问题,也算是一个
TodoList
吧Github Issues API
实现评论,得实现Github
授权登录antd
的组件,但是state
中visibility
一直是false
webpack
按需加载。这可能是目前最方便的方式todo
之一The text was updated successfully, but these errors were encountered: