React學(xué)習(xí)筆記一--基本概念和webpack項(xiàng)目配置

ReactJS簡(jiǎn)介
  • React 起源于 Facebook 的內(nèi)部項(xiàng)目,因?yàn)樵摴緦?duì)市場(chǎng)上所有 JavaScript MVC(Model View Controller) 框架都不滿意,就決定自己寫一套,用來(lái)架設(shè) Instagram 的網(wǎng)站。做出來(lái)以后,發(fā)現(xiàn)這套東西很好用,就在2013年5月開(kāi)源了。
  • 由于 React 的設(shè)計(jì)思想極其獨(dú)特,屬于革命性創(chuàng)新,性能出眾,代碼邏輯卻非常簡(jiǎn)單。所以,越來(lái)越多的人開(kāi)始關(guān)注和使用,認(rèn)為它可能是將來(lái) Web 開(kāi)發(fā)的主流工具。
庫(kù)(library)和框架(FrameWork):

庫(kù):小而輕巧,只提供特定Api;優(yōu)點(diǎn)是船小好調(diào)頭,可以很方便地從一個(gè)庫(kù)切換到另一個(gè)庫(kù)(如jQuery到Zepto),代碼幾乎不需要怎么改動(dòng)。
框架:大而全,提供一整套解決方案。項(xiàng)目從一個(gè)框架切換到另一個(gè)是比較困難的。

三大主流框架

Angluar:最早(出來(lái)得最早),在印度用得比較多

  • 出來(lái)最早的前端框架,學(xué)習(xí)曲線比較陡,NG1學(xué)起來(lái)比較麻煩,NG2開(kāi)始,進(jìn)行了一系列的改革,也開(kāi)始啟用組件化了;在NG中,也支持使用TS(TypeScript)進(jìn)行編程;

Vue:最火(關(guān)注的人多),在中國(guó)用得比較多。對(duì)我我們來(lái)說(shuō),文檔要友好一些。
React:最流行(用的人多)在國(guó)外用得比較多,因?yàn)樗脑O(shè)計(jì)很優(yōu)秀。

React和Vue的對(duì)比

組件化方面:

  1. 什么是模塊化:是從代碼的角度來(lái)進(jìn)行分析的;把編程時(shí)候的業(yè)務(wù)邏輯,分割抽離到不同的模塊中來(lái)進(jìn)行開(kāi)發(fā),這樣能夠方便代碼的重用,便于項(xiàng)目的維護(hù)和開(kāi)發(fā);
  2. 什么是組件化: 是從 UI 界面的角度來(lái)進(jìn)行分析的;把一些可復(fù)用的UI元素,抽離為單獨(dú)的組件;隨著我們項(xiàng)目的開(kāi)發(fā),我們手里的組件會(huì)越來(lái)越多,到后面我們?nèi)绻獙?shí)現(xiàn)一個(gè)頁(yè)面,可能直接把現(xiàn)有的組件拿過(guò)來(lái)進(jìn)行拼接,就能快速得到一個(gè)完整的頁(yè)面, 這樣方便了UI元素的重用;組件是元素的集合體;
  3. 組件化的好處:隨著項(xiàng)目規(guī)模的增大,手里的組件越來(lái)越多;很方便就能把現(xiàn)有的組件,拼接為一個(gè)完整的頁(yè)面;
  4. Vue是如何實(shí)現(xiàn)組件化的: 通過(guò) .vue 文件,來(lái)創(chuàng)建對(duì)應(yīng)的組件,一個(gè)包含以下三個(gè)部分;
    • template 結(jié)構(gòu)
    • script 行為
    • style 樣式
      導(dǎo)入使用: import Home from './Home.vue'
      瀏覽器不識(shí)別這樣的.vue文件,所以在運(yùn)行前,會(huì)把 .vue 預(yù)先編譯成真正的組件;
  5. React如何實(shí)現(xiàn)組件化:React實(shí)現(xiàn)組件化的時(shí)候,并沒(méi)有像.vue這樣的組件模板文件;而是直接使用JS代碼的形式,去創(chuàng)建任何你想要的組件。
  • React全部使用JS來(lái)實(shí)現(xiàn)一個(gè)組件,也就是說(shuō):結(jié)構(gòu)、樣式、業(yè)務(wù)邏輯是混合在JS里面一起編寫出來(lái)的。
  • 要學(xué)習(xí)React,JS要合格;ES6 和 ES7 (async 和 await) 要會(huì)用
移動(dòng)APP開(kāi)發(fā)體驗(yàn)比較:
  • Vue,結(jié)合 Weex 這門技術(shù),提供了遷移到移動(dòng)端App開(kāi)發(fā)的體驗(yàn)(Weex,目前只是一個(gè)小的玩具, 并沒(méi)有很成功的大案例;都是阿里自己的項(xiàng)目在用)
  • React,結(jié)合 ReactNative,也提供了無(wú)縫遷移到移動(dòng)App的開(kāi)發(fā)體驗(yàn)(RN用的最多,也是最火最流行的,大公司用得多);
為什么要學(xué)習(xí)React
  1. 和Angular1相比,React設(shè)計(jì)很優(yōu)秀,一切基于JS并且基于組件化開(kāi)發(fā)的思想;
  2. 開(kāi)發(fā)團(tuán)隊(duì)實(shí)力強(qiáng)悍,不必?fù)?dān)心斷更的情況;
  3. 社區(qū)強(qiáng)大,很多問(wèn)題都能找到對(duì)應(yīng)的解決方案;
  4. 提供了無(wú)縫轉(zhuǎn)到 ReactNative 上的開(kāi)發(fā)體驗(yàn),讓我們技術(shù)能力得到了拓展;增強(qiáng)了我們的核心競(jìng)爭(zhēng)力;
  5. 很多企業(yè)中,前端項(xiàng)目的技術(shù)選型采用的是React.js
React中幾個(gè)核心的概念
虛擬DOM(Virtual Document Object Model)
  • DOM的本質(zhì)是什么:就是用JS表示的UI元素。瀏覽器中的概念,用JS對(duì)象來(lái)表示頁(yè)面上的UI元素,并提供了操作 DOM 對(duì)象的API;
  • 什么是React中的虛擬DOM:是框架中的概念,是程序員用JS對(duì)象來(lái)模擬頁(yè)面上的 DOM 和 DOM嵌套;
  • 為什么要實(shí)現(xiàn)虛擬DOM(虛擬DOM的目的):為了實(shí)現(xiàn)頁(yè)面中, DOM 元素的高效更新
  • DOM和虛擬DOM的區(qū)別
    • DOM:由瀏覽器中的JS提供功能,所以我們只能人為的使用瀏覽器提供的固定的API來(lái)操作DOM對(duì)象;
    • 虛擬DOM:是框架中的概念,不是由瀏覽器提供的,而是程序員手動(dòng)模擬實(shí)現(xiàn)的,類似于瀏覽器中的DOM,但是有著本質(zhì)的區(qū)別。
      • 本質(zhì): 用JS對(duì)象,來(lái)模擬DOM元素和嵌套關(guān)系;
      • 目的:就是為了實(shí)現(xiàn)頁(yè)面元素的高效更新;


        虛擬DOM的概念

Diff算法

  • tree diff:新舊兩棵DOM樹(shù),逐層對(duì)比的過(guò)程,就是Tree Diff; 每當(dāng)我們從前到后,把整顆DOM逐層的節(jié)點(diǎn)對(duì)比完畢,必然能夠找到所有需要被按需更新的元素;
  • component diff:在進(jìn)行Tree Diff的時(shí)候,每一層中,組件級(jí)別的對(duì)比,叫做 Component Diff;當(dāng)對(duì)比組件的時(shí)候,如果兩個(gè)組件的類型相同,則暫時(shí)認(rèn)為這個(gè)組件不需要被更新,如果組件的類型不同,則立即將舊組件移除,新建一個(gè)組件,替換到被移除的位置;
  • element diff:在進(jìn)行組件對(duì)比的時(shí)候,如果兩個(gè)組件類型相同,則需要進(jìn)行元素級(jí)別的對(duì)比,如果元素內(nèi)容不同,則進(jìn)行相應(yīng)的替換修改;
    -key:key這個(gè)屬性,可以把 頁(yè)面上的 DOM節(jié)點(diǎn) 和 虛擬DOM中的對(duì)象,做一層關(guān)聯(lián)關(guān)系;
    Diff算法圖
創(chuàng)建基本的webpack4.x項(xiàng)目
  1. 運(yùn)行npm init -y 快速初始化項(xiàng)目
  2. 在項(xiàng)目根目錄創(chuàng)建src源代碼目錄和dist產(chǎn)品目錄(發(fā)布的產(chǎn)品所在目錄)
  3. 在 src 目錄下創(chuàng)建 index.html
  4. 使用 cnpm 安裝 webpack ,運(yùn)行cnpm i webpack -Dcnpm i webpack-cli -D(開(kāi)發(fā)依賴)
    • 如何安裝 cnpm: 全局運(yùn)行 npm i cnpm -g
  5. webpack.config.js配置:webpack 4.x 提供了 約定大于配置的概念;目的是為了盡量減少配置文件的體積;
    • 默認(rèn)約定了:打包的入口是src -> index.js(新建一個(gè)index.js)
    • 打包的輸出文件是dist -> main.js
    • 4.x 中 新增了 mode 選項(xiàng)(必選項(xiàng)),可選的值為:developmentproduction; production模式會(huì)壓縮打包文件的格式。如果另外寫了配置,如指定entry:''(入口路徑),那么就會(huì)覆蓋默認(rèn)的約定
  6. 執(zhí)行打包webpack,注意,如果執(zhí)行后報(bào)了Cannot find module 'webpack-cli'的提示,說(shuō)明需要全局安裝webpack-cli,命令行運(yùn)行npm i webpack-cli -g
  7. 打包完畢后dist下自動(dòng)生成了打包文件main.js,將它手動(dòng)引入到index.html中<script src="../dist/main.js"></script>
  8. 安裝webpack-dev-server,npm i webpack-dev-server -D,快速搭建本地運(yùn)行環(huán)境的工具。執(zhí)行它的命令即是webpack-dev-server,在package.json里做了如下配置后,可直接執(zhí)行npm run dev來(lái)替代
"scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "dev": "webpack-dev-server"
  },

9.重新配置打包文件路徑,webpack-dev-server會(huì)幫助我們自動(dòng)編譯
webpack-dev-server打包好的main.js托管到了內(nèi)存中,所在在項(xiàng)目根目錄中看不到;出于性能上的考慮,不用反復(fù)讀取物理磁盤
但是我們可以認(rèn)為,在項(xiàng)目根目錄中,有一個(gè)不可見(jiàn)的main.js,然后直接在index.html中引入<script src="/main.js"></script>

執(zhí)行入口文件自動(dòng)編譯

webpack-dev-server幾個(gè)配置項(xiàng):
  • --open是重新編譯后自動(dòng)打開(kāi)瀏覽器 --open firefox(瀏覽器名稱) 則自動(dòng)用火狐瀏覽器打開(kāi)
  • --port 3000 是自定義端口
  • --hot 熱更新
  • --host 127.0.0.1 指定域名
  • --progress 顯示打包的進(jìn)度
  • --compress 開(kāi)啟gzip壓縮
"dev": "webpack-dev-server --open --port 3000 --hot --host 127.0.0.1 --progress --compress"

配置完執(zhí)行npm run dev,會(huì)用chorme自動(dòng)打開(kāi)http://127.0.0.1:3000/(注意:cnpm只能用來(lái)安裝包,其他操作都需要用npm來(lái)執(zhí)行)

  1. 安裝html-webpack-plugin來(lái)把頁(yè)面托管生成到內(nèi)存中 npm i html-webpack-plugin -D
    在webpack-config.js中配置:
const path = require('path')
const HtmlWebPackPlugin = require('html-webpack-plugin');//導(dǎo)入在內(nèi)存中自動(dòng)生成index頁(yè)面的插件

//創(chuàng)建一個(gè)html-webpack-plugin插件的實(shí)例對(duì)象
const htmlPlugin = new HtmlWebPackPlugin({
    template: path.join(__dirname,'./src/index.html'),//源文件
    filename: 'index.html' //生成在內(nèi)存中首頁(yè)的名字
})

module.exports = {
    mode:'development',//development production
    plugins:[
        htmlPlugin
    ]
}

運(yùn)行后就打開(kāi)的http://127.0.0.1:3000/就顯示index.html的內(nèi)容了

在項(xiàng)目中使用 react
  1. 運(yùn)行 cnpm i react react-dom -S 安裝包(生產(chǎn)依賴)
    • react: 專門用于創(chuàng)建組件和虛擬DOM的,同時(shí)組件的生命周期都在這個(gè)包中
    • react-dom: 專門進(jìn)行DOM操作的,最主要的應(yīng)用場(chǎng)景,就是ReactDOM.render()
  2. index.html頁(yè)面中,創(chuàng)建容器:
<!--創(chuàng)建一個(gè)容器,將來(lái)用來(lái)渲染的虛擬DOM,將放到這個(gè)容器內(nèi)顯示-->
<div id="app"></div>
  1. index.js中,導(dǎo)入包:
import React from 'react'
import ReactDOM from 'react-dom'
  1. 創(chuàng)建虛擬DOM元素:
// 這是 創(chuàng)建虛擬DOM元素的 API    <h1 title="啊,五環(huán)" id="myh1">你比四環(huán)多一環(huán)</h1>
//參數(shù)1:創(chuàng)建的元素類型,格式為字符串,表示元素的名稱
//參數(shù)2:是一個(gè)對(duì)象或null,表示當(dāng)前這個(gè)DOM元素的屬性
//參數(shù)3:子節(jié)點(diǎn)(包括其他虛擬DOM 或 文本子節(jié)點(diǎn))
//參數(shù)n:其他子節(jié)點(diǎn),即多個(gè)子節(jié)點(diǎn)就一直往后排,用‘,’隔開(kāi)
const myh1 = React.createElement('h1', { title: '啊,五環(huán)', id: 'myh1' }, '你比四環(huán)多一環(huán)')
  1. 渲染:
// 使用ReactDOM把虛擬DOM渲染到頁(yè)面上
//參數(shù)1:要渲染的虛擬DOM元素(React.createElement創(chuàng)建出來(lái)的)
//參數(shù)2:指定渲染到頁(yè)面上哪個(gè)容器,是DOM元素而不是選擇器,因此這里不能直接放容器元素的Id字符串,需要放一個(gè)容器的DOM對(duì)象
ReactDOM.render(myh1, document.getElementById('app'))

8. JSX語(yǔ)法

什么是JSX語(yǔ)法:就是符合 xml 規(guī)范的 JS 語(yǔ)法;(語(yǔ)法格式相對(duì)來(lái)說(shuō),要比HTML嚴(yán)謹(jǐn)很多)

  1. 如何啟用 jsx 語(yǔ)法?

    • 安裝 babel 插件

      • 運(yùn)行npm i babel-loaderbabel-loader:負(fù)責(zé)轉(zhuǎn)換
        npm i @babel/core -D
        npm i @babel/plugin-proposal-object-rest-spread -D
        npm i @babel/plugin-transform-runtime -D
        npm i @babel/runtime -S
        注意:這邊有個(gè)版本對(duì)應(yīng)問(wèn)題,否則npm run dev后會(huì)失敗
        現(xiàn)在最新的babel-loader 是8.x版本的,要使用@babel/core,而不是babel-core了。而babel-loader 7.x對(duì)應(yīng)安裝babel-core 6.x。
        下面同理:
    • 安裝能夠識(shí)別轉(zhuǎn)換jsx語(yǔ)法的包npm i @babel/preset-react -D

    • 根目錄下添加 .babelrc 配置文件

      {
        "presets": ["@babel/preset-env", "@babel/preset-react", "mobx"],
        "plugins": [
             "@babel/plugin-proposal-object-rest-spread",
             "@babel/plugin-transform-runtime"
         ]
      }
      
    • 添加babel-loader配置項(xiàng):

      module: { //要打包的第三方模塊
          rules: [
            //{ test: /\.js|jsx$/, use: 'babel-loader', exclude: /node_modules/ } 等價(jià)于下面,?表示'x'是0個(gè)或者1個(gè)
            { test: /\.jsx?$/, use: 'babel-loader', exclude: /node_modules/ } 
          ]
      }
      
  2. jsx 語(yǔ)法的本質(zhì):并不是直接把 jsx 渲染到頁(yè)面上,而是 內(nèi)部先轉(zhuǎn)換成了 createElement 形式,再渲染的;

  3. 在 jsx 中寫入 js 表達(dá)式:在 jsx 語(yǔ)法中,要把 JS代碼寫到 { } 中。當(dāng)編譯引擎,在編譯jsx代碼的時(shí)候,如果遇到了<那么就把它當(dāng)作 HTML代碼去編譯,如果遇到了 {} 就把 花括號(hào)內(nèi)部的代碼當(dāng)作普通JS代碼去編譯;

let a = 10;//渲染數(shù)字
let str = '你好,中國(guó)';//渲染字符串
let boo = true;//布爾值加入表達(dá)式
let title = 'lala';//為屬性綁定值
const h1 = <h1>你真可愛(ài)</h1>//渲染jsx元素
const arr =[
    <h2>這是h2</h2>,//這是js對(duì)象,不是html標(biāo)簽
    <h3>這是h3</h3>
]//渲染jsx元素?cái)?shù)組
//將普通字符串?dāng)?shù)組,轉(zhuǎn)為jsx數(shù)組并渲染到頁(yè)面上【兩種方案】
const arrStr =['毛利蘭','柯南','灰原哀'];
//方案一
const nameArr= [];
arrStr.forEach(item=>{//forEach沒(méi)有返回值
    const temp = <h5>{item}</h5>
    nameArr.push(temp);
})
//數(shù)組的map方法,對(duì)數(shù)組的每一項(xiàng)做一個(gè)指定的操作,并返回一個(gè)新的數(shù)組,必須寫return
const resultArr = arrStr.map(item=>{
    return item +'~~'
})

//當(dāng)我們需要在JSX控制的區(qū)域內(nèi)寫js表達(dá)式,則需要把JS代碼寫到{}中
ReactDOM.render(<div>
    {a+2}<hr/>
    {str}<hr/>
    {boo?'條件為真':'條件為假'}<hr/>
    <p title={title}></p>
    {h1}
    {arr}
    <hr/>
    {nameArr}
    <hr/>
    {arrStr.map(item=>{
        return <h3>{item}</h3>
    })}
    <hr/>
    {arrStr.map(item => <h3>{item+'1'}</h3>)}
    </div>,document.getElementById('app'))
  1. 在 jsx 中 寫注釋:推薦使用{ /* 這是注釋 */ };因?yàn)槿绻麑憜涡凶⑨?code>//``,}`要換行
  2. 為 jsx 中的元素添加class類名:必須使用className 替代 class,因?yàn)?class在ES6中是一個(gè)關(guān)鍵字;同樣,必須用htmlFor替換label的for屬性
  3. 給元素綁定屬性的時(shí)候用{變量}即可,如<p title={title}></p>
  4. 在JSX創(chuàng)建DOM的時(shí)候,所有的節(jié)點(diǎn),必須有唯一的根元素進(jìn)行包裹;
  5. 在 jsx 語(yǔ)法中,標(biāo)簽必須成對(duì)出現(xiàn),如果是單標(biāo)簽,則必須自閉合!

當(dāng) 編譯引擎,在編譯JSX代碼的時(shí)候,如果遇到了<那么就把它當(dāng)作 HTML代碼去編譯,如果遇到了 {} 就把 花括號(hào)內(nèi)部的代碼當(dāng)作 普通JS代碼去編譯;

安裝 React Developer Tools 調(diào)試工具

React Developer Tools - Chrome 擴(kuò)展下載安裝地址

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容