React的介紹:
React來自於Facebook公司的開源項目
React 可以開發單頁面應用 spa(單頁面應用)
react 組件化模塊化 開發模式
React通過對DOM的模擬(虛擬dom),最大限度地減少與DOM的交互 (數據綁定)
react靈活 React可以與已知的庫或框架很好地配合。
react 基於jsx的語法,JSX是React的核心組成部分,它使用XML標記的方式去直接聲明界面, html js混寫模式
搭建React開發環境之前的准備工作。
1、必須安裝nodejs 注意:安裝nodejs穩定版本
2、安裝cnpm用cnpm替代npm
地址:http://npm.taobao.org/
安裝cnpm:
npm install -g cnpm --registry=https://registry.npm.taobao.org
3、用yarn替代npm
yarn的安裝:
第一種方法:參考官方文檔https://yarn.bootcss.com/
第二種方法:cnpm install -g yarn 或者 npm install -g yarn
搭建React開發環境
第一種方法(老-現在推薦):
https://reactjs.org/docs/create-a-new-react-app.html
1、必須要安裝nodejs 注意:安裝nodejs穩定版本 nodejs版本:v8.11.2 npm版本:v5.6.0
2.安裝腳手架工具 (單文件組件項目生成工具) 只需要安裝一次
npm install -g create-react-app / cnpm install -g create-react-app
3.創建項目 (可能創建多次)
找到項目要創建的目錄:
create-react-app reactdemo
4.cd 到項目里面
cd reactdemo
npm start yarn start運行項目
npm run build yarn build 生成項目
第二種方法(新-未來推薦):
https://reactjs.org/docs/create-a-new-react-app.html
1、必須要安裝nodejs 注意:安裝nodejs穩定版本 nodejs版本:v8.11.2 npm版本:v5.6.0
2.安裝腳手架工具並創建項目
找到項目要創建的目錄執行:
npx create-react-app reactdemo
4.cd 到項目里面
cd reactdemo
npm start 運行項目(調試)
npm run build 生成項目(發布)
npx介紹:
npm v5.2.0引入的一條命令(npx),引入這個命令的目的是為了提升開發者使用包內提供的命令行工具的體驗。
詳情:
http://www.phonegap100.com/thread-4910-1-1.html
npx create-react-app reactdemo這條命令會臨時安裝 create-react-app 包,命令完成后create-react-app 會刪掉,不會出現在 global 中。下次再執行,還是會重新臨時安裝。
npx 會幫你執行依賴包里的二進制文件。
再比如 npx http-server 可以一句話幫你開啟一個靜態服務器
manifest.json 文件簡介:
https://lavas.baidu.com/mip/doc/engage-retain-users/add-to-home-screen/introduction
允許將站點添加至主屏幕,是 PWA 提供的一項重要功能,當前 manifest.json 的標准仍屬於草案階段,Chrome 和 Firefox 已經實現了這個功能,微軟正努力在 Edge 瀏覽器上實現,Apple 目前仍在考慮中
super關鍵字:
參考:http://www.phonegap100.com/thread-4911-1-1.html
Es6中的super可以用在類的繼承中,super關鍵字,它指代父類的實例(即父類的this對象)。子類必須在constructor方法中調用super方法,否則新建實例時會報錯。這是因為子類沒有自己的this對象,而是繼承父類的this對象,然后對其進行加工。如果不調用super方法,子類就得不到this對象。
1 class Person { 2 constructor (name) { 3 this.name = name; 4 } 5 } 6 class Student extends Person { 7 constructor (name, age) { 8 super(); // 用在構造函數中,必須在使用this之前調用 9 this.age = age; 10 } 11 }
為什么官方的列子里面寫個super(props):
只有一個理由需要傳遞props作為super()的參數,那就是你需要在構造函數內使用this.props
那官方提供學習的例子中都是寫成super(props),所以說寫成super(props)是完全沒問題的,也建議就直接這樣寫。
ReactJSX語法
JSX就是Javascript和XML結合的一種格式。React發明了JSX,可以方便的利用HTML語法來創建虛擬DOM,當遇到<,JSX就當作HTML解析,遇到{就當JavaScript解析.
1、所有的模板要被一個根節點包含起來,在render函數中return返回的只能包含一個頂層標簽,否則也會報錯
2、模板元素不要加引號
3、JSX基本語法規則,遇到HTML標簽(以<開頭),就用HTML規則解析;遇到代碼塊(以{開頭),就用JS規則解析
4、綁定屬性注意:
class 要變成 className
for 要變成 htmlFor
style屬性和以前的寫法有些不一樣
<div style={{'color':'blue'}}>{this.state.title}</div>
<div style={{'color':this.state.color}}>{this.state.title}</div>
5、循環數據要加key
6、組件的構造函數中一定要注意 super
子類必須在constructor方法中調用super方法,否則新建實例時會報錯。這是因為子類沒有自己的this對象,而是繼承父類的this對象,然后對其進行加工。如果不調用super方法,子類就得不到this對象
1 constructor(props){ 2 super(props); /*用於父子組件傳值 固定寫法*/ 3 this.state={ 4 userinfo:'張三' 5 } 6 }
7、組件名稱首字母大寫、組件類名稱首字母大寫
8、react解析html
1 <div dangerouslySetInnerHTML={{__html: this.state.list.htmlStr}}> </div>
9、條件判斷的四種寫法
用三元表達式, 使用dom元素變量,直接調用函數,使用邏輯運算符,利用即時執行函數
1 class HelloWorld extends React.Component{ 2 render(){ 3 return <p>Hello { 4 (function(obj){ 5 if(obj.props.name){ 6 return obj.props.name; 7 }else{ 8 return "World"; 9 } 10 }(this)) 11 }</p> 12 } 13 }
Fragment標簽
加上最外層的DIV,組件就是完全正常的,但是你的布局就偏不需要這個最外層的標簽怎么辦?比如我們在作Flex布局的時候,外層還真的不能有包裹元素。這種矛盾其實React16已經有所考慮了,為我們准備了<Fragment>標簽。
在以類繼承的方式定義的組件中,為了能方便地調用當前組件的其他成員方法或屬性(如:this.state),通常需要將事件處理函數運行時的 this 指向當前組件實例。
引入方式:
import React,{Component,Fragment } from 'react'
然后把最外層的<div>標簽,換成<Fragment>標簽
setState
React是禁止直接操作state的,雖然上面的方法也管用,但是在后期的性能優化上會有很多麻煩
綁定事件處理函數this的幾種方法:
第一種方法:
1 run(){ 2 alert(this.state.name) 3 } 4 <button onClick={this.run.bind(this)}>按鈕</button>
第二種方法: 構造函數中改變
1 this.run = this.run.bind(this); 2 run(){ 3 alert(this.state.name) 4 } 5 <button onClick={this.run>按鈕</button>
第三種方法:
1 run=()=> { 2 alert(this.state.name) 3 } 4 <button onClick={this.run>按鈕</button>
React中的組件: 解決html 標簽構建應用的不足。
獲取表單的值
(獲取點擊的某個鍵的key值 e.keyCode)
1、監聽表單的改變事件 onChange
2、在改變的事件里面獲取表單輸入的值 ref獲取
3、把表單輸入的值賦值給username this.setState({})
4、點擊按鈕的時候獲取 state里面的username this.state.username
組件傳值:
使用組件的好處:把公共的功能單獨抽離成一個文件作為一個組件,哪里里使用哪里引入。
父子組件:組件的相互調用中,我們把調用者稱為父組件,被調用者稱為子組件
父子組件傳值:
一,父組件給子組件傳值
1.在調用子組件的時候定義一個屬性 <Header msg='首頁'></Header>
2.子組件里面 this.props.msg
說明:父組件不僅可以給子組件傳值,還可以給子組件傳方法,以及把整個父組件傳給子組件。
記住一點:父組件向子組件傳遞內容,靠屬性的形式傳遞。
父組件主動獲取子組件的數據
1、調用子組件的時候指定ref的值 <Header ref='header'></Header>
2、通過this.refs.header 獲取整個子組件實例
二,子組件給父組件傳值:
defaultProps:父子組件傳值中,如果父組件調用子組件的時候不給子組件傳值,可以在子組件中使用defaultProps定義的默認值
propTypes:驗證父組件傳值的類型合法性,定義父組件給子組件傳值的類型
1、引入import PropTypes from 'prop-types';
2、類.propTypes = {
name: PropTypes.string
};
都是定義在子組件里面
約束性和非約束性組件:
非約束性組:<input type="text" defaultValue="a" /> 這個 defaultValue 其實就是原生DOM中的 value 屬性。
這樣寫出的來的組件,其value值就是用戶輸入的內容,React完全不管理輸入的過程。
約束性組件:<input value={this.state.username} type="text" onChange={this.handleUsername} />
這里,value屬性不再是一個寫死的值,他是 this.state.username, this.state.username 是由 this.handleChange 負責管理的。
這個時候實際上 input 的 value 根本不是用戶輸入的內容。而是onChange 事件觸發之后,由於 this.setState 導致了一次重新渲染。不過React會優化這個渲染過程。看上去有點類似雙休數據綁定
react獲取服務器APi接口的數據:
react中沒有提供專門的請求數據的模塊。但是我們可以使用任何第三方請求數據模塊實現請求數據
1、axios https://github.com/axios/axios axios的作者覺得jsonp不太友好,推薦用CORS方式更為干凈(后端運行跨域)
1、安裝axios模塊npm install axios --save / npm install axios --save
2、在哪里使用就在哪里引入import axios from 'axios'
3、看文檔使用
1 Var api=''; 2 axios.get(api) 3 .then(function (response) { 4 console.log(response); 5 }) 6 .catch(function (error) { 7 console.log(error); 8 });
2、fetch-jsonp https://github.com/camsong/fetch-jsonp
1、安裝 npm install fetch-jsonp --save
2、import fetchJsonp from 'fetch-jsonp'
3、看文檔使用
fetchJsonp('/users.jsonp')
.then(function(response) {
return response.json()
}).then(function(json) {
console.log('parsed json', json)
}).catch(function(ex) {
console.log('parsing failed', ex)
})
3、其他請求數據的方法也可以...自己封裝模塊用原生js實現數據請求也可以...
React生命周期函數:
組件加載之前,組件加載完成,以及組件更新數據,組件銷毀。
觸發的一系列的方法 ,這就是組件的生命周期函數
組件加載的時候觸發的函數:
constructor 、componentWillMount、 render 、componentDidMount
組件數據更新的時候觸發的生命周期函數:
shouldComponentUpdate、componentWillUpdate、render、componentDidUpdate
你在父組件里面改變props傳值的時候觸發的:
componentWillReceiveProps
組件銷毀的時候觸發的:
componentWillUnmount
必須記住的生命周期函數:
*加載的時候:componentWillMount、 render 、componentDidMount(dom操作)
更新的時候:componentWillUpdate、render、componentDidUpdate
*銷毀的時候: componentWillUnmount
react路由的配置:
1、找到官方文檔 https://reacttraining.com/react-router/web/example/basic
2、安裝 cnpm install react-router-dom --save
3、找到項目的根組件引入react-router-dom
import { BrowserRouter as Router, Route, Link } from "react-router-dom";
4、復制官網文檔根組件里面的內容進行修改 (加載的組件要提前引入)
<Router>
<Link to="/">首頁</Link>
<Link to="/news">新聞</Link>
<Link to="/product">商品</Link>
<Route exact path="/" component={Home} />
<Route path="/news" component={News} />
<Route path="/product" component={Product} />
</Router>
exact表示嚴格匹配
實現js跳轉路由:https://reacttraining.com/react-router/web/example/auth-workflow
1、要引入Redirect
2、定義一個flag
this.state = {
loginFlag:false
};
3、render里面判斷flag 來決定是否跳轉
if(this.state.loginFlag){
return <Redirect to={{ pathname: "/" }} />;
}
4、要執行js跳轉
通過js改變loginFlag的狀態
改變以后從新render 就可以通過Redirect自己來跳轉
url模塊來解析url地址 在react里面使用url模塊需要安裝url模塊 cnpm install url --save
import url from 'url';
//獲取get傳值
console.log(url.parse(this.props.location.search,true));
var query=url.parse(this.props.location.search,true).query;
console.log(query)
未完待續。。。
