国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

手把手教你用React實現(xiàn)一個簡單的個人博客

zhaochunqi / 3499人閱讀

摘要:官方文檔中文文檔基本使用注意一定要在根目錄的中聲明,要不然點擊任何鏈接都無法跳轉(zhuǎn)。官方文檔中文文檔簡單的來說,每一次的修改狀態(tài)都需要觸發(fā),然而其實項目中我現(xiàn)在還沒用到修改數(shù)據(jù)。。。

學(xué)習(xí) React 的過程中實現(xiàn)了一個個人主頁,沒有復(fù)雜的實現(xiàn)和操作,適合入門 ~

原文地址:https://github.com/axuebin/react-blog/issues/17

這個項目其實功能很簡單,就是常見的主頁、博客、demo、關(guān)于我等功能。

頁面樣式都是自己寫的,黑白風(fēng)格,可能有點丑。不過還是最低級的 CSS ,準(zhǔn)備到時候重構(gòu) ~

如果有更好的方法,或者是我的想法有偏差的,歡迎大家交流指正

歡迎參觀:http://axuebin.com/react-blog

Github:https://github.com/axuebin/react-blog

預(yù)覽圖 首頁

博客頁

文章內(nèi)容頁

Demo頁

關(guān)鍵技術(shù)

ES6:項目中用到 ES6 的語法,在寫的過程中盡量使用,可能有的地方?jīng)]想到

React

React-Router:前端路由

React-Redux:狀態(tài)管理

webpack:打包

marked:Markdown渲染

highlight.js:代碼高亮

fetch:異步請求數(shù)據(jù)

eslint:代碼檢查

antd:部分組件懶得自己寫。。

準(zhǔn)備工作

由于不是使用 React 腳手架生成的項目,所以每個東西都是自己手動配置的。。。

模塊打包器

打包用的是 webpack 2.6.1,準(zhǔn)備入坑 webpack 3

官方文檔:https://webpack.js.org/

中文文檔:https://doc.webpack-china.org/

對于 webpack 的配置還不是太熟,就簡單的配置了一下可供項目啟動:

var webpack = require("webpack");
var path = require("path");

module.exports = {
  context: __dirname + "/src",
  entry: "./js/index.js",
  module: {
    loaders: [
      {
        test: /.js?$/,
        exclude: /(node_modules)/,
        loader: "babel-loader",
        query: {
          presets: ["react", "es2015"]
        }
      }, {
        test: /.css$/,
        loader: "style-loader!css-loader"
      }, {
        test: /.js$/,
        exclude: /(node_modules)/,
        loader: "eslint-loader"
      }, {
        test: /.json$/,
        loader: "json-loader"
      }
    ]
  },
  output: {
    path: __dirname + "/src/",
    filename: "bundle.js"
  }
}

webpack 有幾個重要的屬性:entry、module、outputplugins,在這里我還沒使用到插件,所以沒有配置 plugins 。

module 中的 loaders

babel-loader:將代碼轉(zhuǎn)換成es5代碼

css-loader:處理css中路徑引用等問題

style-loader:動態(tài)把樣式寫入css

eslin-loader:使用eslint

包管理

包管理現(xiàn)在使用的還是 NPM

官方文檔:https://docs.npmjs.com/

npm init

npm install

npm uninstall

關(guān)于npm,可能還需要了解 dependenciesdevDependencies 的區(qū)別,我是這樣簡單理解的:

dependencies:項目跑起來后需要使用到的模塊

devDependencies:開發(fā)的時候需要用的模塊,但是項目跑起來后就不需要了

代碼檢查

項目使用現(xiàn)在比較流行的 ESLint 作為代碼檢查工具,并使用 Airbnb 的檢查規(guī)則。

ESLint:https://github.com/eslint/eslint

eslint-config-airbnb:https://www.npmjs.com/package/eslint-config-airbnb

package.json 中可以看到,關(guān)于 ESLint 的包就是放在 devDependencies 底下的,因為它只是在開發(fā)的時候會使用到。

使用

webpack 配置中加載 eslint-loader

module: {
  loaders: [
      {
        test: /.js$/,
        exclude: /(node_modules)/,
        loader: "eslint-loader"
      }
    ]
  }

創(chuàng)建 .elintrc文件:

{
  "extends": "airbnb",
  "env":{
    "browser": true
  },
  "rules":{}
}

然后在運行 webpack 的時候,就會執(zhí)行代碼檢查啦,看著一堆的 warningerror 是不是很爽~

這里有常見的ESLint規(guī)則:http://eslint.cn/docs/rules/

數(shù)據(jù)源

由于是為了練習(xí) React,暫時就只考慮搭建一個靜態(tài)頁面,而且現(xiàn)在越來越多的大牛喜歡用 Github Issues 來寫博客,也可以更好的地提供評論功能,所以我也想試試用 Github Issues 來作為博客的數(shù)據(jù)源。

API在這:https://developer.github.com/v3/issues/

我也沒看完全部的API,就看了看怎么獲取 Issues 列表。。

https://api.github.com/repos/axuebin/react-blog/issues?creator=axuebin&labels=blog

通過控制參數(shù) creatorlabels,可以篩選出作為展示的 Issues。它會返回一個帶有 issue 格式對象的數(shù)組。每一個 issue 有很多屬性,我們可能不需要那么多,先了解了解底下這幾種:

// 為了方便,我把注釋寫在json中了。。
[{
  "url": ,  // issue 的 url
  "id": ,  // issue id , 是一個隨機生成的不重復(fù)的數(shù)字串 
  "number": ,  // issue number , 根據(jù)創(chuàng)建 issue 的順序從1開始累加
  "title": ,  // issue 的標(biāo)題
  "labels": [], // issue 的所有 label,它是一個數(shù)組
  "created_at": , // 創(chuàng)建 issue 的時間
  "updated_at": , // 最后修改 issue 的時間
  "body": , // issue 的內(nèi)容
}]
異步請求數(shù)據(jù)

項目中使用的異步請求數(shù)據(jù)的方法時 fetch

關(guān)于 fetch :https://segmentfault.com/a/1190000003810652

使用起來很簡單:

fetch(url).then(response => response.json())
      .then(json => console.log(json))
      .catch(e => console.log(e));
markdown 渲染

Github 上查找關(guān)于如何在 React 實現(xiàn) markdown 的渲染,查到了這兩種庫:

react-markdown:https://github.com/rexxars/react-markdown

marked:https://github.com/chjj/marked

使用起來都很簡單。

如果是 react-markdown,只需要這樣做:

import ReactMarkdown from "react-markdown";

const input = "# This is a header

And this is a paragraph";
ReactDOM.render(
    ,
    document.getElementById("container")
);

如果是marked,這樣做:

import marked from "marked";

const input = "# This is a header

And this is a paragraph";
const output = marked(input);

這里有點不太一樣,我們獲取到了一個字符串 output,注意,是一個字符串,所以我們得將它插入到 dom中,在 React 中,我們可以這樣做:

由于我們的項目是基于 React 的,所以想著用 react-markdown會更好,而且由于安全問題 React 也不提倡直接往 dom 里插入字符串,然而在使用過程中發(fā)現(xiàn),react-markdown 對表格的支持不友好,所以只好棄用,改用 marked

代碼高亮

代碼高亮用的是highlight.js:https://github.com/isagalaev/highlight.js

它和marked可以無縫銜接~

只需要這樣既可:

import hljs from "highlight.js";

marked.setOptions({
  highlight: code => hljs.highlightAuto(code).value,
});

highlight.js是支持多種代碼配色風(fēng)格的,可以在css文件中進行切換:

@import "~highlight.js/styles/atom-one-dark.css";

在這可以看到每種語言的高亮效果和配色風(fēng)格:https://highlightjs.org/

React state 和 props 是什么

可以看之前的一篇文章:https://github.com/axuebin/react-blog/issues/8

關(guān)于React組件的生命周期

可以看之前的一篇文章:https://github.com/axuebin/react-blog/issues/9

前端路由

項目中前端路由用的是 React-Router V4

官方文檔:https://reacttraining.com/react-router/web/guides/quick-start

中文文檔:http://reacttraining.cn/

基本使用
Blog

  
  
  

注意:一定要在根目錄的 Route 中聲明 exact,要不然點擊任何鏈接都無法跳轉(zhuǎn)。

2級目錄跳轉(zhuǎn)

比如我現(xiàn)在要在博客頁面上點擊跳轉(zhuǎn),此時的 urllocalhost:8080/blog,需要變成 localhost:8080/blog/article,可以這樣做:

這樣就可以跳轉(zhuǎn)到 localhost:8080/blog/article 了,而且還傳遞了一個 number 參數(shù),在 article 中可以通過 this.props.params.number獲取。

HashRouter

當(dāng)我把項目托管到 Github Page 后,出現(xiàn)了這樣一個問題。

刷新頁面出現(xiàn) Cannot GET / 提示,路由未生效。

通過了解,知道了原因是這樣,并且可以解決:

由于刷新之后,會根據(jù)URL對服務(wù)器發(fā)送請求,而不是處理路由,導(dǎo)致出現(xiàn) Cannot GET / 錯誤。

通過修改

借助URL上的哈希值(hash)來實現(xiàn)路由??梢栽诓恍枰了⑿碌那闆r下,達到切換頁面的目的。

路由跳轉(zhuǎn)后不會自動回到頂部

當(dāng)前一個頁面滾動到一定區(qū)域后,點擊跳轉(zhuǎn)后,頁面雖然跳轉(zhuǎn)了,但是會停留在滾動的區(qū)域,不會自動回到頁面頂部。

可以通過這樣來解決:

componentDidMount() {
    this.node.scrollIntoView();
}

render() {
  return (
    
this.node = node} >
); }
狀態(tài)管理

項目中多次需要用到從 Github Issues 請求來的數(shù)據(jù),因為之前就知道 Redux 這個東西的存在,雖然有點大材小用,為了學(xué)習(xí)還是將它用于項目的狀態(tài)管理,只需要請求一次數(shù)據(jù)即可。

官方文檔:http://redux.js.org/

中文文檔:http://cn.redux.js.org/

簡單的來說,每一次的修改狀態(tài)都需要觸發(fā) action ,然而其實項目中我現(xiàn)在還沒用到修改數(shù)據(jù)2333。。。

關(guān)于狀態(tài)管理這一塊,由于還不是太了解,就不誤人子弟了~

主要組件

React是基于組件構(gòu)建的,所以在搭建頁面的開始,我們要先考慮一下我們需要一些什么樣的組件,這些組件之間有什么關(guān)系,哪些組件是可以復(fù)用的等等等。

首頁

可以看到,我主要將首頁分成了四個部分:

header:網(wǎng)站標(biāo)題,副標(biāo)題,導(dǎo)航欄

banner:about me ~,準(zhǔn)備用自己的照片換個背景,但是還沒有合適的照片

card area:暫時是三個卡片

blog card:最近的幾篇博文

demo card:幾個小demo類別

me card:算是我放飛自我的地方吧

footer:版權(quán)信息、備案信息、瀏覽量

博客頁

博客頁就是很中規(guī)中矩的一個頁面吧,這部分是整個項目中代碼量最多的部分,包括以下幾部分:

文章列表組件

翻頁組件

歸檔按鈕組件

類別組件

標(biāo)簽組件

文章列表

文章列表其實就是一個 list,里面有一個個的 item:

文章1
文章2

對于每一個 item,其實是這樣的:

一個文章item組件它可能需要包括:

文章標(biāo)題

文章發(fā)布的時間、類別、標(biāo)簽等

文章摘要

...

如果用 DOM 來描述,它應(yīng)該是這樣的:

文章標(biāo)題
時間
類別
標(biāo)簽
摘要

所以,我們可以有很多個組件:

文章列表組件

文章item組件

類別標(biāo)簽組件

它們可能是這樣一個關(guān)系:


  
    
    
    
    
  
  
  
分頁

對于分頁功能,傳統(tǒng)的實現(xiàn)方法是在后端完成分頁然后分批返回到前端的,比如可能會返回一段這樣的數(shù)據(jù):

{
  total:500,
  page:1,
  data:[]
}

也就是后端會返回分好頁的數(shù)據(jù),含有表示總數(shù)據(jù)量的total、當(dāng)前頁數(shù)的page,以及屬于該頁的數(shù)據(jù)data。

然而,我這個頁面只是個靜態(tài)頁面,數(shù)據(jù)是放在Github Issues上的通過API獲取的。(Github Issues的分頁貌似不能自定義數(shù)量...),所以沒法直接返回分好的數(shù)據(jù),所以只能在前端強行分頁~

分頁功能這一塊我偷懶了...用的是 antd 的翻頁組件 。

官方文檔:https://ant.design/components/pagination-cn/

文檔很清晰,使用起來也特別簡單。

前端渲染的邏輯(有點蠢):將數(shù)據(jù)存放到一個數(shù)組中,根據(jù)當(dāng)前頁數(shù)和每頁顯示條數(shù)來計算該顯示的索引值,取出相應(yīng)的數(shù)據(jù)即可。

翻頁組件中:

constructor() {
  super();
  this.onChangePage = this.onChangePage.bind(this);
}

onChangePage(pageNumber) {
  this.props.handlePageChange(pageNumber);
}

render() {
  return (
    
); }

當(dāng)頁數(shù)發(fā)生改變后,會觸發(fā)從父組件傳進 的方法 handlePageChange,從而將頁數(shù)傳遞到父組件中,然后傳遞到 中。

父組件中:

handlePageChange(pageNumber) {
  this.setState({ currentPage: pageNumber });
}

render() {
  return (
    
); }

列表中:

render() {
  const articlelist = [];
  const issues = this.props.issues;
  const currentPage = this.props.pageNumber;
  const defaultPageSize = this.props.defaultPageSize;
  const start = currentPage === 1 ? 0 : (currentPage - 1) * defaultPageSize;
  const end = start + defaultPageSize < issues.length ? start + defaultPageSize : issues.length;
  for (let i = start; i < end; i += 1) {
    const item = issues[i];
    articlelist.push();
  }
}
label

Github Issues 中,可以為一個 issue 添加很多個 label,我將這些對于博客內(nèi)容有用的 label 分為三類,分別用不同顏色來表示。

這里說明一下, label 創(chuàng)建后會隨機生成一個 id,雖然說 id 是不重復(fù)的,但是文章的類別、標(biāo)簽會一直在增加,當(dāng)新加一個 label 時,程序中可能也要進行對應(yīng)的修改,當(dāng)作區(qū)分 label 的標(biāo)準(zhǔn)可能就不太合適,所以我采用顏色來區(qū)分它們。

表示這是一篇文章的blog:只有有 blogissue 才能顯示在頁面上,過濾 bughelp

表示文章類別的:用來表示文章的類別,比如“前端”、“攝影”等

表示文章標(biāo)簽的:用來表示文章的標(biāo)簽,比如“JavaScript”、“React”等

即使有新的 label ,也只要根據(jù)顏色區(qū)分是屬于哪一類就好了。

類別

在這里的思路主要就是:遍歷所有 issues,然后再遍歷每個 issuelabels,找出屬于類別的 label,然后計數(shù)。

const categoryList = [];
const categoryHash = {};
for (let i = 0; i < issues.length; i += 1) {
  const labels = issues[i].labels;
  for (let j = 0; j < labels.length; j += 1) {
    if (labels[j].color === COLOR_LABEL_CATEGORY) {
      const category = labels[j].name;
      if (categoryHash[category] === undefined) {
        categoryHash[category] = true;
        const categoryTemp = { category, sum: 1 };
        categoryList.push(categoryTemp);
      } else {
        for (let k = 0; k < categoryList.length; k += 1) {
          if (categoryList[k].category === category) {
            categoryList[k].sum += 1;
          }
        }
      }
    }
  }
}

這樣實現(xiàn)得要經(jīng)歷三次循環(huán),復(fù)雜度有點高,感覺有點蠢,有待改進,如果有更好的方法,請多多指教~

標(biāo)簽

這里的思路和類別的思路基本一樣,只不過不同的顯示方式而已。

本來這里是想通過字體大小來體現(xiàn)每個標(biāo)簽的權(quán)重,后來覺得可能對于我來說,暫時只有那幾個標(biāo)簽會很頻繁,其它標(biāo)簽可能會很少,用字體大小來區(qū)分就沒有什么意義,還是改成排序的方式。

文章頁

文章頁主要分為兩部分:

文章內(nèi)容區(qū)域:顯示文章內(nèi)容,顯示在頁面的主體區(qū)域

章節(jié)目錄:文章的章節(jié)目錄,顯示在文章的右側(cè)區(qū)域

文章內(nèi)容

有兩種方式獲取文章具體內(nèi)容:

從之前已經(jīng)請求過的數(shù)組中去遍歷查找所需的文章內(nèi)容

通過 issue number 重新發(fā)一次請求直接獲取內(nèi)容

最后我選擇了后者。

文章是用 markdown 語法寫的,所以要先轉(zhuǎn)成 html 然后插入頁面中,這里用了一個 React 不提倡的屬性:dangerouslySetInnerHTML。

除了渲染markdown,我們還得對文章中的代碼進行高亮顯示,還有就是定制文章中不同標(biāo)簽的樣式。

章節(jié)目錄

首先,這里有一個 issue,希望大家可以給一些建議~

文章內(nèi)容是通過 markdown 渲染后插入 dom 中的,由于 React 不建議通過 document.getElementById 的形式獲取 dom 元素,所以只能想辦法通過字符串匹配的方式獲取文章的各個章節(jié)標(biāo)題。

由于我不太熟悉正則表達式,曾經(jīng)還在sf上咨詢過,就采用了其中一個答案:

const issues = content;
const menu = [];
const patt = /(#+)s+?(.+)/g;
let result = null;
while ((result = patt.exec(issues))) {
  menu.push({ level: result[1].length, title: result[2] });
}

這樣可以獲取到所有的 # 的字符串,也就是 markdown 中的標(biāo)題, result[1].length 表示有幾個 #,其實就是幾級標(biāo)題的意思,title 就是標(biāo)題內(nèi)容了。

這里還有一個問題,本來通過 的方式可以實現(xiàn)點擊跳轉(zhuǎn),但是現(xiàn)在渲染出來的 html 中對于每一個標(biāo)題沒有獨一無二的標(biāo)識。。。

歸檔頁

按年份歸檔:

按類別歸檔:

按標(biāo)簽歸檔:

問題

基本功能是已經(jīng)基本實現(xiàn)了,現(xiàn)在還存在著以下幾個問題,也算是一個 TodoList

評論功能。擬利用 Github Issues API 實現(xiàn)評論,得實現(xiàn) Github 授權(quán)登錄

回到頂部。擬利用 antd 的組件,但是 statevisibility 一直是 false

首頁渲染?,F(xiàn)在打包完的js文件還是太大了,導(dǎo)致首頁渲染太慢,這個是接下來工作的重點,也了解過關(guān)于這方面的優(yōu)化:

webpack 按需加載。這可能是目前最方便的方式

服務(wù)端渲染。這就麻煩了,但是好處也多,不僅解決渲染問題,還有利于SEO,所以也是 todo 之一

代碼混亂,邏輯不對。這是我自己的問題,需要再修煉。

原文地址:https://github.com/axuebin/react-blog/issues/17

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/88772.html

相關(guān)文章

  • 把手你用vue搭建個人

    摘要:在我轉(zhuǎn)前端以來,一直想要實現(xiàn)一個愿望自己搭建一個可以自動解析文檔的個人站今天終于實現(xiàn)啦,先貼上我的地址確認需求其實一個最簡單的個人站,就是許多的頁面,你只要可以用寫出來就可以,然后掛到上。 在我轉(zhuǎn)前端以來,一直想要實現(xiàn)一個愿望: 自己搭建一個可以自動解析Markdown文檔的個人站 今天終于實現(xiàn)啦,先貼上我的blog地址 確認需求 其實一個最簡單的個人站,就是許多的HTML頁面,你只要...

    xietao3 評論0 收藏0
  • 2017-07-10 前端日報

    摘要:前端日報精選入門指南入口,輸出,加載器和插件中數(shù)據(jù)類型轉(zhuǎn)換讓我印象深刻的面試題大話大前端時代一與的組件化庖丁解牛一發(fā)布中文第期手把手教你用管理狀態(tài)上個快速編程技巧眾成翻譯中執(zhí)行順序組件解耦之道眾成翻譯組件模型啟示錄有個梨作 2017-07-10 前端日報 精選 Webpack入門指南: 入口,輸出,加載器和插件JavaScript中數(shù)據(jù)類型轉(zhuǎn)換讓我印象深刻的javascript面試題大...

    Heier 評論0 收藏0
  • 把手你用 JavaScript 實現(xiàn)一個簡單國際象棋 AI

    摘要:實現(xiàn)這一功能最簡單的方法是計算棋盤上棋子的相對強度大小,用下面的對照表。本鏈接是基于算法優(yōu)化的國際象棋。我們來稍微調(diào)整一下棋盤上棋子狀態(tài)的權(quán)重,這一圖表是在國際象棋程序維基百科中給出的。 showImg(https://segmentfault.com/img/remote/1460000009143081?w=2000&h=1317); 本文作者: Lauri Hartikka 編...

    baihe 評論0 收藏0
  • 把手你用 JavaScript 實現(xiàn)一個簡單國際象棋 AI

    摘要:實現(xiàn)這一功能最簡單的方法是計算棋盤上棋子的相對強度大小,用下面的對照表。本鏈接是基于算法優(yōu)化的國際象棋。我們來稍微調(diào)整一下棋盤上棋子狀態(tài)的權(quán)重,這一圖表是在國際象棋程序維基百科中給出的。 showImg(https://segmentfault.com/img/remote/1460000009143081?w=2000&h=1317); 本文作者: Lauri Hartikka 編...

    NickZhou 評論0 收藏0
  • 把手你用es6+vue2+webpack2+vue-router2搭建個人blog

    摘要:更新日志更新完成靜態(tài)頁面原型修復(fù)使用的正確姿勢更新添加靜態(tài)頁面更新添加使用方法請戳我主要作用就是在你開發(fā)環(huán)節(jié)在后端同學(xué)還未開發(fā)完成的情況下,提供一個。 底下評論說是標(biāo)題黨,或者是光扔個github地址上來的同學(xué)我就不說什么了。你們有看看倉庫的提交記錄么?我還沒有吃撐到開個倉庫去騙star.我的出發(fā)點就是每天更新一部分代碼,教大家用我所提到的技術(shù)棧搭建一個blog,我的出發(fā)點就是這么簡單...

    weapon 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<