嘗試用React寫幾個通用組件 - 帶搜索功能的下拉列表,開關切換按鈕,彈出框

嘗試用React寫幾個通用組件 - 帶搜索功能的下拉列表,開關切換按鈕,彈出框

近期正在逐步摸索學習React的用法,嘗試着寫幾個通用型的組件,總體項目仍是根據webpack+react+css-medules構建,
項目代碼 https://github.com/sunrun93/react-custom-components
啓動項目:css

git clone git@github.com:sunrun93/react-blog-app.git
npm i 
npm start

啓動項目後,如若發現本地css未生效,請在node_modules\react-scripts\config\webpack.config.dev.js和node_modules\react-scripts\config\webpack.config.prod.js找到對應的css-loader, 在其options中添加以下兩項(modules,localIdentName):node

loader: require.resolve('css-loader'),
 options: {
        modules: true, 
        localIdentName: '[name]__[local]__[hash:base64:5]'
}

主要組件包括:react

. Search-box:具備輸入搜索功能的下拉列表,僅支持單項選中,並可根據用戶輸入匹配篩選選項,調用方式以下:


let options = [
      { id: '1', label: 'Option-A', value: 'Option-A' },
      { id: '2', label: 'Option-B', value: 'Option-B' },
      { id: '3', label: 'Option-C', value: 'Option-C' },
      { id: '4', label: 'Option-D', value: 'Option-D' }
    ];
<SearchBox options={options}/> //顯示label
Toggle-btn:模仿ios系統中的開關按鈕,基於checkbox實現一個toggle-btn的小插件。樣式上,隱藏checkbox勾選框的樣式,將troggle-btn的樣式添加到checkbox的label上:

<input type="checkbox" checked={this.state.isCheck} className={this.state.isCheck?styles.greenDotRight:styles.greenDotLeft}/>
     <label></label>
input[type='checkbox'] {
          visibility:hidden;
          position:absolute;
      }

  .greenDotLeft+label{
      width:30px;
      height: 30px;
      border-radius: 15px;
      background-color:lightgray;
      display: inline-block;
      position: absolute;
      left: 0;
  }

  .greenDotRight+label{
      width: 30px;
      height: 30px;
      border-radius: 15px;
      background-color: lawngreen;
      display: inline-block;
      position: absolute;
      right:0;
  }

調用方式以下:webpack

<ToggleBtn isChecked={isChecked} onClick={toggleEvent}/> //onClick觸發想要調用的方法,接受一個參數拿到當前的狀態,isChecked可定義初始化的值
dialog-component 彈出框/對話框組件 - 彈出框或者對話框組件在web應用中很是的常見,所以嘗試使用react構造一個對話框組件。

首先咱們考慮一下兩點:ios

  1. 彈出框顯示時,一般狀況會生成一個遮罩層,使用戶沒法觸發頁面上的其餘操做。
  2. 彈出框的DOM節點在根節點生成,顯示或關閉不能影響本來的頁面結構。
    所以,咱們考慮經過兩部分來構造這個組件,並經過ReactDOM提供的 ReactDOM.unstable_renderSubtreeIntoContainer方法將其插入到DOM的根節點,結構以下(Layer層爲遮罩層,Dialog爲咱們實際構造的組件):
<Layer> 
    <Dialog> 
        /* customer defined dialog content */
    </Dialog>
</Layer>

Layer層的具體實現以下,具體請查看git

class Layer extends React.Component {
    constructor(props) {
        super(props);
    }
    componentDidMount() {
        this.renderLayer();
    }
    componentDidUpdate() {
        this.renderLayer();
    }
    componentWillUnmount() {
        this.removeLayer();
    }
    renderLayer() {
        if (!this.props.open) {
            this.removeLayer()
        } else {
            if (!this.layer) {
                this.layer = document.createElement("div");
                this.layer.className = styles.layer;
                document.body.appendChild(this.layer);//首先將Layer節點添加到DOM中
            }
            ReactDOM.unstable_renderSubtreeIntoContainer(this, this.props.children, this.layer);
            //而後經過unstable_renderSubtreeIntoContainer方法將其放到根結點下
        }
    }
    removeLayer() {
        if (!this.layer) {
            return;
        }
        ReactDOM.unmountComponentAtNode(this.layer);
        document.body.removeChild(this.layer);
        this.layer = null;
    }
    render() {
        return null;
    }
}

具體實現方式:https://github.com/sunrun93/react-custom-componentsgithub

相關文章
相關標籤/搜索