react學習筆記(react基礎+react全家桶+ant-ui知識)基礎篇


title: react 第一次實戰(zhàn)項目知識點記錄

基礎知識點項目地址:https://github.com/yangxinjian/reactPractice.git
完整項目地址(主要是這個)
https://github.com/yangxinjian/reactAntBike.git

image.png

image.png

準備階段-基層環(huán)境

安裝node.js(官網(wǎng)下載即可)

node -v (查看是否安裝node完成)

安裝yarn新一代的包管理工具facebook開發(fā),你也可以選擇cnpm

  • yarn的速度會比npm快
  • 安裝版本統(tǒng)一,更安全
  • 更簡潔的輸出
  • 更好的語義化
sudo cnpm install yarn -g
yarn -v(查看是否安裝yarn完成)

使用git在馬云上進行托管,并在本地clone下來項目

git clone 你項目的地址
cd 你的項目

配置gitignore(git命令忽視)

vim .gitignore
i(編輯命令)
.DS_Store (Mac自帶)
node_modules (node包)
dist (打包的壓縮文件)
*.log(錯誤信息等)

初始化項目

yarn init  / cnpm init

提交項目

git add . (保存到暫存區(qū))
git commit -m '備注信息' (把暫存區(qū)內(nèi)容保存到分支)
git pull (拉取其他分支代碼)
git push (將更新內(nèi)容提交進入遠程分支)

安裝webpack打包工具(配置規(guī)則查看webpack章節(jié))

yarn add webpack --dev / cnpm install webpack --dev
在根目錄下創(chuàng)建一個webpack.config.js文件

1. 需要處理的文件類型
  
    html => html-webpack=plugin
    js es6 => babel + babel-preset-react
    css => css-loader + sass-loader
    img => url-loader + file-loader

2. 常用模塊

    html-webpack-plugin => html單獨打包成文件
    extract-text-webpack-plugin => 樣式打包成單獨文件
    CommonsChunkPlugin => 提出通用模塊

3. webpack-dev-server

      (1) 為webpack項目提供web服務  
      (2) 更改代碼自動刷新,路徑轉(zhuǎn)發(fā)
      (3) yarn add webpack-dev-server --dev
      (4) 解決多版本共存
1.配置webpack,在創(chuàng)建好的webpack.config.js中配置
  • 添加模塊輸出口

        const path = require('path')
        module.exports = {
            entry: './src/app.js',
            output: {
                path: path.resolve(__dirname, 'dist'), // __dirname代表根目錄
                filename: '你想輸出的文件名字.js'
            }
        }
    
  • 添加html插件

        yarn add html-webpack-plugin --dev // 生成html5文件插件
        
        在webpack.config.js中設置
    
         const path = require('path')
         const HtmlWebpackPlugin = require('html-webpack-plugin') // 引入插件
         module.exports = {
            entry: './src/app.js',
            output: {
                path: path.resolve(__dirname, 'dist'), 
                filename: '你想輸出的文件名字.js'
            },
            plugins: [ // 使用插件
                new HtmlWebpackPlugin({
                      template: '.src/index.html' // 引用模板自定義html文件,使打包出來的html與此文件一致
                })
            ]
        }
    
  • 添加babel插件 (將es6語言轉(zhuǎn)換成es5)

         yarn add babel-core@6.26.0 babel-preset-env@1.6.1 babel-loader@7.1.2 --dev // 安裝
       
         在webpack.config.js配置
         const path = require('path')
         const HtmlWebpackPlugin = require('html-webpack-plugin')
    
         module.exports = {
            entry: './src/app.js',
             output: {
                 path: path.resolve(__dirname, 'dist'),
                 filename: 'app.js'
             },
             module: {
                 rules: [
                     {
                         test: /\.js$/,
                         exclude: /(node_modules)/,// 將不需要裝換的文件夾排除
                         use: {
                             loader: 'babel-loader',
                             options: {
                                 presets: ['env']
                             }
                         }
                     }
                 ]
             },
              plugins: [
                 new HtmlWebpackPlugin({
                     template: '.src/index.html'// 引用自定義html文件
                 }) // 生成html5文件
             ]
         }
    
  • 安裝react的插件
    yarn add babel-preset-react --dev / cnpm install babel-preset-react --dev

          yarn add html-webpack-plugin --dev // 生成html5文件插件
      
      在webpack.config.js中設置
    
       const path = require('path')
       const HtmlWebpackPlugin = require('html-webpack-plugin') // 引入插件
       module.exports = {
          entry: './src/app.js',
          output: {
              path: path.resolve(__dirname, 'dist'), 
              filename: '你想輸出的文件名字.js'
          },
          plugins: [ // 使用插件
              new HtmlWebpackPlugin({
                    template: '.src/index.html' // 引用模板自定義html文件,使打包出來的html與此文件一致
              })
          ]
      }
    
  • 添加babel插件 (將es6語言轉(zhuǎn)換成es5)

         yarn add babel-core@6.26.0 babel-preset-env@1.6.1 babel-loader@7.1.2 --dev // 安裝
       
         在webpack.config.js配置
         const path = require('path')
         const HtmlWebpackPlugin = require('html-webpack-plugin')
    
         module.exports = {
            entry: './src/app.js',
             output: {
                 path: path.resolve(__dirname, 'dist'),
                 filename: 'app.js'
             },
             module: {
                 rules: [
                     {
                         test: /\.js$/,
                         exclude: /(node_modules)/,// 將不需要裝換的文件夾排除
                         use: {
                             loader: 'babel-loader',
                             options: {
                                 presets: ['env', 'react'] // 只需要在這里引用react
                             }
                         }
                     }
                 ]
             },
              plugins: [
                 new HtmlWebpackPlugin({
                     template: '.src/index.html'// 引用自定義html文件
                 }) // 生成html5文件
             ]
         }
    
  • 安裝樣式的插件

    > 安裝css
    yarn add style-loader@0.19.1 css-loader@0.28.8 --dev
    
    在項目src中新建一個index.css頁面,并在app.jsx中引入頁面
    import React from 'react'
    import ReactDOM from 'react-dom'
    import './index.css'
    
    安裝webpack打包css成獨立文件的插件
    yarn add extract-text-webpack-plugin@3.0.2 --dev
    
    在webpack.config.js中更改對css的配置配置
    
    引入 
    const ExtractTextPlugin = require('extract-text-webpack-plugin')
    
     {
            test: /\.css$/,
            use: ExtractTextPlugin.extract({ // 這里改變
                fallback: 'style-loader',
                use: 'css-loader'
            })
      }
    由于這是一個插件,需要在plugin中配置
    
    > 安裝sass
    
    yarn add sass-loader --dev
    yarn add node-sass --dev
    
    在webpack.config.js中rules css配置下添加
     {
            test: /\.scss$/,
            use: ExtractTextPlugin.extract({
                fallback: 'style-loader',
                use: ['css-loader', 'sass-loader']
            })
      }
    
  • 對圖片的處理

    yarn add url-loader --sev
    
    在webpack.config.js中配置
    {
              test: /\.(png|jpg|gif)$/,
              use: [
                  {
                      loader: 'url-loader',
                      options:{
                          limit: 8192 // 文件大于8k被當做文件
                      } 
                  }
              ]
     }
    
  • 對字體圖標的處理

    yarn add font-awesome
    
    {
              test: /\.(eot|svg|ttf|woff|woff2|otf)$/,
              use: [
                  {
                      loader: 'url-loader',
                      options:{
                          limit: 8192 // 文件大于8k被當做文件
                      } 
                  }
              ]
     }
    
  • 對公共模塊的處理

在plugin中處理

   const path = require('path')
   const webpack = require('webpack')  //為了引用webpack自帶方法
   const HtmlWebpackPlugin = require('html-webpack-plugin')
   const ExtractTextPlugin = require('extract-text-webpack-plugin')

   module.exports = {
       entry: './src/app.jsx',
       output: {
           path: path.resolve(__dirname, 'dist'),
           filename: 'js/app.js'
       },
       module: {
           rules: [
               {
                   test: /\.jsx$/,
                   exclude: /(node_modules)/, // 將不需要裝換的文件夾排除
                   use: {
                       loader: 'babel-loader',
                       options: {
                           presets: ['env', 'react'] // 自動根據(jù)環(huán)境打包
                       }
                   }
              },
               {
                   test: /\.css$/,
                   use: ExtractTextPlugin.extract({
                       fallback: 'style-loader',
                       use: ['css-loader']
                   })
               },
               {
                   test: /\.scss$/,
                   use: ExtractTextPlugin.extract({
                       fallback: 'style-loader',
                       use: ['css-loader', 'sass-loader']
                   })
               },
               {
                   test: /\.(png|jpg|gif|jpeg)$/,
                   use: [
                       {
                           loader: 'url-loader',
                           options:{
                               limit: 8192, // 文件大于8k被當做文件
                               name: 'resource/[name].[ext]'
                           } 
                       }
                   ]
               },
               {
                   test: /\.(eot|svg|ttf|woff|woff2|otf)$/,
                   use: [
                       {
                           loader: 'url-loader',
                           options:{
                               limit: 8192, // 文件大于8k被當做文件
                               name: 'resource/[name].[ext]'
                           } 
                       }
                   ]
               }
           ]
       },
       plugins: [
           new HtmlWebpackPlugin({
               template: './src/index.html'// 引用自定義html文件
           }), // 生成html5文件
           new ExtractTextPlugin('css/[name].css'), // 將樣式單獨打包出來生成新的css頁面
           // 提出公共模塊,webpack自帶
           new webpack.optimize.CommonsChunkPlugin({
               name: 'common',// 手動指定的通用木塊
               filename: 'js/base.js'
           })
       ]
   }
  • webpack 自動刷新處理webpack-dev-server

      yarn add webpack-dev-server
    
      在config下與plugin同級加上
      devServer: {
      }
      為了防止打包后的圖片在根目錄下找不到
      output: {
          path: path.resolve(__dirname, 'dist'),
          publicPath: '/dist/',  //在這里添加路徑
          filename: 'js/app.js'
      },
    
      編譯打包就用webpack-dev-server就可以了
    

使用react環(huán)境搭建項目

      yarn add react react-dom

      在app.js中引用react結構,并將app.js的后綴更改為jsx,webpack.config.js中的js配置也要變成jsx,入口文件的js也要更改為jsx

      import React from 'react'
      import ReactDOM from 'react-dom'

package.json的配置

      "scripts": {
        "dev": "node_modules/.bin/webpack-dev-server",
        "dist": "node_modules/.bin/webpack -p"
      },

這樣就可以使用yarn dev啟動項目
yarn dist 打包項目

react正式開始咯(上訴方法均為自己手打搭建一個react項目,了解每一步,接下來是react提供的項目創(chuàng)建方法)

react => 視圖層框架 組件化 JSX表達式 虛擬DOM
  • Facebook 開源的一個JavaScript庫
  • React結合生態(tài)庫構成一個MVC框架(vue也是mvc)
  • 特點:Declarative(聲明式編碼:只需要聲明在哪里做什么,無需關心如何實現(xiàn));Component-Based(組件化編碼);高效-高效的DOM Diff算法,最小化頁面重繪
  • 單向數(shù)據(jù)流
生態(tài)介紹

vue生態(tài):vue + vue-router + vuex + axios + babel + webpack
react生態(tài): react + react-router + redux + axios + babel + webpack

項目的創(chuàng)建(另一種方式,但是本人喜歡上面的手動配置,看得懂)

  yarn add / cnpm  install global/-g create-react-app (全局安裝)
  在工作區(qū)創(chuàng)建項目

  create-react-app 你的項目名稱

  cd 你的項目名稱

  cnpm / yarn start 啟動

JSX語法

  • 添加html

    let jsx = <div>this is a jsx programmer</div>
    
    ReactDOM.render(
          jsx, // 將jsx組件放到渲染的dom下
          document.getElementById('app)
    )
    
  • 添加樣式

    行內(nèi)樣式
    let style = {
        color: 'red'
    }
    let jsx = <div style={style}></div>
    
    引入class樣式
    在index.scss中設置
    body {
        .jsx {
              font-size: 16px;
         }
    }
    let jsx = <div className="jsx"></div> // react中使用className引用樣式名稱
    
  • 添加邏輯
    (1)使用變量

        let name = "pig"
        let jsx = <div>I am a {pig}</div>
        ReactDom.render(
              jsx,
              document.getElementById('app')
        )
    

    (2)條件判斷

         let truth = true
         let jsx = (//加括號的目的是為了換行的時候,編輯器不會給我們自動填補分號
              <div>
                    { // 條件判斷需要加上{}
                          truth ? <p>I am a pig</p> : <p>I am not a pig</p>
                    }
              </div>
         )
    

    (3)jsx中插入注釋

          {/*我是一個注釋*/} 
    

    (4)數(shù)組的使用

          let names = ['pig', 'dog', 'chicken']
          let jsx = (
              {
                  names.map((name,index) => <p key={index}>I am {name}</p>)
              }
          )
    
  • 添加組件
    (1)基礎

          function Component () {
                return <h1>I am a pig</h1>
          }
          ReactDom.render(
                <Component />, // 如果是變量直接飲用,如果是組件需要加上標簽
                document.getElementById('app')
          )
    

    (2)es6組件寫法

          class ES6Component extends React.Component{
                render () {
                      return <h1>I am a pig in es6</h1>
                }
          }
          ReactDom.render(
              <div>  // 兩個組件共存需要包裹在一個div中
                  <Component />
                  <ES6Component>
              </div>,
              document.getElementById('app')
          )
    

    (3)組件初始化變量

          class Component extends React.Component {
                constructor (props) {
                      super(props);
                      this.state = {
                            name: 'pig'
                      }
                }
                render () {
                     return <h1>I am a {this.state.pig}</h1>
                }
          }
    

    (4)更改組件初始化變量

          class Component extends React.Component {
                constructor (props) { // props在子組件中只能被使用不能被改變
                      super(props);
                      this.state = {
                            name: 'pig'
                      }
                }
                render () {
                    setTimeOut(() => {
                           this.setState({
                              name: 'Pi g Pig'
                           })
                    }, 2000)
                     return <h1>I am a {this.state.pig}</h1>
                }
          }
    

    (5)父組件傳值

          class Component extends React.Component {
                constructor (props) {
                      super(props)
                }
                render () {
                     return <h1>I am a {this.props.name}</h1>
                }
          }
          ReactDom.render(
                <Component name="pig" />,
                 docuement.getElementById('app')
          )
    

    (6)組件添加點擊事件(方法一)

          class Component extends React.Component {
                constructor (props) {
                      super(props);
                      this.state = {
                          age: 18
                      }
                      this.addAge = this.addAge.bind(this)
                }
                addAge () {
                    this.setState({
                        age : this.state.age + 1
                    })
                }
                render () {
                     return (
                          <div>
                                <h1>I am  {this.state.age} years old </h1>
                                <button onclick={this.addAge}><button />
                          </div>
                    )
                }
          }
          ReactDom.render(
                <Component />,
                 docuement.getElementById('app')
          )
    

(7)組件添加點擊事件(方法二)

        class Component extends React.Component {
              constructor (props) {
                    super(props);
                    this.state = {
                        age: 18
                    }
              }
              addAge () {
                  this.setState({
                      age : this.state.age + 1
                  })
              }
              render () {
                   return (
                        <div>
                              <h1>I am  {this.state.age} years old </h1>
                              <button onclick={(e) => {this.addAge(e)}}><button />
                        </div>
                  )
              }
        }
        ReactDom.render(
              <Component />,
               docuement.getElementById('app')
        )

(8)組件添加輸入框更改事件

        class Component extends React.Component {
              constructor (props) {
                    super(props);
                    this.state = {
                        age: 18
                    }
              }
              changeValue (e) {
                  this.setState({
                      age : e.target.value
                  })
              }
              render () {
                   return (
                        <div>
                              <h1>I am  {this.state.age} years old </h1>
                              <input type="text" onChange={(e) => {this.changeValue(e)}} />
                        </div>
                  )
              }
        }
        ReactDom.render(
              <Component />,
               docuement.getElementById('app')
        )

(9)容器性組件嵌套組件

        class Component extends React.Component {
              constructor (props) {
                    super(props);
                    this.state = {
                        age: 18
                    }
              }
              changeValue (e) {
                  this.setState({
                      age : e.target.value
                  })
              }
              render () {
                   return (
                        <div>
                              <h1>I am  {this.state.age} years old </h1>
                              <input type="text" onChange={(e) => {this.changeValue(e)}} />
                        </div>
                  )
              }
        }
        class Title extends React.Component{
              constuctor (props) {
                  super(props)
              }
              render (props) {
                  return <h1>{this.props.title}</h1>
              }
        }
        class App extends React.Component{
              render () {
                  return (
                      <div>
                          <Title title="app" />
                          <Component />  // 在這里引用小組件component
                      </div>
                  )
              }
        }
        ReactDom.render(
              <App />, // 這里換成App
               docuement.getElementById('app')
        )

(10)組件嵌套組件

        class Component extends React.Component {
              constructor (props) {
                    super(props);
                    this.state = {
                        age: 18
                    }
              }
              changeValue (e) {
                  this.setState({
                      age : e.target.value
                  })
              }
              render () {
                   return (
                        <div>
                              <h1>I am  {this.state.age} years old </h1>
                              <input type="text" onChange={(e) => {this.changeValue(e)}} />
                        </div>
                  )
              }
        }
        class App extends React.Component{
              render () {
                  return (
                      <div>
                          <h1>app</h1>
                          <Component />  // 在這里引用小組件component
                      </div>
                  )
              }
        }
        ReactDom.render(
              <App />, // 這里換成App
               docuement.getElementById('app')
        )

(11)容器性組件嵌套組件,傳值可以為任何html形式

        class Component extends React.Component {
              constructor (props) {
                    super(props);
                    this.state = {
                        age: 18
                    }
              }
              changeValue (e) {
                  this.setState({
                      age : e.target.value
                  })
              }
              render () {
                   return (
                        <div>
                              <h1>I am  {this.state.age} years old </h1>
                              <input type="text" onChange={(e) => {this.changeValue(e)}} />
                        </div>
                  )
              }
        }
        class Title extends React.Component{
              constuctor (props) {
                  super(props)
              }
              render (props) {
                  return <h1>{this.props.children}</h1> // 這里變成獲取子children
              }
        }
        class App extends React.Component{
              render () {
                  return (
                      <div>
                          <Title>
                                <span>我是spanspan</span>
                                <a href="">link</a>
                          </Title> //更改為html形式
                          <Component /> 
                      </div>
                  )
              }
        }
        ReactDom.render(
              <App />, // 這里換成App
               docuement.getElementById('app')
        )

(12)子組件給父組件傳值

    class Father extends React.Component {
       constructor (props) {
           super(props);
           this.state = {
               bgColor: 'red'
           }
       }
       changeMyBgColors (color) {
           this.setState({
               bgColor: color
           })
       }
       render () {
           return (
               <div style={{background: this.state.bgColor}}>
                   <h1>我是爸爸</h1>
                   <Child bgColor={this.state.bgColor} changeColor={(color) => {this.changeMyBgColors(color)}}/>
               </div>
           )
       }
   }
   class Child extends React.Component {
       constructor (props) {
           super(props)
       }
       changeMyBgColor () {
           this.props.changeColor('blue')
       }
       render () {
           return (
               <div>
                   <h2>我是baby</h2>
                   <button onClick={(e) => {this.changeMyBgColor(e)}}>我想改變我爸爸的背景顏色</button>
               </div>
           )
       }
   }
   ReactDOM.render(
       <Father />,
       document.getElementById('app')
   )

(13)兄弟之間的組件通信(子1傳父,父在傳子2)

        class Child1 extends React.Component{
           constructor (props) {
               super(props)
               this.state = {
                   color1: 'red'
               }
           }
           changeMyBrotherColor (props) {
               this.props.change2Color(this.state.color1)
           }
           render () {
               return (
                   <div>
                       <h2>我是孩子1</h2>
                       <button onClick={(e) => {this.changeMyBrotherColor(e)}}>我要改變我弟弟的顏色咯</button>
                   </div>
               )
           }
       }
       class Child2 extends React.Component{
           constructor (props) {
               super(props)
           }
           render () {
               return (
                   <div>
                       <h2 style={{color: this.props.color22}}>我是孩子2</h2>
                   </div>
               )
           }
       }
       class Father extends React.Component{
           constructor (props) {
               super(props)
               this.state = {
                   color2: 'yellow'
               }
           }
           changColor (colorsss) {
               this.setState({
                   color2: colorsss
               })
           }
           render () {
               return (
                   <div>
                       <h1>這是我的孩子們</h1>
                       <Child1 change2Color={(color) => {this.changColor(color)}}/>
                       <Child2 color22={this.state.color2}/>
                   </div>
               )
           }
       }
       ReactDOM.render(
           <Father />,
           document.getElementById('app')
       )

react生命周期

getDefaultProps // 初始化props屬性,props來自其他組件
getInitialState // 初始化組件的狀態(tài)
componentWillMount // 組件加載之前
render // 渲染
componentDidMount // 組件dom插入之后
componentWillReceiveProps // 接受父組件的傳遞
shouldComponentUpdate // 組件的更新處罰
componentWillUpdate // 組件要更新前
componentDidUpdate // 組件更新后
componentWillUnmount // 組件的銷毀

  • Mounting : 掛載階段

  • Updating: 運行時階段

  • Unmounting: 卸載階段

  • Error Handling: 錯誤處理

    import React from 'react'
    import ReactDOM from 'react-dom'
    
    import './index.scss'
    
    class Child extends React.Component{
        // 構造函數(shù)
       constructor (props) {
            super(props)
            this.state = {
                data: 'oldzhuzhu'
            }
            console.log('這里是初始化數(shù)據(jù)constructor')
        }
        componentWillMount () {
            // 組件渲染前
            console.log('componentWillMount')
        }
        componentDidMount () {
            // 組件渲染結束
            console.log('componentDidMount')
        }
        componentWillReceiveProps () {
            // 將要接受父組件傳來的props觸發(fā)
            console.log('componentWillReceiveProps')
        }
        shouldComponentUpdate () {
            // 子組件是不是應該更新
            console.log('shouldComponentUpdate')
            return true
            // 如果是false,后面的update就不會跟著更新
        }
        componentWillUpdate () {
            // 組件將要更新
            console.log('componentWillUpdate')
        }
        componentDidUpdate () {
            // 組件更新完成
            console.log('componentDidUpdate')
        }
        componentWillUnmount () {
            // 組件將要銷毀調(diào)用
            console.log('componentWillUnmount')
        }
        // 點擊事件
        handleClick () {
            console.log('這里是更新數(shù)組')
            this.setState({
                data: 'zhuzhuzhu'
            })
        }
        // 渲染
        render () {
            console.log('render')
            return (
                <div>
                    {this.state.data}
                    接收到的props: {this.props.data}
                    <button onClick={() => {this.handleClick()}}>更新組件</button>
                </div>
          
            )
        }
    }
    
    class Father extends React.Component{
        constructor (props) {
            super(props)
            this.state = {
                data: 'old props'
            }
        }
        changeData () {
            this.setState({
                data: 'new props',
                show: true
            })
        }
        byeChild () {
            this.setState({
                show: false
            })
        }
        render () {
            return (
                <div>
                    {
                        this.state.show ? <Child data={this.state.data}/> : null
                    }
                    <button onClick={() => {this.changeData()}}>改變子組件的props</button>
                    <button onClick={() => {this.byeChild()}}></button>
                </div>
            )
        }
    }
    
    ReactDOM.render(
        <Father />,
        document.getElementById('app')
    )
    

按順序輸出值:

constructor  // 構造函數(shù)初始化
componentWillMount  // 組件渲染前
render  // 組價渲染
componentDidMount  // 選件渲染完成
componentWillReceiveProps  // 子組件接收到父組件傳來的props
shouldComponentUpdate  // 是否組件進行更新,true更新,false接下來的周期不觸發(fā)
componentWillUpdate  // 組件更新前
render  //  更新
componentDidUpdate  // 組件更新結束
componentWillUnmount  // 組件被摧毀之前

react-router

1.router幾種方式
  • 頁面路由

      window.location.href = '地址' // www.baidu.com
      history.back()  //回退
    
  • hash 路由

    window.location = '#hash'
    window.onhashchange = function () {
        console.log('current hash' + window.location.hash)
    }
    
  • h5路由

    history.pushState('name', 'title', '/path')  // 推進一個狀態(tài)
    history.replaceState('name', 'title', '/path') // 更換一個狀態(tài)
    window.onpopstate = function () {
        console.log(window.location.href)
        console.log(window.location.pathname)
        console.log(window.location.hash)
        console.log(window.location.search)
    }
    
2. react-router幾種方式
  • hash

      import React from 'react'
      import ReactDOM from 'react-dom'
      import {HashRouter as Router,Route,Link} from 'react-router-dom'  // 這里是Hash
    
      import './index.scss'
    
      class A extends React.Component {
          constructor (props) {
              super(props)
          }
          render () {
              return (
                  <div>Component A</div>
              )
          }
      }
      class B extends React.Component {
          constructor (props) {
              super(props)
          }
          render () {
              return (
                  <div>Component B</div>
              )
          }
      }
      class Wrapper extends React.Component {
          constructor (props) {
              super(props)
          }
          render () {
              return (
                  <div>
                      <Link to="/a" >組件A</Link>
                      <br />
                      <Link to="/b" >組件B </Link>
                      {this.props.children}
                  </div>
              )
          }
      }
      ReactDOM.render(
          <Router>
               <Wrapper>
                  <Route path="/a" component={A}/>
                  <Route path="/b" component={B}/>
              </Wrapper>
          </Router>
         ,
          document.getElementById('app')
      )
    
  • browser

    如果改成
    import {BrowserRouter as Router,Route,Link} from 'react-router-dom'
    路徑地址都會變成 http://localhost:8080/a,
    此時請求的是后端代碼,在復制這個鏈接在其他頁面打開時,會報成404,因為后臺并沒有生成這個地址
    
3.router傳參,組件接受不同組件傳參
  • 引入switch
    import {HashRouter as Router,Route,Link,Switch} from 'react-router-dom'
  class A extends React.Component {
      constructor (props) {
          super(props)
      }
      render () {
          return (
              <div>
                  Component   A  
                  <Switch>
                      <Route 
                          exact // 必須完全符合path
                          path={`${this.props.match.path}`}
                          render={(route) => {
                              return <div>當前組件是不帶參數(shù)的A</div>
                          }}
                      />
                     <Route >
                          path={`${this.props.match.path}/sub`}
                          render={(route) => {
                              return <div>當前組件是sub</div>
                          }}
                      />
                      <Route 
                      path={`${this.props.match.path}/:id`} // 通過路由地址解析
                      render={(route) => {
                          return <div>當前組件是帶參數(shù)的A,參數(shù)是 : {route.match.params.id}</div>
                      }}/>
                  </Switch>
              </div>
          )
      }
  }
  class B extends React.Component {
      constructor (props) {
          super(props)
      }
      render () {
          return (
              <div>Component B</div>
          )
      }
  }
  class Wrapper extends React.Component {
      constructor (props) {
          super(props)
      }
      render () {
          return (
              <div>
                  <Link to="/a" >組件A</Link>
                  <br />
                  <Link to="/a/123" >帶參數(shù)的組件A</Link> 
                  <br />
                  <Link to="/a/sub" >/a/sub子路徑</Link>
                  <br />
                  <Link to="/b" >組件B </Link>
                  {this.props.children}
              </div>
          )
      }
  }
  
  ReactDOM.render(
      <Router>
           <Wrapper>
              <Route path="/a" component={A}/>
              <Route path="/b" component={B}/>
          </Wrapper>
      </Router>
     ,
      document.getElementById('app')
  )

開始正式共享單車項目知識點(react全家桶+ant ui 組件+公共機制封裝)

地址:https://github.com/yangxinjian/reactAntBike.git

  • react基礎知識,生命周期(見上部分的基礎知識點)
  • router4.0
  • redux集成開發(fā)
  • ant最實用基礎組件
  • ant柵格系統(tǒng)
  • Etable組件封裝
  • BaseForm組件封裝
  • 表格內(nèi)嵌單選,復選封裝
  • axios請求插件封裝
  • api封裝
  • 錯誤攔截
  • 權限,菜單封裝等
  • 地圖,圖表的使用

安裝腳手架(上述有步驟,可選擇自己搭建,也可以使用官方腳手架)

sudo cnpm install -g create-react-app

初始化項目

create-react-app bikesystem (你項目的名稱:注意不用大寫字母)

安裝react-router

yarn add react-router

啟動項目

yarn start

項目所需要的插件

  • 安裝react-router,axios
  • 安裝AntD
  • 暴露webpack配置文件
  • 安裝less-loader
  • 修改less-loader
sudo yarn add react-router-dom axios less-loader
sudo yarn add less
sudo yarn antd   (支付寶做的ui組件)

引用antd樣式

  import {Button} from 'antd'  // 引用某一個組件
  <Button>使用組件</Button>
  import 'antd/dist/antd.css'
  • 想要按需加載對應組件css,需要安裝babel,安裝后就無需引用上面的css
 sudo yarn add babel-plugin-import
 sudo yarn add less@^2.7.3
  在package.json 的babel下加入
  "plugins": [
  [
    "import",
    {
      "libraryName": "antd",
      "style": "css"
    }
  ]
]

暴露webpack文件,得到config文件夾

sudo yarn eject

更改config/webpack.config.js ,使項目能識別less文件,配置后重啟生效

  • 在 // style files regexes下 添加
const lessRegex = /\.less$/;
const lessModuleRegex = /\.module\.less$/;
  • 在 cssRegex引用后面下 添加less配置對象
{
          test: lessRegex,
          exclude: lessModuleRegex,
          use: getStyleLoaders(
            {
              importLoaders: 3,  // 這里不要與其他配置的數(shù)字一樣
              sourceMap: isEnvProduction && shouldUseSourceMap,
            },
            'less-loader'
          ),
          sideEffects: true,
        },
        {
          test: lessModuleRegex,
          use: getStyleLoaders(
            {
              importLoaders: 3,  // 這里不要與其他配置的數(shù)字一樣
              sourceMap: isEnvProduction && shouldUseSourceMap,
              modules: true,
              getLocalIdent: getCSSModuleLocalIdent,
            },
            'less-loader'
          ),
        },

項目架構

  • 在src中新建組件文件夾,取名component,分別根據(jù)項目搭建出header頭部文件夾,footer底部文件夾,NavLeft左菜單文件夾,以及在src下新建admin.js


    Jietu20190401-163524.jpg

    在admin.js中配置主結構,用row,col,并引入三個外部組件,注意?。。∪齻€外部組件的內(nèi)容不能為空,否則會報錯

          import React from 'react'
         import { Row, Col} from 'antd';
         import Header from './components/header';
         import Footer from './components/footer';
    
         export default class Admin extends React.Component{
             render () {
                 return (
                     <Row>
                         <Col span="3">
                             left
                         </Col>
                         <Col span="21">
                             <Header>
                                 header
                             </Header>
                             <Row>
                                 contet
                             </Row>
                             <Footer>
                                 footer
                             </Footer>
                         </Col>
                    </Row>
                 )
             }
         }
    
  • 作為主要的菜單結構,單獨封裝出一個js,寫在了config下的menuConfig.js中,請大家自行git clone 我的項目地址,本項目是開源的項目

  • public里文件是將要被打包部署到服務器上。一般是圖片等元素信息

項目中使用的功能方法

1. 請求外部的百度地圖下的天氣API

  • 先在百度地圖開放平臺,創(chuàng)建應用,選擇瀏覽器,生成自己的AK碼

  • 在代碼中安裝jsonp

     sudo yarn add jsonp --save
    
  • 封裝jsonp方法

      import JsonP from 'jsonp'
      export default class Axios {
          // 鏈式調(diào)用
          static jsonp (options) {
              return new Promise((resolve, reject) => {
                  JsonP(options.url,{
                      param: 'callback'
                  },function(err, response){
                      if (response.status == 'success') { // 成功回調(diào)
                          resolve(response);
                      } else {
                          reject(response.messsage); //  失敗回調(diào)
                      }
                  })
              })
          }
      }
    
  • 在組件中調(diào)用

    import axios from '../../axios'
    state={}
    componentWillMount () {
        this.getWeatherAPIData() // 調(diào)用方法
    }
    // 獲取天氣api,encodeURIComponent編碼對中文的處理
    getWeatherAPIData () {
            let city = '北京'
            axios.jsonp({
                url: 'http://api.map.baidu.com/telematics/v3/weather?location='+encodeURIComponent(city)+'&output=json&ak=3p49MVra6urFRGOT9s8UBWr2'  // api地址 , ak是你自己申請的應用ak
            }).then((res) => {
                if(res.status == 'success'){
                    let data = res.results[0].weather_data[0];  // 取當前的天氣
                    this.setState({
                        dayPictureUrl:data.dayPictureUrl,
                        weather:data.weather
                    })
                }
            })
        }
            // 在render中渲染
           <span className="weather-img">
               <img src={this.state.dayPictureUrl} alt="" />
            </span>
             <span className="weather-detail">
                  {this.state.weather}
             </span>
    

2.react-router4.0(不需要路由配置,一切皆組件,瀏覽器端)

  • 核心用法:

    1. HashRouter和BrowserRouter

       hash: http://localhost:3000/#/admin
       browser: http://localhost:3000/admin
      

    2.Route:path,exact,component,render --- 參考項目中的pages下的router-demo下的router2文件夾的內(nèi)容

           <Router>
              <Home> // home 是主界面,包含的都是他的子組件路由
                  <Route path="/" component={Main} exact></Route>
                  <Route path="/about" component={About}></Route>
                  <Route path="/topics" component={Topics}></Route>
              </Home>
          </Router>
    
          主界面加載子組件的地方,添加{this.props.children}
    

    3.NavLink,Link ------ 通過this.props.match接受路由帶的內(nèi)容--- 參考項目中的pages下的router-demo下的router1文件夾的內(nèi)容

          <HashRouter>
              {/* 需要根節(jié)點 */}
              <div>
                  <ul>
                      <li>
                          <Link to="/">Home</Link>
                      </li>
                      <li>
                          <Link to="/about">About</Link>
                      </li>
                      <li>
                          <Link to="/topics">Topics</Link>
                      </li>
                  </ul>
                  {/* /about會檢索到/和/about,所以防止加載兩次,加上exact精確匹配 */}
                  <Route path="/" component={Main}></Route>
                  <Route path="/about" component={About}></Route>
                  <Route path="/topics" component={Topics}></Route>
              </div>
          </HashRouter>
    

    4.Switch

          <Switch>
                      {/* switch只會加載一次,按順序 */}
                      <Route path="/" component={Main}></Route>
                      <Route path="/about" component={About}></Route>
                      <Route path="/topics" component={Topics}></Route>
                  </Switch>
    

    5.Redict

          <Redirect to="/admin/home" />
    
    1. withRouter 直接跳轉(zhuǎn)路由
      import {withRouter} from 'react-router-dom'   引入

      使用
      this.props.history.push({
              pathname: '/admin'
      })

      渲染,在export default 中增添
      withRouter(Form.create()(OrganizeManage))

3.項目中運用router實現(xiàn)菜單導航路由

  1. 根路由的編寫
  • 在src目錄下建立router.js文件 , 并在全局index.js中更換Router

  • 在router.js中引用app.js作為主框架

     import React from 'react'
     import {HashRouter, Route, Switch} from 'react-router-dom'
     import App from './App'
     import Login from './pages/login'
     import Admin from './admin'
     export default class IRouter extends React.Component{
         render () {
             return (
                 <HashRouter>
                     <App>
                         <Route path="/login" component={Login}/> (一級路由--登錄界面)
                         <Route path="/admin" component={Admin}/> (一級路由--登錄進來的頁面)
                     </App>
                 </HashRouter>
             )
         }
     }
    
  • 在app中引用子路由

    import React, { Component } from 'react';
    import logo from './logo.svg';
    import './App.css';
    class App extends Component {
      render() {
        return (
          <div>
            {this.props.children}
          </div>
        );
      }
    }
    export default App;
    
  • 在一級路由下嵌套二級路由,更改的admin界面下的路由配置

        <Route path="/admin" render={() => 
                      // 二級路由
                      <Admin>
                          <Route path="/admin/ui/button" component={Button}/>
                      </Admin>
                  }/>
    
      在admin.js中更改
      <Row className="content" >
                     {this.props.children}  // 這里引用
                  </Row>
    
  • 菜單路由link配置

     引用路由 在NavLeft頁面下
    import {NavLink} from 'react-router-dom'
    在menu-item中包裹路由
    <Menu.Item title={item.title} key={item.key}>
                  <NavLink to={item.key}>{item.title}</NavLink>  // 這里跳轉(zhuǎn)地址
              </Menu.Item>
    
  • 配置路由加載錯誤的情況下的展示頁面

先建立文件夾nomatch包裹404展示文件,再在路由里面引用

   <Switch>
               <Route path="/admin/ui/buttons" component={Buttons}/>
                <Route component={NoMatch}></Route>
   </Switch>

Ant design UI組件的基本使用

  • 在項目地址下的ui文件夾有基本的使用展示,你可以選擇clone我的項目下到本地進行查看,接下來的筆記介紹幾種初學者會遇到的使用

1. form組件實現(xiàn)登錄

  • 創(chuàng)建用戶名和密碼以及登錄摁鈕

        需要引用FormItem
        const FormItem = Form.item
        <Form>
                <FromItem>
                        <Input prefix={<Icon type="user" />} placeholder="請輸入用戶名"/>
                </FormItem>
                <FromItem>
                        <Input prefix={<Icon type="lock" />} placeholder="請輸入密碼"/>
                </FormItem>
                <FromItem>
                        <Button type="primary">登錄</Button>
                </FormItem>
        </Form>
    
  • 添加輸入驗證
    第一步:在render中創(chuàng)建getFieldDecorator對象

      const { getFieldDecorator } = this.props.form;
    

    第二步:給標簽內(nèi)嵌入js語法實現(xiàn)驗證

                    <FormItem>
                          {
                              getFieldDecorator('userName',{ // username是定義的用戶名變量,不同輸入框的命名要是分別的
                                  initialValue:'',
                                  rules:[
                                      {
                                          required:true,
                                          message:'用戶名不能為空'
                                      },
                                      {
                                          min:5,max:10,
                                          message:'長度不在范圍內(nèi)'
                                      },
                                      {
                                          pattern:new RegExp('^\\w+$','g'),  // 正則表達式都可以
                                          message:'用戶名必須為字母或者數(shù)字'
                                      }
                                  ]
                              })(
                                  <Input prefix={<Icon type="user"/>} placeholder="請輸入用戶名" />
                              )
                          }
                      </FormItem>
    

    第三步:通過Form創(chuàng)建表單

      class FormLogin extends React.Component 將前面的export default 去掉
      
      export default Form.create()(FormLogin); 在結尾中加入
    
  • 添加摁鈕點擊校驗
    第一步: 給摁鈕綁定事件

        <Button type="primary" onClick={this.handleSubmit}>登錄</Button>
    

    第二步:編寫事件

    handleSubmit = ()=>{
      let userInfo = this.props.form.getFieldsValue();
      this.props.form.validateFields((err,values)=>{
          if(!err){ // 如果沒有錯的情況下
              message.success(`${userInfo.userName} 恭喜你,您通過本次表單組件學習,當前密碼為:${userInfo.userPwd}`)
          }
      })
    }
    

2. datePicker日期控件的引用

想要設置默認值,需要引用moment插件

     sudo yarn add moment --save

        import moment from 'moment
            <FormItem label="生日" >
                        {
                            getFieldDecorator('birth', {
                                initialValue: moment('2018-08-08') , // 獲取moment
                                rules: [
                                    {
                                        required: true
                                    }
                                ]
                            })(
                                <DatePicker
                                    showTime
                                    format="YYYY-MM-DD"
                                />
                            )
                        }
                    </FormItem>

3.柵格左右大小分配格式提取

    const formItemLayout = { // 柵格樣式 復用
        labelCol: {
            xs: 24,
            sm: 4
        },
        wrapperCol: {
            xs: 24,
            sm: 8
        }
    }

   <FormItem {... formItemLayout}> 使用es6結構賦值
   </FormItem>

4.上傳文件

    <Upload
              listType="picture-card"
              howUploadList={false}
              // axtion是服務器的地址
             action="http://jsonplaceholder.typicode.com/posts/"
             nChange={this.handleChange}
     >
          {this.state.userImg?<img src={this.state.userImg} />:<Icon type="plus"></Icon>}
    </Upload>
 handleChange = (info) => { // 上傳圖像
    if (info.file.status === 'uploading') {
        this.setState({ loading: true });
        return;
    }
    if (info.file.status === 'done') {
        // 正常是調(diào)用服務器的上傳地址
    }
}

5. easy mock,語法參考mock.js

是一款可以適用于前端編寫線上接口,以便測試調(diào)用,自動創(chuàng)建項目,編寫接口,放入數(shù)據(jù)

' result|10': [ { // 生成十條數(shù)據(jù)
    "code": 0,
    "message": '失敗',
    "result|10": [{
      'id|+1': 0, // 遞增+1
      'userName': '@cname', // 隨機的名字
      'sex|1-2': 1, // 隨機在1-2中選擇
      'telephone': '888888',
      'state|1-5': 1,// 隨機在1-5中選擇
      'interest|1-8': 1,// 隨機在1-8中選擇
      'birth': '1995-06-30',
      'address': '地球',
 }]

6. axios使用與封裝

  • 最簡單的引用

      // 動態(tài)獲取mock數(shù)據(jù),根據(jù)上步創(chuàng)建的接口獲取
    import axios from 'axios
    request = () => {
      let baseUrl = 'https://www.easy-mock.com/mock/5caffee40ee3ff114ba3e62b/yxjapi' 
      axios.get(`${baseUrl}/table/list`).then((res) =>{
          if (res.data.code == '0') {
              this.setState({
                  dataSource2: res.data.result
              })
          }
      })
    }
    
  • 封裝axios請求

    static ajax(options){
      const baseURL = 'https://www.easy-mock.com/mock/5caffee40ee3ff114ba3e62b/yxjapi'  // 接口地址
      return new Promise((resolve,reject) => {
          axios({
              url: options.url,
              method: 'get',
              baseURL: baseURL,
              timeout: 7000,
              params: (options.data.params && options.data) || ''
          }).then((response) => {
              if (response.status == '200') {// http請求自帶status
                  let res = response.data
                  if (res.code == '0') { // 項目服務器后臺接口業(yè)務層面的判斷
                      resolve(res)
                  }else {
                      Modal.info({
                          title: '提示',
                          content: res.data.messsage
                      })
                  }
              }else {
                  reject(response.data)
              }
          })
      })
    }
    
  • 使用

    axios.ajax({
          url: '/table/list',
          data: {
              params: {
                  page: 1
              }
          }
      }).then((res) => {
          if (res.code == '0') {
              this.setState({
                  dataSource2: res.result
              })
          }
      })
    

7. 表格分頁的封裝

    // 分頁的封裝
pagination (data, callback) {
    let page = {
        onChange: (current) => {
            callback(current)
        },
        current: data.result.page,
        pageSize: data.result.page_size,
        total: data.result.total,
        showTotal: () => {
           return `共${data.result.total}條` 
        },
        showQuickJumper: true
    }
    return page
}
  • 使用

    request = () => {
      axios.ajax({
          url: '/table/list',
          data: {
              params: {
                  page: 1
              },
              isShowLoading: true
          }
      }).then((res) => {
          if (res.code == '0') {
              this.setState({
                  dataSource2: res.result.list,
                  selectedRowKeys: [], // 刪除后的重置
                  selectedRows: null, // 刪除后的重置
                  pagination: util.pagination(res, (current)=>{ // 根據(jù)點擊的頁瑪進行數(shù)據(jù)變化處理
                      // to-do
                      _this.params.page = current
                      _this.request()
                      message.success(`當前頁${current}`)
                  })
              }) 
          }
      })
    <Table 
                      bordered
                      dataSource={this.state.dataSource2}
                      columns={columns}
                      pagination={this.state.pagination}
                  />
    

8 . 組件使用外部class的form表單,獲取表單對象

綁定wrappedComponentRef方法輸出表達對象給dataform自定義,通過

  let drgInfo = this.dataForm.props.form.getFieldsValue() 獲取數(shù)據(jù)

   <OpenFormDatas wrappedComponentRef={(datas) => {this.dataForm = datas}} />

9. 地圖功能的實現(xiàn)(基于項目中的騎車路線)

  • 創(chuàng)建ak,加載百度地圖sdk
  • 地圖初始化,添加地圖控件
  • 繪制路線(通過坐標點)
  • 繪制服務區(qū)地圖

(1) 創(chuàng)建ak,加載百度地圖sdk

第一步:打開map.baidu.com,找到地圖開放平臺,點擊進入
第二步:點擊開發(fā)文檔,點擊web開發(fā)下的JavaScript API
第三步:在產(chǎn)品簡介中,點擊申請秘鑰ak,創(chuàng)建應用,選擇瀏覽器 端,白名單中設置*號,點擊創(chuàng)建即可獲取ak值
第四步:在public文件夾下的index.html的head部分中引用以下代碼

    <script type="text/javascript" src="http://api.map.baidu.com/api?v=2.0&ak=您的ak秘鑰"></script>

(2)初始化地圖

第一步:創(chuàng)建一個渲染地圖的容器,取一個id值

    <div id="orderDetailMap" className="order-map"></div>

第二步:為獲取地圖對象添加方法,并且添加控件,同時在接口數(shù)據(jù)返回后調(diào)用方法

     renderMap = (result)=>{
            this.map = new window.BMap.Map('orderDetailMap');
            // 添加地圖控件
            this.map.centerAndZoom('北京',11); // 設置地圖的中心點
            this.addMapControl();
      }
      // 添加地圖控件
         addMapControl = ()=>{
             let map = this.map;
             map.addControl(new window.BMap.ScaleControl({ anchor: window.BMAP_ANCHOR_TOP_RIGHT}));
             map.addControl(new window.BMap.NavigationControl({ anchor: window.BMAP_ANCHOR_TOP_RIGHT }));
         }

(3)繪制路線

      // 繪制用戶的行駛路線
drawBikeRoute = (positionList)=>{
    let map = this.map;
    let startPoint = '';
    let endPoint = '';
    // lon 經(jīng)度 lat 緯度
    if (positionList.length>0){ // 判斷行駛軌跡是否存在
        let first = positionList[0]; 
        let last = positionList[positionList.length-1];
        startPoint = new window.BMap.Point(first.lon,first.lat);// 獲取地圖點
        
        // 創(chuàng)建開始坐標點的圖標
        let startIcon = new window.BMap.Icon('/assets/start_point.png',
        new window.BMap.Size(36,42),{// 整個圖標
            imageSize:new window.BMap.Size(36,42), // 圖片的大小
            anchor: new window.BMap.Size(18, 42)
        })
        
        // marker是為了將icon圖標嵌入到地圖里面,并且要設置坐標點實現(xiàn)點
        let startMarker = new window.BMap.Marker(startPoint, { icon: startIcon});
        this.map.addOverlay(startMarker);

        // 創(chuàng)建結束坐標點的圖標
        endPoint = new window.BMap.Point(last.lon, last.lat);
        let endIcon = new window.BMap.Icon('/assets/end_point.png', new window.BMap.Size(36, 42), {
            imageSize: new window.BMap.Size(36, 42),
            anchor: new window.BMap.Size(18, 42)
        })
        
        // marker是為了將icon圖標嵌入到地圖里面,并且要設置坐標點實現(xiàn)點
        let endMarker = new window.BMap.Marker(endPoint, { icon: endIcon });
        this.map.addOverlay(endMarker);

        // 連接路線圖
        let trackPoint = [];
        for(let i=0;i<positionList.length;i++){
            let point = positionList[i];
            trackPoint.push(new window.BMap.Point(point.lon, point.lat));
        }

        // 設置線的樣式
        let polyline = new window.BMap.Polyline(trackPoint,{
            strokeColor:'#1869AD',
            strokeWeight:3,
            strokeOpacity:1
        })
        this.map.addOverlay(polyline);
        this.map.centerAndZoom(endPoint, 11);
    }
    
}

(4) 繪制服務區(qū)地圖

       // 繪制服務區(qū)
drwaServiceArea = (positionList)=>{
    // 連接路線圖
    let trackPoint = [];
    for (let i = 0; i < positionList.length; i++) {
        let point = positionList[i];
        trackPoint.push(new window.BMap.Point(point.lon, point.lat));
    }
    // 繪制服務區(qū)
    let polygon = new window.BMap.Polygon(trackPoint, {
        strokeColor: '#CE0000',
        strokeWeight: 4,
        strokeOpacity: 1,
        fillColor: '#ff8605',
        fillOpacity:0.4
    })
    this.map.addOverlay(polygon);
}

10. echart的使用

  • 安裝

    sudo yarn add echarts-for-react --save
    sudo yarn add echarts --save
    
  • 引用

    import ReactEcharts from 'echarts-for-react';
    import echarts from 'echarts/lib/echarts'
    可以按需引用echart中某一個組件
    // 引入餅圖和折線圖
    import 'echarts/lib/chart/pie'
    
  • 使用

  getOption() {
    let option = {
        title: {
            text: '用戶騎行訂單',
            x : 'center'
        },
        legend : {
            orient: 'vertical',
            right: 10,
            top: 20,
            bottom: 20,
            data: ['周一','周二','周三','周四','周五','周六','周日']
        },
        tooltip: {
            trigger : 'item',
            formatter : "{a} <br/> : {c} (u0z1t8os%)"
        },
        series: [
            {
                name : '訂單量',
                type : 'pie',
                radius : '55%',
                center : [
                    '50%', '60%'
                ],
                data:[
                    {
                        value:1000,
                        name:'周一'
                    }
                ],
                itemStyle : {
                    emphasis: {
                        shadowBlur: 10,
                        shadowOffsetX: 0,
                        shadowColor: 'rgba(0, 0, 0, 0.5)'
                    }
                }
            }
        ]
    }
    return option;
}
 // render中渲染
  <ReactEcharts
           option={this.getOption()} 
           style={{ height: 500 }}/>

11. 富文本編輯器的使用 ------ react-draft-wysiwyg

  • 安裝富文本組件以及將組件內(nèi)容裝換成html格式的draftjs

       sudo yarn add react-draft-wysiwyg draftjs-to-html --save  
    
  • 使用 參考項目代碼把。。。文字過長了,不讓發(fā)了,我都提交了

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

相關閱讀更多精彩內(nèi)容

  • 1).React核心概念 虛擬DOM(Virtual Document Object Model)假如存在如下的H...
    DoEmpty閱讀 565評論 0 0
  • 前言 這篇文章用來記錄從無到有的Webpack + React的學習筆記。 開始 一開始什么都沒有。 step1:...
    cab240f6e992閱讀 281評論 0 0
  • create-react-app 通過創(chuàng)建一個已經(jīng)完成基本配置的應用,讓開發(fā)者快速開始React應用的開發(fā)。 安裝...
    愛翔是我二媳婦閱讀 294評論 0 0
  • 3. JSX JSX是對JavaScript語言的一個擴展語法, 用于生產(chǎn)React“元素”,建議在描述UI的時候...
    pixels閱讀 2,982評論 0 24
  • 最是莫嘆韶華念 夜幽寒窗闌珊 六出飛花冰時延 翠竹化作瓊枝扇 沉香燃紅綃短 錦貌貂裘盈款款 玲瓏步搖星燭淡 一簪挑...
    暗塵隨馬閱讀 460評論 0 1

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