傳統(tǒng)Web前端
傳統(tǒng)編寫前端網(wǎng)頁大三大技術(shù)慰枕,HTML豆挽、CSS、JavaScript(以及以JavaScript為基礎(chǔ)所封裝的第三方庫爬立,比如:JQuery等)
HTML
HTML 是用來描述網(wǎng)頁的一種語言,超文本標(biāo)記語言 (Hyper Text Markup Language)堰乔;
標(biāo)記語言是一套標(biāo)記標(biāo)簽 偏化,HTML 使用標(biāo)記標(biāo)簽來描述網(wǎng)頁,構(gòu)建網(wǎng)頁的基本骨架浩考;
當(dāng)網(wǎng)頁被加載時夹孔,瀏覽器會創(chuàng)建頁面的文檔對象模型(Document Object Model)。
CSS
CSS 指層疊樣式表 (Cascading Style Sheets)析孽,定義顯示 HTML 元素的方式;
HTML 標(biāo)簽被設(shè)計為用于定義文檔內(nèi)容只怎。通過使用 <h1>袜瞬、<p>、<table> 這樣的標(biāo)簽身堡,HTML 的初衷是表達(dá)“這是標(biāo)題”邓尤、“這是段落”、“這是表格”之類的信息贴谎。最終由瀏覽器渲染到頁面汞扎,但是這些標(biāo)簽只能按默認(rèn)樣式,和流動布局的方式渲染擅这。
CSS則通過盒模型澈魄、選擇器、定位仲翎、層疊樣式等技術(shù)為網(wǎng)頁內(nèi)容添加格式
JavaScript
JavaScript 是輕量級的腳本語言痹扇,可插入 HTML 頁面,插入 HTML 頁面后溯香,可由所有的現(xiàn)代瀏覽器執(zhí)行鲫构。
JS能夠獲得頁面的文檔對象樹,從而獲得頁面中的DOM對象玫坛,再通過內(nèi)部封裝的函數(shù)來操作這些DOM對象结笨。
另外JS還封裝了關(guān)于HTTP請求和響應(yīng)的函數(shù),實現(xiàn)頁面發(fā)送和響應(yīng)HTTP請求
HTML+CSS+JavaScript
通過這三個技術(shù)就能實現(xiàn)前端頁面的內(nèi)容填充湿镀,樣式布局炕吸,交互響應(yīng)等所有內(nèi)容。項目中頁面就由page1.html肠骆、page1.css算途、page1.js三者組成。頁面的內(nèi)容是整體加載與渲染的蚀腿。
React組件化模式下的Web前端
React則另辟蹊徑提出了以組件化的形式重新構(gòu)建頁面內(nèi)容嘴瓤,所謂組件就是將頁面的內(nèi)容按特征分塊扫外,然后將特定塊中的HTML、CSS廓脆、JS封裝在一起筛谚,最后用組件來構(gòu)建頁面內(nèi)容。然而React不是一個完整的MVC停忿,它只是V驾讲,也就是視圖表現(xiàn),采用React搭建完整的頁面還需要其它技術(shù)支持:npm席赂、ES6吮铭、JSX、bable颅停、less谓晌、Router、Redux癞揉、WebPack
React
React 是一個采用聲明式纸肉,高效而且靈活的用來構(gòu)建用戶界面的框架。
(下面是個人理解的說法)
每一個React組件既是一個ES6對象喊熟,對象內(nèi)部可以有屬性和方法柏肪,從而更好的操作組件內(nèi)部的頁面元素。
React為了統(tǒng)一檢測變化芥牌,為每個React組件定義了兩個固定屬性烦味,prop和state,prop是react父組件在使用react組件時所傳入的屬性胳泉,是由外部賦值的拐叉,而state只能通過內(nèi)部的構(gòu)造函數(shù)和setState方法賦值和修改。
function Welcome(props) {
return <h1>Hello, {props.name}</h1>;
}
function App() {
return (
<div>
<Welcome name="Sara" />
<Welcome name="Cahal" />
<Welcome name="Edite" />
</div>
);
}
ReactDOM.render(
<App />,
document.getElementById('root')
);
例如:
class App extends Component {
constructor(props){
super(props);
this.onClickButton = this.onClickButton.bind(this);
this.state = {count : 0};
}
onClickButton(){
this.setState({
count : this.state.count + 1
});
}
render() {
return (
<div>
<button id="btn_click" type="button" onClick={this.onClickButton}>click me</button>
<span id="value">{this.state.count}</span>
</div>
);
}
}
而通過JQuery代碼則是:
<body>
<button id="btn_click" type="button" name="button">click me</button>
<span id="value">0</span>
<script src="./jquery-3.2.1.js" charset="utf-8"></script>
<script type="text/javascript">
$(function(){
$("#btn_click").click(function(event) {
/* Act on the event */
var clickCounter = $("#value");
var count = parseInt(clickCounter.text(),10);
clickCounter.text(count+1);
});
})
</script>
</body>
對比可以看出來傳統(tǒng)JQuery方式需要的到具體的DOM對象扇商,然后進(jìn)行操作凤瘦,而React組件方式只需要更改對象內(nèi)的state屬性,不需要操作DOM元素案铺。
npm
NPM(node package manager)蔬芥,通常稱為node包管理器。顧名思義控汉,它的主要功能就是管理node包笔诵,包括:安裝、卸載姑子、更新乎婿、查看、搜索街佑、發(fā)布等谢翎。
npm的背后捍靠,是基于couchdb的一個數(shù)據(jù)庫,詳細(xì)記錄了每個包的信息森逮,包括作者榨婆、版本、依賴褒侧、授權(quán)信息等良风。它的一個很重要的作用就是:將開發(fā)者從繁瑣的包管理工作(版本、依賴等)中解放出來闷供,更加專注于功能的開發(fā)烟央。
Node.js 就是運行在服務(wù)端的 JavaScript,是一個基于Chrome JavaScript 運行時建立的一個平臺歪脏,賦予了JavaScript很多面向?qū)ο笳Z言的特性
Node.js是一個事件驅(qū)動I/O服務(wù)端JavaScript環(huán)境吊档,基于Google的V8引擎,V8引擎執(zhí)行Javascript的速度非惩倥矗快,性能非常好鬼贱。
ES6移怯、JSX、bable
ES6即ECMAScript 2015这难,是 JavaScript 語言的下一代標(biāo)準(zhǔn)舟误,它和JavaScript的關(guān)系就是,JS是ES的一種實現(xiàn)姻乓。
ES6中有很多新的特性嵌溢,比如箭頭函數(shù)、匹配賦值等蹋岩,使的其更像是一門面向?qū)ο蟮恼Z言赖草。
目前主流的瀏覽器還不支持ES6,所以需要通過轉(zhuǎn)碼器將ES6轉(zhuǎn)為ES5剪个,bable就是目前主流的轉(zhuǎn)碼器
JSX就是Javascript和XML結(jié)合的一種格式秧骑。傳統(tǒng)的Web中HTML,CSS扣囊,JS一般是分開的乎折,便于管理,要想在HTML中嵌套JS和CSS需要特定格式侵歇,而JSX就等價于這種規(guī)則骂澄。React發(fā)明了JSX,利用HTML語法來創(chuàng)建虛擬DOM惕虑。當(dāng)遇到“</>”坟冲,JSX就當(dāng)HTML解析磨镶,遇到“{}”就當(dāng)JavaScript解析。
例如:
function Welcome(props) {
return <h1>Hello, {props.name}</h1>;
}
less或者Sass
Less (Leaner Style Sheets 的縮寫) 是一門向后兼容的 CSS 擴展語言樱衷。他豐富了css選擇器的種類棋嘲,使程序員能夠在css中定義變量,函數(shù)矩桂,減少了css編寫的代碼量沸移。同時他還支持選擇器之間的嵌套,這樣css更有邏輯侄榴,更易維護雹锣,也更符合React組件化的思想,我們可以將一個React組件顯得選擇器封裝在一個嵌套層中癞蚕,這樣邏輯更加清晰蕊爵。
@width: 10px;
@height: @width + 10px;
.bordered {
border-top: dotted 1px black;
border-bottom: solid 2px black;
}
#header {
color: black;
.bordered();
.navigation {
font-size: 12px;
}
.logo {
width: @width;
height: @height;
}
}
Router
前面講了React是組件化的開發(fā),小組件構(gòu)成大組件桦山,大組件構(gòu)成更大的組件攒射,整個網(wǎng)頁頁面也成了一個組件,那么怎么實現(xiàn)頁面的跳轉(zhuǎn)呢恒水?
傳統(tǒng)的web前端可以通過HTML文件的路徑來跳轉(zhuǎn)会放,而React中都是組件,那么就不能通過傳統(tǒng)的方式來跳轉(zhuǎn)了钉凌,這時候Router就來了咧最,他就是來解決這個問題的。
React Router 是一個基于 React 之上的強大路由庫御雕,它可以讓你向應(yīng)用中快速地添加視圖和數(shù)據(jù)流矢沿,同時保持頁面與 URL 間的同步。
import React from 'react'
import { render } from 'react-dom'
// 首先我們需要導(dǎo)入一些組件...
import { Router, Route, Link } from 'react-router'
const About = React.createClass({/*...*/})
// 新建一個組件讓其在 Inbox 內(nèi)部渲染
const Message = React.createClass({
render() {
return <h3>Message</h3>
}
})
const Inbox = React.createClass({
render() {
return (
<div>
<h2>Inbox</h2>
{/* 渲染這個 child 路由組件 */}
{this.props.children || "Welcome to your Inbox"}
</div>
)
}
})
// 然后我們從應(yīng)用中刪除一堆代碼和
// 增加一些 <Link> 元素...
const App = React.createClass({
render() {
return (
<div>
<h1>App</h1>
{/* 把 <a> 變成 <Link> */}
<ul>
<li><Link to="/about">About</Link></li>
<li><Link to="/inbox">Inbox</Link></li>
</ul>
{/*
接著用 `this.props.children` 替換 `<Child>`
router 會幫我們找到這個 children
*/}
{this.props.children}
</div>
)
}
})
// 最后酸纲,我們用一些 <Route> 來渲染 <Router>捣鲸。
// 這些就是路由提供的我們想要的東西。
React.render((
<Router>
<Route path="/" component={App}>
<Route path="about" component={About} />
<Route path="inbox" component={Inbox}>
{/* 添加一個路由福青,嵌套進(jìn)我們想要嵌套的 UI 里 */}
<Route path="messages/:id" component={Message} />
</Route>
</Route>
</Router>
), document.body)
Router還提供了<Link/>等組件方便使用摄狱,具體參考官方文檔
Redux
Redux本不是為了方便React而出現(xiàn)的,React項目中也可以不使用Redux无午,相反在小項目中使用Redux反而會增加項目的復(fù)雜度媒役。但是在大型前端項目中,Redux則能夠很好地管理網(wǎng)站中的狀態(tài)宪迟。
Redux 是 JavaScript 狀態(tài)容器酣衷,提供可預(yù)測化的狀態(tài)管理。隨著 JavaScript 單頁應(yīng)用開發(fā)日趨復(fù)雜次泽,JavaScript 需要管理比任何時候都要多的 state (狀態(tài))穿仪。 這些 state 可能包括服務(wù)器響應(yīng)席爽、緩存數(shù)據(jù)、本地生成尚未持久化到服務(wù)器的數(shù)據(jù)啊片,也包括 UI 狀態(tài)只锻,如激活的路由,被選中的標(biāo)簽紫谷,是否顯示加載動效或者分頁器等等齐饮。
管理不斷變化的 state 非常困難。如果一個 model 的變化會引起另一個 model 變化笤昨,那么當(dāng) view 變化時祖驱,就可能引起對應(yīng) model 以及另一個 model 的變化,依次地瞒窒,可能會引起另一個 view 的變化捺僻。直至你搞不清楚到底發(fā)生了什么。state 在什么時候崇裁,由于什么原因匕坯,如何變化已然不受控制。 當(dāng)系統(tǒng)變得錯綜復(fù)雜的時候拔稳,想重現(xiàn)問題或者添加新功能就會變得舉步維艱醒颖。
Redux將所有的state構(gòu)建為state樹,保存到一個對象中壳炎;將所有可能的行為封裝到action中,然后編寫reducer函數(shù)分別處理action逼侦,根據(jù)action的種類來更改state從而實現(xiàn)state的管理和控制匿辩。這就是Redux的核心思想。
webpack
Webpack的工作方式是:把你的項目當(dāng)做一個整體榛丢,通過一個給定的主文件(如:index.js)铲球,Webpack將從這個文件開始找到你的項目的所有依賴文件,使用loaders處理它們晰赞,最后打包為一個(或多個)瀏覽器可識別的JavaScript文件稼病。