利用bootstrap的modal組件自定義alert,confirm和modal對話框

来源:http://www.cnblogs.com/lyzg/archive/2016/03/01/5229217.html
-Advertisement-
Play Games

由於瀏覽器提供的alert和confirm框體驗不好,而且瀏覽器沒有提供一個標準的以對話框的形式顯示自定義HTML的彈框函數,所以很多項目都會自定義對話框組件。本篇文章介紹自己在項目中基於bootstrap的modal組件,自定義alert,confirm和modal對話框的經驗,相對比較簡單實用,...


 

由於瀏覽器提供的alert和confirm框體驗不好,而且瀏覽器沒有提供一個標準的以對話框的形式顯示自定義HTML的彈框函數,所以很多項目都會自定義對話框組件。本篇文章介紹自己在項目中基於bootstrap的modal組件,自定義alert,confirm和modal對話框的經驗,相對比較簡單實用,希望能對你有所參考價值。(代碼下載

1. 實例展示

詳細的代碼可通過前面給出的下載鏈接下載源碼去瞭解,代碼量不大,這三個組件加起來只有200多行

image

如果你有javascript的組件開發經驗,我這個層級的代碼相信你一下子就能看明白。源碼中我還給出了一個demo,這個demo模擬了一個比較貼近現實需求的一個場景:

1)用戶點擊界面上的某個按鈕,打開之前定義的一個modal框:

image

2)用戶在打開的modal框內填寫一些表單,點擊確定的時候,會觸發一些校驗:

沒填email時:

image

填寫了email之後:

image

這兩個提示其實是為了演示Alert和Confirm的效果硬塞進去的,實際上可能沒有這麼彆扭的功能。

3)在提示Password為空的時候,細心的人會發現那個確定按鈕處於一個禁用的狀態,這個考慮是因為確定按鈕最終要完成的是一些非同步任務,在非同步任務成功完成之前,我希望modal組件都不要關閉,並且能夠控制已點擊的按鈕不能重覆點擊;

4)我用setTimeout模擬了一個非同步任務,這個非同步任務在點擊確定按鈕之後,3s才會回調,並且:

當email輸入admin@admin 的時候,會給出提交成功的提示,確定之後就會關閉所有的彈框:

image

當email輸入其它值得時候,會給出提交失敗的提示,並且modal框會依然顯示在那裡:

image

image

在組件定義裡面,尤其是註冊按鈕這一塊,我加了一些AOP編程的處理,同時利用了jquery的延遲對象,來實現我需要的非同步編程,詳情請閱讀源碼,有問題可以在評論區交流賜教。

2. 組件需求

有時候為了寫一個好用的組件,只需要把它的大概原型和要對外部提供的介面確定下來,就已經完成這個組件編寫最重要的工作了,雖然還沒有開始編碼。以本文要編寫的這幾個組件來說,我想要的這幾個組件的原型和調用形式分別是這樣的:

1)自定義alert框

原型是:

image

調用時最多需要兩個參數,一個msg用來傳遞要顯示的提示內容,一個onOk用來處理確定按鈕點擊時候的回調,調用形式有以下2種:

//1
Alert('您選擇的訂單狀態不符合當前操作的條件,請刷新列表顯示最新數據後再繼續操作!');
//2
Alert({
    msg: '您選擇的訂單狀態不符合當前操作的條件,請刷新列表顯示最新數據後再繼續操作!',
    onOk: function(){
    }
});

第一種是沒有回調的情況,那麼直接傳遞msg即可,第二種是有回調的情況,用options對象的方式來傳遞msg和onOks回調這兩個參數。不管onOk回調有沒有,點擊按鈕的時候都要關閉彈框。

2)自定義confirm框

這個框的原型跟alert框只差一個按鈕:

image

調用形式只有一種:

Confirm({
    msg: '您選擇的訂單狀態不符合當前操作的條件,請確認是否要繼續操作!',
    onOk: function(){

    },
    onCancel: function(){
        
    }
});

onCancel是在點擊取消按鈕時候的回調。不管onOk和onCancel回調有沒有,點擊按鈕的時候都要關閉彈框。onCancel回調可以沒有。

3)自定義modal框

原型:

image

調用形式:

var modal = new Modal({
    title: '',
    content: '',
    width: 600,
    buttons: [
        {
            html: '<button type="button" class="btn btn-sm btn-primary btn-ok">確定</button>',
            selector: '.btn-ok',
            callback: function(){
                //點擊確定按鈕的回調
            }
        },
        {
            html: '<button type="button" class="btn btn-sm btn-default btn-cancel">取消</button>',
            selector: '.btn-cancel',
            callback: function(){
                //點擊取消按鈕的回調
            }
        }
    ],
    onContentReady: function(){
        //當modal添加到DOM並且初始化完畢時的事件回調,每個modal實例這個回調只會被觸發一次
    },
    onContentChange: function(){
        //當調用modal.setContent類似的方法改變了modal內容時的事件回調
    },
    onModalShow: function(){
        //當調用modal.open類似方法顯示modal時都會觸發的事件回調
    },
    onModalHide: function(){
        //當調用modal.hide類似方法隱藏modal時都會觸發的事件回調
    }
});

$('#btn-audit').click(function(){
    modal.open();
});

跟Alert和Confirm不同的是,一個頁面裡面只需要一個Alert和Confirm的實例,但是可能需要多個Modal的實例,所以每個Modal對象都需要單獨new一下。由於每個Modal要完成的事情都不相同,所以:

需要一個title參數來設置名稱,表達這個Modal正在處理的事情;

content參數表示Modal的html內容;

width參數設置Modal的寬度,Modal的高度保持auto;

buttons參數用來配置這個Modal上面的按鈕,一般情況下Modal組件只需要兩個按鈕(確定和取消)就夠了,但也有少數情況需要多個按鈕,所以把按鈕做成配置的方式相對靈活一點,每個按鈕用三個參數來配置,html表示按鈕的html結構,selector方便註冊回調的時候通過事件委托的方式來處理,callback配置按鈕點擊時的回調;

onContentReady這個事件回調,可以在Modal初始化完畢的時候,主動去初始化Modal內部html的一些組件;由於組件初始化一般只進行一次,所以放在這個回調裡面最合適;

onContentChange回調,在一個Modal需要被用作不同的場景,顯示不同的HTML的內容時會派上用場,但是不是非常的好用,處理起來邏輯會稍微偏複雜,如果一個Modal實例只做一件事情的時候,onContentChange這個回調就用不到了;

onModalShow這個回調在每次顯示Modal的時候都會顯示,使用的場景有很多,比如某個Modal用來填寫一些表單內容,下次填寫的時候需要reset一下表單才能給用戶使用,這種處理在這個回調裡面處理就比較合適;

onModalHide這個回調有用,不過能夠用到的場景不多,算是預留的一個介面。

4)其它需求

所有類型的彈框都做成虛擬模態的形式,顯示框的同時加一個遮罩;

所有框都不需要支持拖動和大小調整;

alert和dialog框的標題,按鈕數量、按鈕位置、按鈕文字都固定。

實際上

遮罩這個效果,bootstrap的modal組件本身就已經支持了;

拖動和大小調整,這個功能屬於錦上添花,但是對軟體本身來說,並一定有多少額外的好處,所以我選擇不做這種多餘的處理;

alert和dialog不需要做太過個性化,能夠統一風格,改變瀏覽器原生的彈框體驗即可。

5)DEMO中調用實例

接下來演示下我在完成這三個組件開發之後,實際使用過程中調用這些組件的方式:

var modal = new Modal({
    title: '測試modal',
    content: $('#modal-tpl').html(),
    width: 500,
    onOk: function(){
        var $form = this.$modal.find('form');
        var data = $form.serializeArray();
        var postData = {};
        data.forEach(function(obj){
           postData[obj.name] = obj.value;
        });

        if(!postData.email) {
            Alert('請輸入EMAIL!');
            return false;
        }

        var deferred = $.Deferred();
        if(!postData.password) {
            Confirm({
                msg: 'Password為空,是否要繼續?',
                onOk: function(){
                    _post();
                },
                onCancel: function(){
                    deferred.reject();
                }
            })
        } else {
            _post();
        }

        return $.when(deferred);

        function _post(){
            //模擬非同步任務
            setTimeout(function(){
                if(postData.email === 'admin@admin') {
                    Alert({
                        msg: '提交成功!',
                        onOk: function(){
                            deferred.resolve();
                        }
                    });
                } else {
                    Alert({
                        msg: '提交失敗!',
                        onOk: function(){
                            deferred.reject();
                        }
                    });
                }
            },3000);
        }
    },
    onModalShow: function () {
        var $form = this.$modal.find('form');
        $form[0].reset();
    }
});
$('#btn-modal').click(function () {
    modal.open();
});

3. 實現要點

1)最基礎的一點,要對bootstrap的modal組件源碼有所瞭解

初始化方式:$modal.modal()

打開:$modal.modal('show')

關閉:$modal.modal(hide)

事件:bootstrap大部分帶過渡效果的組件的事件都是成對的,並且一個是現在時,一個是完成時,modal組件定義了2對:

show.bs.modal和shown.bs.modal,hide.bs.modal和hidden.bs.modal。

這兩對事件分別在打開和關閉的過渡效果執行前後觸發。從我要定義的組件需求來說,定義組件的時候需要show.bs.modal和hidden.bs.modal這兩個事件,在偵聽到bootstrap的modal組件派發這兩個事件的時候,派發自己定義的組件的事件:modalShow和modalHide。

選項:

backdrop: 是否顯示遮罩;

keyboard: 是否支持鍵盤迴調;

show:是否在初始化完畢就立即顯示。

這三個選項預設都是true,但是在我定義組件的時候,我都配置成了false,鍵盤迴調這種特性暫時不考慮,所以配置為true;當調用bootstrap的modal初始化的時候當然不能立即顯示彈框,所以也不能配置為true;backdrop配置為false的原因在下一點介紹。

2)遮罩處理

如果啟用bootstrap的遮罩,會發現在點擊遮罩部分的時候,彈框就會自動關掉了,這不是我期望的虛擬模態效果,所以必須把backdrop配置為false。但是把這個選項配置為false之後,又會引發一個新問題,就是組件沒有了遮罩效果,所以為了兼顧這兩個問題,只能自己寫一個簡單的遮罩處理:

var $body = $(document.body),
    BackDrop = (function () {
        var $backDrop,
            count = 0,
            create = function () {
                $backDrop = $('<div class="modal-backdrop fade in"></div>').appendTo($body);
            };

        return {
            show: function () {
                !$backDrop && create();
                $backDrop[0].style.display = 'block';
                count++;
            },
            hide: function () {
                count--;
                if (!count) {
                    $backDrop.remove();
                    $backDrop = undefined;
                }
            }
        }
    })();

這段代碼中引入count變數的原因是因為BackDrop是一個全局的單例對象,當調用多個modal實例的open方法的時候,都會調用BackDrop的show方法,為了保證在調用BackDrop的hide方法時,能夠確保在所有的modal實例都關閉之後再隱藏Backdrop,所以就加了一個count變數來記錄BackDrop的show方法被調用了多少次,只有當count為0的時候,調用BackDrop的hide方法才會真正隱藏BackDrop。

3)組件的選項的預設值定義

ModalDialog.defaults = {
    title: '',
    content: '',
    width: 600,
    buttons: [
        {
            html: '<button type="button" class="btn btn-sm btn-primary btn-ok">確定</button>',
            selector: '.btn-ok',
            callback: getDefaultBtnCallbackProxy('onOk')
        },
        {
            html: '<button type="button" class="btn btn-sm btn-default btn-cancel">取消</button>',
            selector: '.btn-cancel',
            callback: getDefaultBtnCallbackProxy('onCancel')
        }
    ],
    onOk: $.noop,
    onCancel: $.noop,
    onContentReady: $.noop,
    onContentChange: $.noop,//content替換之後的回調
    onModalShow: $.noop,
    onModalHide: $.noop//modal關閉之後的回調
};

通過buttons配置兩個預設的按鈕,確定和取消,然後為了簡化這兩個預設按鈕的回調配置,把這兩個按鈕的介面進一步擴展到了上一級別,onOk和onCancel分別會在點擊確定和取消的時候被調用,這兩個選項完全是函數回調,不像onContentReady這種屬於事件回調。getDefaultBtnCallbackProxy用來輔助註冊onOk和onCancel:

var getDefaultBtnCallbackProxy = function (callbackName) {
    return function () {
        var opts = this.options,
            callback = opts[callbackName] && typeof opts[callbackName] === 'function' ? opts[callbackName] : '';

        return callback && callback.apply(this, arguments);
    }
}

裡面的this會被綁定到modal實例上。

4)構造函數:

function ModalDialog(options) {
    this.options = this.getOptions(options);
    this.$modal = undefined;
    this.$modalTitle = undefined;
    this.$modalBody = undefined;
    this.$modalFooter = undefined;
    this.state = undefined;
}

這個主要是聲明瞭用到的一些實例變數。

5)關鍵的原型方法和函數

open: function (state) {
    this.state = state;
    !this.$modal && initModal(this, this.options);
    BackDrop.show();
    this.$modal.modal('show');
}

這是個原型方法,組件的初始化也是在這個方法調用的時候執行的(延遲初始化)。

initModal = function (that, opts) {
    var $modal = createModal(that);
    that.setTitle(opts.title);
    that.setContent(opts.content);
    that.addButtons(opts.buttons);
    that.setWidth(opts.width);
    bindHandler(that, opts);
    $modal.modal();//調用bootstrap的Modal組件
    $modal.trigger('contentReady');
}

這是個函數,用來初始化組件。其中:

setTitle是個原型方法,用來設置modal的標題;

setContent是個原型方法,用來設置modal的html內容;

addButtons是個原型方法,用來註冊按鈕;

setWidth是個原型方法,用來設置modal的寬度;

bindHandler是個函數,用來註冊modal的那些事件;

倒數第二步調用$modal.modal()初始化bootstrap的modal組件;

最後一步觸發contentReady事件。

bindHandler源碼:

bindHandler = function (that, opts) {
    var $modal = that.$modal;
    typeof opts.onContentChange === 'function' && $modal.on('contentChange', $.proxy(opts.onContentChange, that));
    typeof opts.onContentReady === 'function' && $modal.on('contentReady', $.proxy(opts.onContentReady, that));
    typeof opts.onModalShow === 'function' && $modal.on('modalShow', $.proxy(opts.onModalShow, that));
    typeof opts.onModalHide === 'function' && $modal.on('modalHide', $.proxy(opts.onModalHide, that));
    $modal.on('show.bs.modal', function () {
        $modal.trigger('modalShow');
    });
    $modal.on('hidden.bs.modal', function () {
        $modal.trigger('modalHide');
    });
}

為了方便使用,我把onContentChange這幾個回調的上下文綁定到了當前的modal實例。最後兩個事件偵聽就是把bootstrap的事件封裝成了我定義的modal事件。

addButtons源碼:

addButtons: function (buttons) {
    var buttons = !$.isArray(buttons) ? [] : buttons,
        that = this,
        htmlS = [];
    buttons.forEach(function (btn) {
        htmlS.push(btn.html);

        btn.selector && that.$modal.on('click', btn.selector, $.proxy(function (e) {

            var self = this,
                $btn = $(e.currentTarget);

            //先禁用按鈕
            $btn[0].disabled = true;

            var callback = typeof btn.callback === 'function' ? btn.callback : '',
                ret = callback && callback.apply(self, arguments);

            if (ret === false) {
                $btn[0].disabled = false;
                return;
            }

            if (typeof(ret) === 'object' && 'done' in ret && typeof ret['done'] === 'function') {
                //非同步任務只有在成功回調的時候關閉Modal
                ret.done(function () {
                    that.hide();
                }).always(function () {
                    $btn[0].disabled = false;
                });
            } else {
                $btn[0].disabled = false;
                that.hide();
            }

        }, that));
    });

    this.$modalFooter.prepend($(htmlS.join('')));
}

從這個代碼可以看出:

當按鈕點擊之後,按鈕就會被禁用;

當按鈕返回false的時候,按鈕恢復,但是modal不會被關閉,說明當前的一些操作被代碼給攔下來了;

當按鈕返回的是一個延遲對象的時候,會等到延遲對象完成的時候才會恢復按鈕,並且只有在延遲對象resolve的時候才會關閉modal;

否則就恢復按鈕,並主動關閉modal。

在這段代碼裡面考慮了:

按鈕的防重覆點擊,modal的自動關閉以及非同步任務的處理。

6)封裝Alert和Confirm

Alert和Confirm其實就是一個特殊的modal,另外這兩個組件還可以共用一個modal,瞭解到這些基礎之後,組件就可以這樣定義:

var Alert, Confirm;
(function () {
    var modal,
        Proxy = function (isAlert) {
            return function () {
                if (arguments.length != 1) return;
                var msg = typeof arguments[0] === 'string' && arguments[0] || arguments[0].msg || '',
                    onOk = typeof arguments[0] === 'object' && typeof arguments[0].onOk === 'function' && arguments[0].onOk,
                    onCancel = typeof arguments[0] === 'object' && typeof arguments[0].onCancel === 'function' && arguments[0].onCancel,
                    width = typeof arguments[0] === 'object' && arguments[0].width || 400,
                    _onModalShow = function () {
                        this.setWidth(width);
                        this.setContent(msg);
                        this[(isAlert ? 'hide' : 'show') + 'Button']('.btn-cancel');
                    },
                    _onModalHide = function () {
                        this.setContent('');
                    };

                //延遲初始化modal
                if(!modal) {
                    modal = new Modal({
                        'title': '操作提示',
                        onModalShow: _onModalShow,
                        onModalHide: _onModalHide,
                        onContentReady: function(){
                            this.$modalBody.css({
                                'padding-top': '30px',
                                'padding-bottom': '30px'
                            })
                        }
                    });
                } else {
                    //如果modal已經初始化則需要重新監聽事件
                    var $modal = modal.$modal;
                    $modal.off('modalShow modalHide');
                    $modal.off('modalShow modalHide');
                    $modal.on('modalShow', $.proxy(_onModalShow, modal));
                    $modal.on('modalHide', $.proxy(_onModalHide, modal));
                }

                modal.setOptions({
                    onOk: onOk || $.noop,
                    onCancel: onCancel || $.noop
                });

                modal.open();
            }
        };

    Alert = Proxy(true);
    Confirm = Proxy();
})();

這段代碼里:

首先考慮到了延遲初始化這個全局的modal組件;

由於onModalHide和onModalShow這兩個回調屬於事件回調,在初始化組件的時候通過options傳進去的參數,不能通過修改options的方式來更改回調,只能通過重新註冊的方式來處理;而onOk和onCancel屬於函數回調,只要更改了options裡面的引用,回調就能更改;

考慮到Alert和Confirm內容的長短,新加了一個參數width,以便調節框的寬度。

4. 小結

本文介紹的是自己在定義js組件過程中的一些方法和實踐,代碼偏多,不容易引起人的閱讀興趣,但是文中介紹的方法比較簡單,而且這三個組件我已經用到好幾個項目裡面,從目前來看,能夠解決我所有需要的彈框需求,所以我把它推薦出來,希望能給有需要的人帶來幫助。如果你對代碼有興趣,歡迎下載源碼瞭解詳細的實現,任何問題都可在評論裡面與我交流。謝謝閱讀:)

代碼下載


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • JavaScript 中的所有事物都是對象:字元串、數字、數組、日期,等等。 在 JavaScript 中,對象是擁有屬性和方法的數據。 屬性和方法 屬性是與對象相關的值。 方法是能夠在對象上執行的動作。 舉例:汽車就是現實生活中的對象。 汽車的屬性: car.name=Fiat car.model
  • forEach是ECMA5中Array新方法中最基本的一個,就是遍歷,迴圈。例如下麵這個例子: [1, 2 ,3, 4].forEach(alert); 等同於下麵這個for迴圈 var array = [1, 2, 3, 4]; for (var k = 0, length = array.len
  • 在編寫CSS時也存在一些編碼規範,平時註意這些基本的規範,可使代碼更易閱讀和維護。 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title></title> <style> /* 語法 用兩個空格來代替製表符(tab
  • 在編寫HTML時,可能有一些方面不夠規範,在通過對《HTML5編碼規範》的學習後,採用代碼註解的方式,做相關的整理,方便今後回顧。 1 <!DOCTYPE html> <!-- HTML5 doctype 標準模式(standard mode)的聲明,這樣能夠確保在每個瀏覽器中擁有一致的展現-->
  • 1 H5 緩存機制介紹 H5,即 HTML5,是新一代的 HTML 標準,加入很多新的特性。離線存儲(也可稱為緩存機制)是其中一個非常重要的特性。H5 引入的離線存儲,這意味著 web 應用可進行緩存,並可在沒有網際網路連接時進行訪問。 H5 應用程式緩存為應用帶來三個優勢: 離線瀏覽 用戶可在應用離
  • 一、標題 標題的h1到h6標簽,這裡不再贅述。值得一提的是,H5中新定義了一個元素<hgroup>,用來將標題和副標題群組。一般在header里將一組標題組合在一起,變成一個區塊: 1 <body> 2 <header> 3 <hgroup> 4 <h1> 阿裡旅行·去啊 </h1> 5 <h2>
  • 目錄 瞭解什麼是Web 瞭解什麼是HTML 瞭解什麼是CSS 瞭解什麼是JavaScript 瞭解HTML與CSS是如何一起工作的 為何要使用CSS 擴展閱讀 一、瞭解什麼是Web? 通俗來講,可以使用戶通過瀏覽器來訪問某個電腦上的文件。 二、瞭解什麼是HTML? HTML(超文本標記語言--Hyp
  • 前端自動化流程工具,用來合併文件,壓縮等。 Gulp官網 http://gulpjs.com/ Gulp中文網 http://www.gulpjs.com.cn/ Gulp中文文檔 https://github.com/lisposter/gulp-docs-zh-cn Gulp插件網 http:/
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...