react入門學習

初始配置

$ 1 建立基本的webpack項目

建立目錄

  • npm init -y 建立package.json
  • cnpm i webpack webpack-cli -D 安裝webpack webpack-cli
  • 在根目錄建立webpack.config.js並寫入相應代碼module.exports={mode:'development'}
    css

  • 終端裏輸入webpack進行打包,以後dist文件夾裏多出個main.js,打包成功html

    配置實時打包編譯
  • cnpm i webpack-dev-server -D
    package.jsonscripts裏寫入"dev": "webpack-dev-server --open --port 3000 --hot --host 127.0.0.1 --progress --compress"webpack-dev-server以後的如--open,--hot等代碼是功能性代碼,可選擇性寫
`--open` 設置自動打開默認瀏覽器 `--oprn chrome`設置自動打開google瀏覽器
`--port 3000` 設置端口號爲3000,若不寫則默認是8080
`--host 127.0.0.1`設置域名爲127.0.0.1
`--compress` 壓縮
`http://loaclhost:8080/`
  • npm run dev 運行,文件可在http://localhost:8080打開(ctrl+c能夠終止npm run dev)
    index.html 中<script src="../dist/main.js"></script> 路徑改成/main.js
由於webpack-dev-server打包好的main.js是託管到內存中的,在內存中是看不到的,
但卻實實在在的存在於根目錄中,因此用/main.js引入根目錄中的main.js
解決常常訪問磁盤目錄問題——將index頁面也放入內存中便可
  • cnpm i html-webpack-plugin -D 安裝在內存中自動生成html頁面的插件,解決每保存一次就調用代碼消耗磁盤性能的問題
  • webpack.config.js寫入以下代碼(dirname前是兩個 _ )--注意,代碼千萬不要敲錯

const path=require('path')
const HtmlWebPackPlugin = require('html-webpack-plugin')

const htmlPlugin = new HtmlWebPackPlugin({
  template: path.join(__dirname,'./src/index.html'),
  filename:'index.html'
})

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

在這運行以後,系統會自動把打包好的js注入到頁面中去(以下圖藍色部分是系統自動注入的)。因此<script src="/main.js"></script>能夠省去了!vue

  • npm run dev便可(注,不要cnpm run dev, cnpm通常只用來裝包)

———————————————以上,初步配置完成———————————————node

$ 2 react起步(react中,一切都是用js來表現的)

安裝react react-dom包
  • cnpm i react react-dom -S
  • 在index.js裏導入包
    import React from 'react'
    import ReactDOM from 'react-dom'
  • 接下來能夠根據格式來寫代碼了,在index.js裏寫
建立虛擬DOM元素: const myh1 = React.createElement("h1",{id:"myh1",title:"thish1"},"這是一個h1標籤及其內容")
`參數1:標籤類型:div,h1,input等:
參數2:標籤屬性,{attr:"aa",attr:"bb"},不設置就寫null`
`參數3:標籤子節點,或者說內容
參數n:其餘更多子節點`
調用render函數渲染: ReactDOM.render(myh1,document.getElementById("list1"))
`參數1:要渲染的那個虛擬DOM元素,如myh1;
參數2:指定html頁面上的一個容器(必須寫成dom元素的形式,就是這裏的document.getElementById)
如<div id="list1"></div>`

標籤嵌套寫法
react

JSX
  • React.createElement形式寫起來太繁瑣
  • 因而react開發出了在js中,混合寫入相似於html的語法,咱們稱之爲JSX
  • 寫好以後經過babel轉換成React.createElement形式執行即可
  • jsx 語法的本質:並非直接把 jsx 渲染到頁面上,而是內部先轉換成了 createElement 形式,再渲染的
配置babel

(版本配置問題,避免踩坑從我作起 https://blog.csdn.net/tj310/article/details/88134512 )webpack

  • 安裝 babel插件
    • 運行cnpm i babel-loader @babel/core @babel/plugin-transform-runtime @babel/runtime -D
    • 運行 cnpm i @babel/preset-env @babel/plugin-proposal-class-properties -D
  • 安裝可以識別轉換jsx語法的包,就是將jsx轉化爲js @babel/preset-react
    • 運行cnpm i @babel/preset-react -D
  • 在根目錄添加.babelrc 配置文件
{
  "presets": ["@babel/preset-env", "@babel/preset-react"],
  "plugins": ["@babel/plugin-transform-runtime", "@babel/plugin-proposal-class-properties"]
}
  • 在webpack.config.js的module.exports中添加babel-loader配置項:
module: { //要打包的第三方模塊
    rules: [
      { test: /\.js|jsx$/, use: 'babel-loader', exclude: /node_modules/ }  //exclude必定不能丟
    ]
}
  • 後綴名的省略及改變路徑
在以上,在webpack.config.js之中的module下方添加以下代碼
 resolve: {
    extensions: ['.js', '.jsx', '.json', '.vue'], // 表示,這幾個文件的後綴名,能夠省略不寫
    alias: { // 表示別名
      '@': path.join(__dirname, './src') // 這樣,@ 就表示 項目根目錄中 src 的這一層路徑
    }
  }
建立組件(兩種方法,本質區別是有無state屬性)

方法1:普通function模式建立組件(用的很少)ios

一、 src目錄下建立components文件夾,裏面建立組件文件(如comp1.jsx),在裏面寫入組件
    `如`
        import React from "react"     `*****必須引入React包*****`
        function Hello(props) {          `***組件名稱首字母大寫***`
          return <div>這是一個Hello組件----{props.name}----{props.age}----{props.weight}</div>
        }
        export default Hello           `*****必須暴露組件*****`

二、在index.js文件裏引入組件
        import Hello(組件名稱) from "./components/comp1.jsx"   `*****必須引入組件*****`

        const arrStr = ["haha", "heihei", "hehe", "xixi"]

        const dog={
            name:"金毛",
            age:"2",
            sex:"公",
            weight:"50kg"
        }

        ReactDOM.render(<div>

          <Hello {...dog}></Hello>      `***使用組件,以組件作標籤名來使用,記住要和組件名如出一轍***`
                                                      `{...dog}`,es6語法---展開運算符

          {arrStr.map(item => < div key = {item.id}><h3>{item}</h3></div > )}   //map方法映射數組,箭頭函數,key

         </div>, document.getElementById("list1"))
方法2:class關鍵字建立組件
  • 先了解什麼是class關鍵字
建立一個動物類
//在class的{}區間內只能寫構造器(內部包含實例屬性),靜態屬性,實例方法,靜態方法
//class關鍵字內部,仍是原來的js方法來寫,只不過更方便了,所以把class關鍵字稱做 語法糖
const Animal {    // 這是class關鍵字
構造器://class關鍵字內必需要有。每當執行new這個類的時候,會優先執行構造器中的代碼
    constructor("name","age"){
        this.name=name      
        this.age=age
    }
靜態屬性://在class內部,經過static修飾的屬性
    static info = "aaaaa"
實例方法(常常用到)
    yaoweiba(){
        console.log("這是一個實例方法")
    }
靜態方法(用的很少)
    static yaoweiba(){
        console.log("這是Animal的靜態方法")
    }
}

    const a1 = new Animal("金毛", 2)
    console.log(a1)
    a1.yaoweiba()   這是實例方法的調用
    Animal.yaoweiba()   這是靜態方法的調用
  • class關鍵字的繼承
class Person{     //父類
    constructor(name,age){     //這裏是公用樣式
        this.name=name
        this.age=age
       }
    sayHello(){
        console.log("你們好")
        }
  }

class American extends Person{    `// class 子類名 extends 父類名`
    constructor(name,age){
    super(name,age)                 `//若是寫構造器了,則super()必需要有,並且必須放在構造器裏的第一行`
        }
  }
const am1 = new American("jack",20)
console.log(am1)
am1.sayHello()

class Chinese extends Person{
     constructor(name,age,IdNumber){
        super(name,age)   
        this.IdNumber = IdNumber
      }
  }
const ch1  = new Chinese("張三",22,"342422************")
console.log(ch1)
ch1.sayHello()
  • class關鍵字建立組件
// 若是要使用 class 定義組件,必須 讓本身的組件,繼承自 React.Component
class Person extends React.Component {
   constructor() {   //給class建立的組件綁定私有數據(普通建立不支持)
      super()
      // 只有調用了 super() 之後,才能使用 this 關鍵字
      this.state = { // 這個 this.state = {} 就至關於 Vue 中的 data() { return { } }
        msg: '你們好,我是 class 建立的 Person組件'
      }
    }
      // 在 組件內部,必須有 render 函數,做用:渲染當前組件對應的 虛擬DOM結構
      render(){
          // render 函數中,必須 返回合法的 JSX 虛擬DOM結構
        this.state.msg="msg的值被我修改了"   //state私有數據的值是能夠修改的,而props是不可修改的
        return <div>
        <h5>這是 class 建立的組件---{this.props.name}---{this.props.age}---{this.props.wife}</h5>
        <h2>{this.state.msg}</h2></div>
//在 class 關鍵字建立的組件中,若是想使用外界傳遞過來的 props 參數,不需接收,直接經過 this.props.屬性名 訪問
     }
}

const person={
    name:"林子閒",
    age:22,
    wife:"喬韻"
 }

ReactDOM.render(<div>
  <Person name={person.name} age={person.age} wife={person.wife}></Person>     
 //必須用組件名以標籤的形式調用
   <Person {...person}></Person>
</div>,document.getElementById("list1"))
使用CSS樣式美化組件

詳細教程請看 https://www.bilibili.com/video/av25294556/?p=42 (第42集)git

一、先下載相關包
      cnpm i style-loader css-loader -D
二、在webpack.config.js內的rules裏配置以下代碼
     { test: /\.css$/, use: ['style-loader', 'css-loader']} 
三、在src文件夾下建立css文件夾,再在裏面建立css文件,而後寫樣式
      如 src > css > style1.css
      在style1.css裏寫樣式
         .mystyle{
              color:red;
              font-size: 14px;
          }
四、在相關文件中引入css文件
      import cssobj from "@/css/style1.css"    //這裏固定寫法cssobj,而非css
五、接下來能夠在相關文件中經過className給定樣式了
      如<div className="mystyle">哈哈</div>
CSS模塊化——避免css樣式污染全局代碼問題,讓其只在當前區域生效
* css模塊化只針對 `類選擇器` 和 `id選擇器` 生效
一、 將webpack.config.js內的rules裏的如下代碼
     { test: /\.css$/, use: ['style-loader', 'css-loader']} 改成
     { test: /\.css$/, use: ['style-loader', 'css-loader?modules']} 
二、 給定樣式的方式改爲
   如  <div className={cssobj.mystyle} id={css.obj.mystyle2}>哈哈</div>
若是有某些css元素不想被模塊化,想全局生效
一、將webpack.config.js內的rules裏的一下代碼
     { test: /\.css$/, use: ['style-loader', 'css-loader?modules']} 改成
     { test: /\.css$/, use: ['style-loader', 'css-loader?modules&localIdentName=[path][name]-[local]-[hash:5]'] }
//[path]  表示樣式表 相對於項目根目錄 所在路徑
//[name]  表示 樣式表文件名稱
//[local]  表示樣式的類名定義名稱
//[hash:length]  表示最多32位的hash值,length能夠指定具體數值  
二、  :global(.allstyle){    //這樣寫就不會被模塊化了 :local(屬性名)
      font-size: 12px;
      padding: 0;
  }
三、而後在相關文件裏引用
  <div className={cssobj.mystyle} className={.allstyle}>哈哈</div>
也能夠這麼寫
<div className={cssobj.mystyle+" allstyle"}>哈哈</div>   //allstyle前面有空格哦
也能夠這麼寫
<div className={[cssobj.mystyle,"allstyle"].join(" ")}>哈哈</div>   //空格哦
在項目中啓用模塊化並同時使用bootstrap

原理:第三方的樣式表是以.css爲後綴名,而咱們將本身的樣式用scss或less來作後綴名, 這樣就能夠區分開來本身的樣式和第三方樣式,從而能夠給scss,less啓用模塊化,而不 影響第三方樣式es6

一、下載bootstrap包   cnpm i bootstrap -S
二、下載包處理字體文件的url包   cnpm i url-loader -D    cnpm i file-loader -D
三、webpack.config.js的rules裏添加   { test:/\.ttf|woff|woff2|eot|svg$/,use:'url-loader'}
四、下載sass的包   cnpm i sass-loader node-sass -D
五、webpack.config.js的rules裏添加   { test:/\.scss$/,use:['style-loader','css-loader?modules&localIdentName=[path][name]-[local]-[hash:5]','sass-loader']}
六、將{ test: /\.css$/, use: ['style-loader', 'css-loader?modules&localIdentName=[path][name]-[local]-[hash:5]','sass-loader'] }
   改成{ test: /\.css$/, use: ['style-loader', 'css-loader'] }
七、在相應jsx或js文件裏引入   import "bootstrap/dist/css/bootstrap.css"  
   而後盡情發揮吧

webpack.config.js裏本階段rules最終版以下web

rules: [
      {test: /\.js|jsx$/,use: 'babel-loader',exclude: /node_modules/},
      { test: /\.css$/, use: ['style-loader', 'css-loader'] },
      { test:/\.ttf|woff|woff2|eot|svg$/,use:'url-loader'},
      { test:/\.scss$/,use:['style-loader','css-loader?modules&localIdentName=[path][name]-[local]-[hash:5]','sass-loader']}
    ]
爲按鈕綁定事件及修改私有數據

onClick onMouseenter onMouseover等 要採用小駝峯命名

import React from "react"
import "bootstrap/dist/css/bootstrap.css"

export default class Hello extends React.Component{
  constructor(){
    super()
    this.state={
        msg: '我沒被修改呢'
    }
  }
  render(){
    /*this.state.msg="我被一this.state.msg的方式修改了"*/
    return <div>
            <h5>這是一個Hello組件</h5><br/>
            <h5>{this.state.msg}</h5>
            <button className="btn btn-primary" onClick={ ()=>{this.myclickHandler(參數1,參數2)}} >按鈕</button>         
//函數調用用這種形式來寫,能夠不寫參數  onClick={()=>{this.myclickHandler()}}
          </div>

  }
  myclickHandler=(a,b)=>{     //函數部分用箭頭函數來寫,能夠不寫參數a,b   myclickHandler=()=>{ }
    alert("我被點擊了"+a+b);
    this.setState({       //若要修改私有數據state,react給定了一個方法 this.setState({ }),同時記住this.state.msg在這裏不可用
      msg:'我被以this.setState的方式修改了'
    },function(){this.state.msg})   //此處爲回調函數,可不加
  }
}
文本框與state值之間的雙向綁定
import React from 'react'

export default class BindEvent extends React.Component {
    constructor() {
      super()
      this.state = {
        msg: '哈哈',
        age: 22,
      }
    }

    render() {
      return <div>
        {/* 需求:點擊按鈕,把修改 msg 的值 */}
        <button onClick={() => this.show('aa', 'bb')}>按鈕</button>
        <h3>{this.state.msg}</h3>


        /* 若是 咱們只是把 文本框的 value 屬性,綁定到了 state 狀態,可是,若是不提供   onChagne 處理函數的話,獲得的文本框,將會是一個只讀的文本框 */
        /* 當爲文本框綁定 value 值之後,要麼同時提供一個 readOnly, 要麼,提供一個   onChange 處理函數 */
        /* <input type="text" style={{ width: '100%' }} value={this.state.msg} readOnly /> */
        <input type="text" style={{ width: '100%' }} value={this.state.msg} onChange={(e) => this.txtChanged(e)} />
              </div>
    }
  
    // 每當文本框的內容變化了,必然會調用 這個 txtChanged
    txtChanged = (e) => {
      // 在 onChange 事件中,獲取 文本框的值,經過事件參數 e 來獲取
      // console.log(e.target.value);

      const newVal = e.target.value

      this.setState({
        msg: newVal
      })
  }

快速搭建react項目

一、電腦裏新建文件夾
二、npm create react-app 項目名稱    如 npm create react-app huihuidemo / yarn create react-app huihuidemo
三、cd 項目名稱    如 cd huihuidemo
四、npm run start
五、安裝antd    cnpm i antd -S / yarn add antd 
六、在css文件中最頂部引入  @import '~antd/dist/antd.css';   //分號不能丟
    (也可在js文件裏直接引入,  import 'antd/dist/antd.css';  )
七、在js jsx文件中引入須要使用的組件   import {Button,Icon...} from 'antd';
八、(之後必要)安裝路由和ajax請求插件   yarn add react-router-dom axios 

具體可見antd官網   https://ant.design/docs/react/use-with-create-react-app-cn
解決react腳手架不支持less的問題
一、安裝less相關包    cnpm i less less-loader -S / yarn add less less-loader 
二、暴露webpack    npm run eject / yarn eject   (此語句執行後會有config和scripts文件夾生成)   
      若出現如下錯誤: (Remove untracked files, stash or commit any changes, and try again.)
      是由於咱們使用腳手架建立一個項目的時候,自動給咱們增長了一個.gitignore文件,而咱們本地卻沒有文件倉庫
      這樣解決: 先輸入  git add .      再輸入  git commit -m 'up' 
三、找到webpack.config.js的const cssRegex = /\.css$/; (第38行) 作出以下改動
    - const cssRegex = /\.css$/;
    + const cssRegex = /\.(css|less)$/;
四、找到webpack.config.js的const loaders ,在裏面最後一組後面添加
    { loader: require.resolve('less-loader') },
添加以後是這樣的:
const loaders = [
      isEnvDevelopment && require.resolve('style-loader'),
      isEnvProduction && {...
       },
      {...
      },
      {...
      },
      {
        loader: require.resolve('less-loader')
      },
    ].filter(Boolean);
五、大功告成

ps:若npm start失敗,出現這個問題(Build fails after eject: Cannot find module '@babel/plugin-transform-react-jsx' )
則能夠
一、刪除 node_modules 文件夾
二、運行 yarn
三、cnpm i less less-loader -S / yarn add less less-loader
三、從新 npm start / yarn start
相關文章
相關標籤/搜索