1. 程式人生 > >簡單的JavaScript元件化實現

簡單的JavaScript元件化實現

作為一名前端菜鳥,最近看react例子,根據理解自己也簡單實現了一下元件的繼承和事件機制。

程式碼在這裡

原始的元件寫法

(function($) {
    $.pluginName = function(element, options) {
        var defaults = {
            title: '',
            content: '',
            showOKBtn: 1, // 顯示確定按鈕
            showCCBtn: 1, // 顯示取消按鈕
            onFoo: function() {}
// callback } var plugin = this; plugin.settings = {} var $element = $(element); plugin.init = function(options) { this.settings = $.extend({}, defaults, options); this.initNode(options); } // public method. plugin.
show = function() { // ... } plugin.hide = function() { // ... } plugin.initNode = function(options) { var $okBtn = $element.find(''), $content = $element.find(''); // .... // 部分邏輯 $content.
text(plugin.settings.content); $okBtn.on('click', $.proxy(this.onOk, this)); } plugin.onOk = function(){ this.hide(); plugin.settings.onFoo(); } plugin.init(); } $.fn.pluginName = function(options) { return this.each(function() { if (undefined == $(this).data('pluginName')) { var plugin = new $.pluginName(this, options); $(this).data('pluginName', plugin); } }); } })(jQuery); // 使用 var template = '<div>...彈框html...</div>'; $(template).pluginName({ content: '確定刪除該地址' }).show();

一般我們寫得入門級jquery元件,基本就是這樣一個模板。 這裡我們實現了一個基本的彈窗元件,也完成了需求方的要求,oh ye!enter image description here

某天需求mm說我們要加一個confirm資訊的彈框,只要一個確定按鈕!!還好還好。元件中本來就加了options.showCCBtn的配置,例項化的時候傳一個引數就可以了。分分鐘解決了mm的問題,還得到mm的讚許,想想都有點小激動呢。

處理一套風格相似的元件的時候,通過傳遞不同的引數來控制不同的ui顯示和邏輯程式碼執行,確實可以解決問題,隨著功能的一步步增加,這個元件就變得越來越臃腫,程式碼耦合成度變高,到最後自己都搞不清楚每個引數不同值代表的意思。況且在團隊中都是多個人維護同一個元件,這簡直就是一場悲劇。從此mm的態度也變得不好,你還坑害了維護元件的好基友。

繼承

這時候面向物件的思維就出場了enter image description here我們發現設定titile, 關閉窗體是大家共有的功能。這裡可以抽象成一個基礎元件,新的元件繼承這個元件即可。

(function() {
    var BaseWindon = Kclass.extend({
        init: function(options){
           //公共功能 
            $titleElm.text(options.title);
            $closeElm.on('click', $.proxy(this.close, this));
        },
                    // 銷燬
        destroy: function(){

        }
        close: function(){

        }
    };
    return BaseWindon;
})()

 在子類中 require('BaseWindon');

 (function() {
    var AddAddressWindon = BaseWindon.extend({
        init: function(options){
            // 呼叫parent的init
            this.supr();
        },
        validate: function(){

        },
        // 元件自己的功能
        submit: function(){

        }
    };
    return AddAddressWindon;
})()

javascript oo的實現有很多種,我用了ded/klass,supr的實現比較巧妙。主要原理為:獲取方法的程式碼字串,通過正則檢測字串中是否包含 supr,若包含, 則改寫該方法,在改寫的方法中動態的改變this.supr,使其指向父類同名方法,以完成呼叫父類方法的目的。具體的原理可看參考野生小技巧–繼承中的super()實現

這時需求mm又來了,需求mm說當用戶點選確定之後要加一個其他功能,其實第一個例子中,我們也可以實現這樣的功能。我們可以傳遞一個callback onFoo。

我們需要引入一種更加優雅的方式,參考node的事件機制。大家知道,Node.js能夠在眾多的後端JavaScript技術之中脫穎而出,正是因其基於事件的特點而受到歡迎。

事件機制

事件機制對應著一種設計模式-觀察者模式。

(function() {
    var win = new BaseWindow();

    win.on('ok', function(){
        console.log('on ok!');
    });

    win.emit('ok');  
    // log  --- on ok!
})()

實現在這裡

顯然事件驅動的方式更加優雅,相比之下第一種手動觸發callback的方式顯得有點out。事件機制的方式,在監聽on和觸發emit的時機上也顯得更加靈活,對於只需要觸發一次的callback,你只需要用once函式來監聽。寫程式碼好像突然變得好爽好舒服。

最後記得提供一個銷燬元件的方法,一個簡單的元件就完成了。 完整的程式碼在這裡

當然要更好的元件還需要提供

  1. 模板機制
  2. 雙向繫結                                          
轉載自前端亂燉http://www.html-js.com/article/2875