一、Node.js
Node.js并不是一個JavaScript框架获印,Node.js是JavaScript運行時的運行環(huán)境述雾,類比Java中的JVM。
java的開端是什么兼丰,無疑是JVM玻孟,自從有了JVM,java才能吹牛說自己是“一次編寫處處運行”鳍征,不管你是windows還是linux黍翎,只要安裝了對應版本的JVM都可以運行.class文件。
同樣Node.js的作用和JVM的一樣一樣的艳丛,也是js的運行環(huán)境匣掸,不管是你是什么操作系統(tǒng),只要安裝對應版本的Node.js氮双,那你就可以用js來開發(fā)后臺程序旺聚。這具有劃時代的意義正林,意味著一直以來只能在瀏覽器上玩來玩去的js鼻听,可以做后端開發(fā)了遂蛀。
從有了Node.js后就催生出一大批用js做后臺開發(fā)的前端人員古胆,這部分人員就是偏前端的“全棧程序員”绳矩。記住十偶,Node.js是和JVM同等地位的js運行環(huán)境学歧,打開了前端人員走向后端的道路勾效。
二饭入、React介紹
React設計思想及其獨特嵌器,屬于革命性創(chuàng)新,性能出眾谐丢,代碼邏輯卻非常簡單爽航。
庫(library):小而巧蚓让,庫只提供了特定的api。優(yōu)點是船小好調(diào)頭讥珍,可以很方便的從一個庫切換到另外的庫历极,但是代碼幾乎不會改變。
框架(Framework):大而全衷佃,框架提供了一整套的解決方案趟卸。所以,如果在項目中間氏义,想切換到另外的框架是比較困難的锄列。
和Angular1相比,React設計很優(yōu)秀惯悠,一切基于JS并且實現(xiàn)了組件化開發(fā)的思想
React提供了無縫轉(zhuǎn)到ReactNative上的開發(fā)體驗邻邮。
1.React與Vue的對比
(1)組件化方面
什么是模塊化:是從代碼的角度來進行分析的;把一些可復用的代碼克婶,抽離為單個的模塊饶囚,便于項目的維護和開發(fā)。
什么是組件化:是用UI界面的角度來進行分析的鸠补;把一些可復用的UI元素萝风,抽離為單獨的組件,便于項目的維護和開發(fā)紫岩。
組件化的好處:隨著項目規(guī)模的增大规惰,手里的組件越來越多,很方便就可以把現(xiàn)有的組件泉蝌,拼接成一個完整的頁面歇万。
-
Vue是如何實現(xiàn)組件化的:通過.vue文件,來創(chuàng)建對應的組件:
- template 結(jié)構(gòu)
- script 行為
- style 樣式
React是如何實現(xiàn)組件化的:React中有組件化的概念勋陪,但是并沒有像Vue這樣的組件模板文件贪磺;React中,一切都是以JS來表現(xiàn)的诅愚。因此要學習React寒锚,JS要合格,ES6和ES7(async和await)要會用
(2)移動APP開發(fā)體驗方面
Vue违孝,結(jié)合Weex這門技術(shù)刹前,提供了遷移到移動端APP開發(fā)的體驗(Weex目前只是一個小的玩具,并沒有很成功的大案例雌桑,主要是阿里系的應用在使用)
React喇喉,結(jié)合ReactNative,也提供了無縫遷移到移動APP的開發(fā)體驗(RN用的最多校坑,也是最火最流行的)
2.React中的幾個核心概念
(1)虛擬DOM
DOM本質(zhì)是什么:瀏覽器中的概念拣技,用JS對象來表示頁面上的元素千诬,并提供了操作DOM對象的api(瀏覽器提供的)
什么是React中的虛擬DOM:是框架中的概念,手動用JS對象來模擬頁面上的DOM元素和DOM的嵌套關(guān)系(框架提供的)
為什么要實現(xiàn)虛擬DOM(虛擬DOM的目的):為了實現(xiàn)頁面中膏斤,DOM元素的高效更新徐绑。
DOM樹的概念: 一個網(wǎng)頁呈現(xiàn)的過程: 1、瀏覽器請求服務器獲取頁面HTML代碼 2掸绞、瀏覽器要先在內(nèi)存中解析DOM結(jié)構(gòu),并在瀏覽器內(nèi)存中耕捞,渲染出一顆DOM樹 3衔掸、瀏覽器把DOM樹,呈現(xiàn)到頁面上
總結(jié):什么是虛擬DOM俺抽?
本質(zhì):用JS對象的形式敞映,來模擬頁面上DOM元素和嵌套關(guān)系(虛擬DOM是以JS對象的形式存在的) 目的:實現(xiàn)DOM元素的高效更新
(2)Diff算法
tree diff:新舊兩顆DOM樹,逐層對比的過程磷斧,就是Tree Diff振愿;當整顆DOM逐層對比完畢,則所有需要被按需更新的元素弛饭,必然能夠找到
component diff:在進行tree diff的時候冕末,每一層中,組件級別的對比侣颂,叫作component diff档桃;
如果對比前后,組件的類型相同憔晒,則暫時認為此組件不需要被更新藻肄;
如果對比前后,組件類型不同拒担,則需要移除舊組件嘹屯,創(chuàng)建新組件,并追加到頁面上从撼;
element diff:在進行組件對比的時候州弟,如果兩個組件類型相同,則需要進行元素級別的對比低零,這叫作element diff呆馁;
3.構(gòu)建基本的webpack4.x項目
因為webpack是基于Node構(gòu)建的,所以webpack支持所有Node的api和語法
在webpack4.x中毁兆,有一個很大的特性浙滤,就是約定大于配置 約定的默認打包入口是/src/index.js
-
構(gòu)建步驟
1、運行npm init -y快速初始化項目
2气堕、在項目根目錄創(chuàng)建src源代碼目錄和dist產(chǎn)品目錄
3纺腊、使用cnpm安裝webpack畔咧,運行cnpm install webpack -D以及cnpm install webpack-cli -D
4、Webpack4.x提供了約定大于配置的概念揖膜,目的是為了減少配置文件的體積誓沸;默認約定的 打包的入口是/src/index.js;打包的輸出文件是/dist/main.js
5壹粟、Webpack4.x 新增了mode選項(必填項)拜隧,可選值為development和production
6、為了方便運行趁仙,配置實時打包編譯工具->webpack-dev-server洪添。 cnpm install webpack-dev-server -D
7、Webpack-dev-server打包好的main.js是托管到了內(nèi)存中雀费,在項目根目錄的物理磁盤中看不到干奢;但是我們可以認為,在項目根目錄中盏袄,有一個看不見的mian.js
8忿峻、Webpack-dev-server打包后打開的首頁是項目根目錄,而不是src目錄下的index.html辕羽。 為了讓打包編譯后的網(wǎng)頁自動打開index.html逛尚,就需要用到HtmlWebpackPlugin插件,來在項目根目錄下生成index.html刁愿。安裝并在webpack.config.js的module.exports中配置plugins黑低。
4.在項目中使用React
(1)什么是React和React-dom
React:專門用來創(chuàng)建組件和虛擬DOM的,同時組件的生命周期都在這個包中
React-dom:專門進行DOM操作的酌毡,最主要的應用場景就是ReactDOM.render()
(2)React創(chuàng)建虛擬DOM元素
在JS文件中克握,默認不能寫HTML的標簽,否則會打包失敗枷踏。這個時候需要使用babel來轉(zhuǎn)換這些JS中的標簽
注意菩暗,在JS中混合寫入類似于HTML的語法,叫作JSX的語法(符合XML規(guī)范的JS)
SX語法的本質(zhì)旭蠕,還是在運行的時候停团,被轉(zhuǎn)換成了React.createElement的形式來執(zhí)行的(通過babel轉(zhuǎn)換)
-
配置babel的步驟
安裝所需的bebel包
在webpack.config.js中配置babel,將babel配置在第三方匹配規(guī)則中(module下的rules中)
在項目根目錄中編寫babel的配置文件->.babelrc掏熬,這是一個json的配置文件佑稠,所以要符合json語法規(guī)則。
在.babelrc中配置babel用到的語法規(guī)則和插件
當要在JSX代碼中使用JS表達式時旗芬,需要用大括號{}將JS表達式框起來
5.React中創(chuàng)建組件
(1)第一種創(chuàng)建組件的方式
使用構(gòu)造函數(shù)來創(chuàng)建組件舌胶,如果要接收外界傳遞的數(shù)據(jù),需要在構(gòu)造函數(shù)的參數(shù)列表中使用props來接收疮丛;必須要向外return一個合法的JSX的虛擬DOM幔嫂。
- 創(chuàng)建組件
//第一種創(chuàng)建組件的方式
function Hello(props) {
//如果在一個組件中 return 一個 null辆它。則表示此組件是空的,什么都不會渲染
// return null
//在組件中履恩,必須返回一個合法的JSX虛擬DOM元素
return <div>這是 Hello 組件 --- {props.name} --- {props.age} --- {props.gender}</div>
//無論是vue還是React锰茉,組件中的props永遠都是只讀的,不能被重新賦值
}
- 為組件傳遞數(shù)據(jù)
ReactDOM.render(
<div>
{/*直接把創(chuàng)建的組件名稱切心,以標簽的形式飒筑,丟到頁面上即可*/}
<Hello name={dog.name} age={dog.age}
gender={dog.gender}></Hello>
</div>
, document.getElementById('parent'))
-
this.props對象的屬性
1、 history:用來跳轉(zhuǎn)路由 路徑
2.绽昏、Match:匹配結(jié)果协屡,如果匹配上就是對象,匹配不上就是null
3而涉、Location:當前路徑 pathname當前路徑名
父組件向子組件傳遞數(shù)據(jù)
使用{...obj}屬性擴散傳遞數(shù)據(jù)
將組件封裝到單獨的文件中
注意:組件的名稱首字母必須是大寫
如何省略.jsx后綴名
//打開webpack.config.js著瓶,并在導出的配置對象中联予,新增如下節(jié)點
resolve: {
extensions: [
'.js', '.jsx', '.json'
]//表示這幾個文件的后綴名啼县,可以省略不寫(.js和.json是默認有的)
}
- 設置別名 resolve: {
//alias:別名;這里設置別名是為了讓后續(xù)引用的地方減少路徑的復雜度
alias: {
'@': path.join(__dirname, './src')
}
}
(2)第二種創(chuàng)建組件的方式
使用class關(guān)鍵字來創(chuàng)建組件
通過extends繼承React.Component
每一個類中沸久,都有一個構(gòu)造器季眷,如果我們沒有手動指定構(gòu)造器,那么卷胯,可以認為類內(nèi)部有個隱形的子刮,看不見的空構(gòu)造器,類似于constructor(){}
構(gòu)造器的作用就是窑睁,每當new這個類的時候挺峡,必然會 優(yōu)先執(zhí)行,構(gòu)造器中的代碼担钮。
通過 new出來的實例 訪問到的屬性橱赠,叫作實例屬性。構(gòu)造器中的屬性箫津,是實例屬性狭姨。
通過 構(gòu)造函數(shù) 直接訪問到的屬性,叫作靜態(tài)屬性苏遥。在class中通過static關(guān)鍵字定義的屬性是靜態(tài)屬性饼拍。
實例方法,通過 new出來的實例 訪問到的方法田炭,實際項目中使用較多
靜態(tài)方法师抄,通過 構(gòu)造函數(shù) 直接訪問到的方法,實際項目中使用到的不多教硫。在class中通過static關(guān)鍵字定義的方法
注意:在class的{ }區(qū)間內(nèi)司澎,只能寫 構(gòu)造器欺缘、靜態(tài)方法、靜態(tài)屬性和實例方法
注意:class關(guān)鍵字內(nèi)部還是通過function的方式來實現(xiàn)的挤安。所以說谚殊,我們把class關(guān)鍵字,稱作 語法糖
通過extends關(guān)鍵字來實現(xiàn)繼承蛤铜,將共有的某些屬性或方法放到父類中
在class關(guān)鍵字創(chuàng)建的組件中嫩絮,如果想使用外界傳遞過來的props參數(shù),不需接收围肥,直接通過this.props.****來訪問即可
ES6的展開運算符【...】可以展開一個對象
(3)兩種創(chuàng)建組件的方式的對比
使用class關(guān)鍵字創(chuàng)建的組件剿干,有自己的私有數(shù)據(jù)(this.state)和聲明周期函數(shù),但是使用function創(chuàng)建的組件穆刻,只有props置尔,沒有自己的私有數(shù)據(jù)和生命周期函數(shù)
用構(gòu)造函數(shù)創(chuàng)建出來的組件,叫作‘無狀態(tài)組件’【無狀態(tài)組件今后用得不多】
用class關(guān)鍵字創(chuàng)建出來的組件氢伟,叫作‘有狀態(tài)組件’【今后用的最多】
有狀態(tài)組件和無狀態(tài)組件之間的本質(zhì)區(qū)別就是:有無state屬性榜轿,和有無生命周期函數(shù)
-
什么情況下使用有狀態(tài)組件?什么情況下使用無狀態(tài)組件朵锣?
1谬盐、如果一個組件需要自己的私有數(shù)據(jù),則推薦使用:class創(chuàng)建的有狀態(tài)組件
2诚些、如果一個組件不需要私有的數(shù)據(jù)飞傀,則推薦使用:無狀態(tài)組件
3、React官方:無狀態(tài)組件由于沒有自己的state和聲明周期函數(shù)诬烹,所以運行效率會比有狀態(tài)組件稍微高一些
-
組件中的props和state/data之間的區(qū)別
1砸烦、props中的數(shù)據(jù)都是外界傳遞過來的
2、state/data中的數(shù)據(jù)绞吁,都是組件私有的幢痘;(通過Ajax獲取回來的數(shù)據(jù),一般都是私有數(shù)據(jù))
3掀泳、 props中的數(shù)據(jù)都是只讀的雪隧,不能重新賦值
4、state/data中的數(shù)據(jù)员舵,都是可讀可寫的
6.React-router
-
組件的this.props對象的屬性
1脑沿、history:用來跳轉(zhuǎn)路由 路徑
2、Match:匹配結(jié)果马僻,如果匹配上就是對象庄拇,匹配不上就是null
3、Location:當前路徑 pathname當前路徑名
安裝路由:cnpm install react-router-dom -S
-
HashRouter
1、什么叫 hash 地址措近,hash 地址就是指 # 號后面的 url
2溶弟、假如有一個 Link 標簽,點擊后跳轉(zhuǎn)到 /abc/def瞭郑。
BrowserRouter: http://localhost:8080/abc/def
HashRouter: [<u>http://localhost:8080/#/abc/def</u>](http://localhost:8080/#/abc/def)
如果有服務器端的動態(tài)支持辜御,建議使用 BrowserRouter,否則建議使用 HashRouter屈张。
原因在于擒权,如果是單純的靜態(tài)文件,假如路徑從 / 切換到 /a 后阁谆,此時刷新頁面碳抄,頁面將無法正常訪問,需要在服務器端進行相關(guān)配置Switch:只渲染一個匹配到的<路由組件>或<重定向組件>