react 的彈出層你們一般怎麼寫
阿新 • • 發佈:2018-11-09
流程
- 分析:互動意圖以及需求
- 結構:HTML+CSS實現靜態結構
- 介面:定義公共介面
- 實現:抽象=>細節,實現功能介面、暴露事件
- 完善:便利介面,外掛封裝、重構等
例項 :Modal元件
模態元件是最常用到等元件,Modal通過彈出一個高聚集性的視窗來立即捕獲當前使用者注意力
需求分解
- 模態視窗水平錘子居中
- 半透明遮罩。
- 可以自定義標題和內容
- 提供取消和確認操作
頁面結構分解
- 遮罩層>窗體結構
- 窗體>頭部+內容+按鈕
頁面結構程式碼:
<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%;
}
定義公共介面和方法
-
介面設定
- 內容配置
- 動畫設定
- 取消操作回掉
- 確認操作回掉
介面程式碼實現
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') // } })
-
方法呼叫
- 顯示彈窗
- 關閉彈窗
程式碼實現
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);
})
}
}
元件完善
- 一個元件寫好之後肯定是希望它能在儘可能多的地方被使用,所以模組化非常重要。多個團隊如果存在使用不同的模組管理工具的情況,我們就需要在暴露介面的時候做好相容
// 支援commonjs
if (typeof exports === 'object') {
module.exports = Modal;
// 支援amd
} else if (typeof define === 'function' && define.amd) {
define(function() {
return Modal
});
} else {
// 直接暴露到全域性
window.Modal = Modal;
}
- 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的一個非常關鍵的原因。