前端筆記之React(一)初識React&組件&JSX語法

1、React項目起步配置

官網:https://reactjs.org/javascript

文檔:https://reactjs.org/docs/hello-world.htmlcss

中文:http://react.css88.com/html

2013年被開源,2014年在中國完全火爆。vue

 

ReactCMD架構,現階段須要webpack打包java

npm install -g webpack@4.9.1

必須安裝如下三個依賴:node

npm install --save-dev babel-core babel-loader babel-preset-env

 

React採用jsx語法,JSX語法是什麼?react

就是全球惟一標準的JavaScriptXHTML結合開發最優雅的語法。webpack

瀏覽器不識別JSX語法,因此須要babelJSX語法翻譯,babel要裝一個新的presetweb

npm install --save-dev babel-preset-react

 

安裝完依賴,修改webpack.congif.js文件中的preset配置:npm

const path = require('path');
module.exports = {
    entry: "./www/app/main",
    output : {
        path: path.resolve(__dirname, "www/dist"),
        filename : "bundle.js",
    },
    watch:true,
    mode : "development",
    module: {
        rules: [
            {
                test: /\.js?$/, 
                include: [path.resolve(__dirname, "www/app")],
                exclude: [path.resolve(__dirname, "node_modules")], 
                loader : "babel-loader",
                options: { presets: ["env","react"] }, //要翻譯的語法 
            }
        ]
    }
}

還要安裝reactreact-dom包:

npm install --save react react-dom

 react是核心庫

 react-dom提供了與DOM操做的功能庫

注意:項目文件夾名字千萬不要叫react,很坑。

 

index.html上放「掛載點」的盒子:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8" />
    <title>Document</title>
</head>
<body>
    <div id="app"></div>
</body>
<script type="text/javascript" src="dist/bundle.js"></script>
</html>

 

app/main.js

import React from "react";
import ReactDOM from "react-dom";

ReactDOM.render(
    <div>
        <h1>你好,我是react,來自Facebook公司</h1>
    </div>,
    document.getElementById('app')
);
示例代碼

運行webpack,直接打開頁面:

 React是全部react項目的入口

 React-dom負責react Element添加到HTML頁面的掛載點上

 

react-dom 這個包提供了你的app最高等級的API,提供了元素的掛載和上樹的方法

render() 接收兩個參數,第一個參數是react元素,第二個參數是掛載點,用來讓react元素進行掛載。

 

Vue在寫實例,而React在寫類(構造函數)。


2、組件

組件叫component」,就是HTMLCSSJS行爲的一個封裝。

Vue中的組件是一個.vue文件(實際上是普通的JSON對象),React中,組件是一個類(構造函數)。

2.1類式組件

建立App.js文件,這是一個組件,必須按照要求寫標準殼,這個殼咱們叫rcc殼「react class component」,react的類式組件:

import React from "react";
// 默認暴露一個構造函數(類組件)
export default class App extends React.Component{
    constructor(){
        super();
    }
    render(){
        return <div>
            <h1>我是App組件!</h1>
        </div>
    }
}

 

注意:

1)這個文件的默認暴露就是一個類,這個類的類名必須和文件名相同。
2)文件名和類名的首字母必須大寫!React中組件的合法名字首字母必須是大寫字母。
3)這個類必須繼承自React.Component類,也就是說,rcc殼必須是extends React.Component的寫法。
4)這個類必須有構造器constructor,構造器裏面必須調用超類的構造器,super();
5)這個類必須有render函數,render函數中必須return一個jsx對象。並且這個jsx對象必須被惟一的標籤包裹。

 

在main.js主文件中引入組件,而後用自定義標籤:

import React from "react";
import ReactDOM from "react-dom";
// 引入組件
import App from "./App.js";

ReactDOM.render(
    <div>
        <App></App>
        <h1>你好,我是react,來自Facebook公司</h1>
    </div>,
    document.getElementById("app")
);

注意:

引入的組件必須路徑以./開頭

組件要使用,就將這個組件的名字(類名、文件名)進行標籤化便可

原理就是這個App類在被實例化。

由於類的名字是大寫字母,因此全部的自定義組件標籤名字必定是大寫字母開頭的

react中,全部以大寫字母開頭的都是組件,而不是標籤。

 

ReactDOM.render(jsx,根的掛載點)

ReactDOM只能出現一次,可是很是厲害,能夠和HTML結合

 

jsx,如今一概在js文件夾中開發,並非傳統放html開發

HTMLCSSJS都被構建到bundle.js文件夾中。

 

安裝如下插件,輸入rcc便可快速生成一個組件的語法:

 


2.2組件能夠多層嵌套

main.js文件中引入App.js組件,App組件裏面的render函數還能夠引入其餘組件。

components/Child.js

import React from "react";
export default class Child extends React.Component {
    constructor() {
        super();
    }
    render() {
        return <div>
            <h1>我是Child子組件!</h1>
        </div>
    }
}

 

App父組件中引入:

import React from "react";
import Child from "./components/Child";
// 默認暴露一個構造函數(類組件)
export default class App extends React.Component {
    constructor() {
        super();
    }
    render() {
        return <div>
            <h1>我是App組件!</h1>
            <Child></Child>
            <Child></Child>
            <Child></Child>
        </div>
    }
}

簡單的說:在react中作一個組件:

第一步:建立一個類並暴露

第二步:引入這個類,而後用這個類的類名當作組件的標籤(實例化)


2.3函數式組件

一個函數,若是是大寫字母開頭,而且return一個React Element就是一個組件。

好比App.js組件中,建立一個Child1的函數,這個函數直接返回JSX語法的React Element,此時這個函數就是組件,這個函數直接成爲自定義標籤,就能夠用了。

import React from "react";
import Child from "./components/Child";
// 默認暴露一個構造函數(類組件)

//定義一個自定義的函數組件
const Child1 = ()=> <div>
    <h1>我是Child1函數式組件!</h1>
</div>

export default class App extends React.Component {
    constructor() {
        super();
    }
    render() {
        return <div>
            <h1>我是App組件!</h1>
            <Child></Child>
            <Child1></Child1>
        </div>
    }
}

注意:

1render是一個函數,因此函數裏面固然能夠定義另外一個函數。咱們用const來定義一個箭頭函數,這個箭頭函數的名字,必須首字母大寫。react中全部標籤名字是首字母大寫的,將被斷定爲咱們本身的組件。

2)這個函數裏面return了一個jsx對象,注意,不要加引號。初學者會有不少不適。

3)這個組件也是經過「標籤」的形式來上樹的!

4)函數式組件比類組件差不少功能不少,後面會說。

5)至於何時用什麼組件、圓括號中能不能傳入參數,後面會說。

 

函數式組件有個缺點,沒有state,沒有生命週期。


3、JSX語法

全部對React不適應,都是JSX語法形成的,JSX語法淡化了JSHTML之間的「邊界」。

 

3.1標籤必須合理嵌套

錯誤的:

import React from "react";
import ReactDOM from "react-dom";
// 引入組件
import App from "./App.js"
ReactDOM.render(
    <App></App>
    <App></App>
    <App></App>
  ,
  document.getElementById('app')
);

 

有多個組件,必須有一個標籤包裹全部組件:

import React from "react";
import ReactDOM from "react-dom";
// 引入組件
import App from "./App.js"
ReactDOM.render(
  <div>
     <App></App>
     <App></App>
     <App></App>
  </div>
  ,
  document.getElementById('app')
);

 

好比table不能直接嵌套tr,必需要有tbody

import React from "react";
export default class App extends React.Component {
    constructor() {
        super();
    }
    render() {
        return <div>
            <table>
                <tbody>
                    <tr>
                        <td>1</td>
                        <td>2</td>
                    </tr>
                </tbody>
            </table>
        </div>
    }
}

 

好比這樣也是錯誤的:

 <p><div>111</div></p>


3.2 return不能換行

return後面直接跟着div,不能換行

 

 

若是想換行,必須加圓括號包裹。

import React from "react";
export default class App extends React.Component {
    constructor() {
        super();
    }
    render() {
        return (
            <div>
                <h1>我是App組件</h1>
            </div>
 )
    }
}

3.3標籤必須嚴格封閉

由於jsx語法被babel-loader翻譯(babel-perset-react),因此標籤必須嚴格封閉,不然翻譯會報錯。

錯誤的:
<br>
<hr>

正確的:
<br/>
<hr/>

錯誤的:
<input type="text">

正確的:
<input type="text" />

3.4全部的類名必須用className表示

由於JSclass是關鍵字,因此類名必須用className

錯誤的

<div class="box"></div>

正確的:

 <div className="box"></div>

 

for要用htmlFor代替:

錯誤的:
 <label for=""></label>
正確的:
 <label htmlFor=""></label>

3.5插值基礎(重點)

能夠在jsx內部,用單個「{}」大括號進行一些js表達式的插入,咱們叫作插值。

{} 只能出如今React element中,簡化了連字符串工做。

import React from "react";
export default class App extends React.Component {
    constructor() {
        super();
    }
    render() {
        const year = 10000;
        const pingfang = (n)=>{
            return n * n }
        const arr = [1000,2000,3000,4000]
        return <div>
            <h1>{5000 * 2}年</h1>
            <h1>{year}年</h1>
            <h1>{pingfang(100)}年</h1>
            <h1>{arr.reduce((a,b)=>a + b)}年</h1>
            <h1>{parseInt(Math.random() * 100)}年</h1>
            <h1>{3 > 8 ? 10000 : 1}年</h1>
        </div>
    }
}

 

不能出現的語法:

不能定義變量:

<h1>{var a = 100}</h1>

不能定義函數:

<h1>{function name(){}}</h1>

應該在return以前定義:

render() {
    const pingfang = (n)=> n * n
    return (
        <div>
            <h1>我愛你{pingfang(100)}年</h1>
        </div>
    )
}

 

不能出現for循環、if語句、whiledo語句:

<h1>{for(var i = 0;i < 100;i++){}}</h1>

JSX不能出現對象(JSON)。

render() {
    const obj = {"a":100,"b":200}
    return (
        <div>
            <h1>{obj}</h1>
        </div>
    )
}

此時會報錯,若是要在頁面顯示JSON,應該:

render() {
   const obj = {"a":100,"b":200}
    return (
        <div>
            <h1>{JSON.stringify(obj)}</h1>
        </div>
    )
}

3.6插值高級

JSX表達式不能出現引號中,好比有一個變量

render() {
    const picUrl = "baby1.jpg"
    return <div>
        <img src="images/{picUrl}.jpg" />
    </div>
}

 

正確的應該先寫在外層的{}

render() {
    const picUrl = "baby1";
    const tip = '這是黃曉明老婆';
    const url = 'http://www.baidu.com/'
    return <div>
        <img src={"images/" + picUrl + ".jpg"} />
        <img src={`images/${picUrl}.jpg`} title={tip} />
        <a href={url}>去百度</a>
    </div>
}

 

內嵌樣式要求這樣的語法插值:

style後面直接跟着{{}},沒有引號,{{}}中是JSON,全部的屬性名都是駝峯命名法:

<div style={{"width":"100px","height":"100px","backgroundColor":"red"}}></div>

react的程序,能夠進行合理的換行

<div style={{
    "width":"100px",
    "height":"100px",
    "backgroundColor":"red"
}}>
</div>

3.7 jsx中數組內容會被自動展開(重點)

此時你內心可能有一萬個草泥馬,這是什麼鬼,數組怎麼能不加引號呢?由於是JSX語法規定。

import React from "react";
export default class App extends React.Component {
    constructor() {
        super();
    }
    render() {
       const arr = [
            <li key="0">牛奶</li>,
            <li key="1">咖啡</li>,
            <li key="2">奶茶</li>,
            <li key="3">可樂</li>
        ]
        return <div>
             <ul>
                 {arr}
             </ul>
        </div>
    }
}

只要你在{}放一個數組,此時這個數組不用循環了,就會自動被展開。

全部的數組元素,必須加上key屬性,不然報錯

 

注意:

數組有4項,每項都是jsx元素,不須要加引號

每項必需要有不一樣的key屬性,這是react要求的

數組直接{arr}就能夠了,也不須要寫循環遍歷語句。

 

數據和DOM怎麼進行模板的循環:

arr數組中,沒有任何的標籤,只是數據:此時就要在{}中用map來映射一個新的數組

import React from "react";
export default class App extends React.Component {
    constructor() {
        super();
    }
    render() {
        const arr = ["牛奶","咖啡","奶茶","可樂"]
        return <div>
             <ul>
                 {arr.map((item,index)=>{
                    return <li key={index}>{item}</li>
                 })}
             </ul>
        </div>
    }
}
示例代碼

映射出一個表格:

import React from "react";
export default class App extends React.Component {
    constructor() {
        super();
    }
    render() {
        const arr = [
            {"id":1,"name":"小明","age":12,"sex":"男"},
            {"id":2,"name":"小紅","age":13,"sex":"女"},
            {"id":3,"name":"小剛","age":14,"sex":"男"},
            {"id":4,"name":"小白","age":15,"sex":"男"}
        ]
        return <div>
             <table>
                 <tbody>
                    {
                        arr.map(item=>{
                            return <tr key={item.id}>
                                <td>{item.id}</td>
                                <td>{item.name}</td>
                                <td>{item.age}</td>
                                <td>{item.sex}</td>
                            </tr>
                        })
                    }
                 </tbody>
             </table>
        </div>
    }
}
示例代碼

3.8九九乘法表

學習的是二維數組的展開

咱們先有一個套路,準備一個外層的數組,而後外層的循環中push內部數組:

import React from "react";
export default class App extends React.Component {
    //構造函數
    constructor() {
        super();
    }
    render() {
        var arr = [];
        for(var i = 1;i <= 9;i++){
            var temp = []
            for(var j = 1; j <= i; j++) {
                temp.push(<td key={j}> {i} * {j} = {i*j} </td>)
            }
            arr.push(<tr key={i}>{temp}</tr>)
        }
        return (
            <div>
                 <table>
                    <tbody>
                        {arr}
                    </tbody>
                 </table>
            </div>
        )
    }
};
實力代碼

3.9日曆

日曆的原理,決定一個日曆的畫風,有三要素:

 這個月第一天是星期幾;

 這個月有幾天;

 上個月有幾天;

 

要知道2018年5月5日是星期幾:
new Date(2018,5-1,5).getDay()

要知道2018年5月有幾天:
new Date(2018,5,0).getDate()

 

本月有幾天,等價於下個月前一天是幾號,因此下個月的0號,就是本月的最後一天。

 

 

給日曆加農曆:

npm install --save solarlunar
import React from "react";
import solarLunar from 'solarLunar';
export default class App extends React.Component {
    //構造函數
    constructor() {
        super();
    }
    render() {
        var year = 2018;
        var month = 8; //是人類的月份,而不是計算機的
        //本月第一天是星期幾
        var TheMonthFirstDay = new Date(year,month - 1,1).getDay();
        //本月共幾天
        var TheMonthDays = new Date(year,month,0).getDate();
        //上個月共幾天
        var prevMonthDays = new Date(year,month-1,0).getDate();

        var arr = [];
        
        //上個月的尾巴,本月第一天星期幾就有幾天上個月的尾巴
        while (TheMonthFirstDay--){
            arr.unshift(prevMonthDays--)
        }

        // 本月放進數組
        var count = 1;
        while(TheMonthDays--){
            arr.push(count++);
        }
        // 下個月的前有多少天,要補齊42天
        var nextCount = 1;
        while ( arr.length != 42){
            arr.push(nextCount++);
        }
        console.log(arr)
        //接下來要用這個一維數組集合JSX語法,展開爲二維數組
        const showTable = ()=>{
            var domArr = [];
            for(var i = 0; i < arr.length / 7; i++){
              domArr.push(      <tr key={i}>
                        {
                            arr.slice(i * 7, i * 7 + 7).map(item=>{
                                var n = solarLunar.solar2lunar(year, month, item);
                                return <td key={item}>
                                    {item}
                                    <br/>
                                    {n.term || n.dayCn}
                                </td>
 })
                        }
                    </tr>      
                )
            } return domArr;
        }

        return (
            <div>
                 <table>
                     <thead>
                         <tr>
                             <th>日</th>
                             <th>一</th>
                             <th>二</th>
                             <th>三</th>
                             <th>四</th>
                             <th>五</th>
                             <th>六</th>
                         </tr>
                     </thead>
                     <tbody>
                        {showTable()}
                     </tbody>
                 </table>
            </div>
        )
    }
};
相關文章
相關標籤/搜索