1. 程式人生 > >react 的彈出層你們一般怎麼寫

react 的彈出層你們一般怎麼寫

流程

  1. 分析:互動意圖以及需求
  2. 結構:HTML+CSS實現靜態結構
  3. 介面:定義公共介面
  4. 實現:抽象=>細節,實現功能介面、暴露事件
  5. 完善:便利介面,外掛封裝、重構等

例項 :Modal元件

模態元件是最常用到等元件,Modal通過彈出一個高聚集性的視窗來立即捕獲當前使用者注意力

需求分解

  1. 模態視窗水平錘子居中
  2. 半透明遮罩。
  3. 可以自定義標題和內容
  4. 提供取消和確認操作

頁面結構分解

  1. 遮罩層>窗體結構
  2. 窗體>頭部+內容+按鈕

頁面結構程式碼:

<div class="m-modal">
    <div class="modal_align"></div>
    <div class="modal_wrap">
        <div class="modal_head"></div>
        <div class="modal_body"></div>
        <div class="modal_foot">
            <a href="" class="confirm"></a>
            <a href="" class="cancel"></a>
        </div>
    </div>
</div>

使用新增一個輔助線的方法<div class="modal_align"></div>使窗體垂直水平居中
css居中關鍵實現程式碼

.m-modal{
    text-align:center;
}
.modal_align,.modal_wrap{
    display:inline-block;
    vertical-align:middle;
}
.modal_align{
    height:100%;
    width:1px;
    line-height:100%;
}

定義公共介面和方法

  • 介面設定

    1. 內容配置
    2. 動畫設定
    3. 取消操作回掉
    4. 確認操作回掉

    介面程式碼實現

var modal = new Modal({
    // 1. 內容配置
    cotent: "內容在此", //可傳入節點和字串
    // 2. 動畫設定
    animation: {
        enter: 'bounceIn',
        leave: 'bounceOut'
    }
    // 3. confirm回撥
    onConfirm: function(){
        console.log('ok')
    },
    // 4. cancel糊掉
    onCancel: function(){
        console.log('cancel')
    // }
})
  • 方法呼叫

    1. 顯示彈窗
    2. 關閉彈窗

程式碼實現

modal.show(/* 可以傳入內容 */);
modal.hide();

這裡使用的是TDD思想,行為驅動開發,先定義使用方式,再去開發

實現思路

巨集觀的角度去思考有哪些業務邏輯,首先構建

function Modal(){
}
Modal.prototype.show=function(){
    //顯示邏輯
};
Modal.prototype.show=function(){
    //隱藏邏輯
};

在Modal物件裡去配置例項的私有變數,最後執行初始化事件繫結。

function Modal(options){
options = options || {};

// 即 div.m-modal 節點
//每個Modal被示例後都應該是獨立的,所以我們需要複製傳入的目標節點
this.container = this._layout.cloneNode(true);

// body 用於插入自定義內容
this.body = this.container.querySelector('.modal_body');

// 窗體節點,在應用動畫時有用
this.wrap = this.container.querySelector('.modal_wrap');

// 將options 複製到 元件例項上
extend(this, options);

this._initEvent();
}
// 顯示彈窗
extend(Modal.prototype,
    show: function(content){
      //如果傳入內容久設定內容
      if(content) this.setContent(content);
    
      document.body.appendChild(this.container);
      animateClass(this.wrap, this.animation.enter)
    
    
    },
    hide: function(){

      var container = this.container;

      animateClass(this.wrap, this.animation.leave, function(){
        document.body.removeChild(container);
      })
      
    }
}

元件完善

  1. 一個元件寫好之後肯定是希望它能在儘可能多的地方被使用,所以模組化非常重要。多個團隊如果存在使用不同的模組管理工具的情況,我們就需要在暴露介面的時候做好相容
// 支援commonjs
if (typeof exports === 'object') {
    module.exports = Modal;
// 支援amd
} else if (typeof define === 'function' && define.amd) {
    define(function() {
    return Modal
});
} else {
    // 直接暴露到全域性
    window.Modal = Modal;
}
  1. react給了我一個思路就是將HTML裝入js。這樣別人需要用到我做好的元件時,只需要引入js包,不必再跑到html檔案裡去複製結構
var template = 
'<div class="m-modal">\
<div class="modal_align"></div>\
<div class="modal_wrap animated">\
  <div class="modal_head">標題</div>\
  <div class="modal_body">內容</div>\
  <div class="modal_foot">\
    <a class="confirm" href="#">確認</a>\
    <a class="cancel" href="#">取消</a>\
  </div>\
</div>\
</div>';

把節點用字串方式拼接,然後再插入到DOM中

// 將HTML轉換為節點
function html2node(str){
    var container = document.createElement('div');
    container.innerHTML = str;
    return container.children[0];
}

這樣別人只需要引入js檔案就能獲得我寫好的元件。

當然複雜的元件對於結構的拼接要更復雜,react的JSX很好用,同時兼具react的diff演算法,能快速計算出需要渲染的部分,非常好用。所以元件化也是我推崇react的一個非常關鍵的原因。