成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

MV* 框架 與 DOM操作為主 JS庫 的案例對比

springDevBird / 1240人閱讀

摘要:中定義的處理業(yè)務(wù)邏輯與提供數(shù)據(jù)源,中的綁定負(fù)責(zé)渲染與響應(yīng)用戶點(diǎn)擊拖拽等行為,這樣就最大保證了視圖邏輯相分離。遠(yuǎn)離的世界,圍繞層控制器路由從后端放到前端,更加適合開發(fā)。

最近分別使用 Zepto 和 Avalon框架寫了個(gè) SPA項(xiàng)目,貼出來討論下 JS DOM操作為主 JS庫 與 MV* 框架的對比

案例(MV* 框架 與 DOM操作 JS庫 實(shí)例對比) 購物車頁面 JS業(yè)務(wù)邏輯(忽略 Ajax請求--Ajax請求時(shí)機(jī)根據(jù)產(chǎn)品具體情況而定)

以列表方式展示購物車商品

每件商品有"+"、"-" 按鈕,點(diǎn)擊該按鈕則:

檢測是否達(dá)到購買極限(如:最小購買數(shù)量不能小于 1件)

達(dá)到購買極限則給該按鈕添加相應(yīng)的 class 以便提示用戶該按鈕不能再點(diǎn)擊

反之則去掉該按鈕上的該 class(如:現(xiàn)在商品數(shù)量為 1,"-" 為不可用狀態(tài),現(xiàn)在點(diǎn)擊 "+" 則 "-"變?yōu)榭捎脿顟B(tài))

改變該件商品數(shù)量

計(jì)算 并 更新該商品總價(jià)金額

重新計(jì)算 并 更新 購物車所有商品金額

移除單種商品

從視圖上找到該 DOM

然后移除該 DOM

重新計(jì)算 并 更新 購物車所有商品金額

移除購物車所有商品

顯示購物車無商品 div,引導(dǎo)用戶到商品列表等其它頁面

實(shí)現(xiàn): 實(shí)現(xiàn)一:Zepto 版
  

以 DOM操作 JS庫實(shí)現(xiàn):jQuery、Zepto、MooTools)

通過后端控制器渲染頁面

view:

<{css src="page/cart.css"}>

購物車
style="display: none;"<{/if}> >

購物車空空如也

">去添加

<{if !empty($cart.cartList)}>
商品總價(jià)(不含運(yùn)費(fèi)) <{$cart.totalAmount|cur}> " class="topBtn">去結(jié)算
<{foreach from=$cart.cartList item=item}>

<{$item.cashcoupon.name}>

<{$item.cashcoupon.price|cur}> <{$item.cashcoupon.mktprice|cur}>
<{/foreach}>
商品總價(jià)(不含運(yùn)費(fèi))<{$cart.totalAmount|cur}>
<{script src="page/cart.js"}> <{/if}>

JS 邏輯

javascript
// 全局常量 var UA = navigator.userAgent; var ipad = !!(UA.match(/(iPad).*OSs([d_]+)/)), isIphone = !!(!ipad && UA.match(/(iPhonesOS)s([d_]+)/)), isAndroid = !!(UA.match(/(Android)s+([d.]+)/)), isMobile = !!(isIphone || isAndroid); var CLICK = isMobile ? "tap" : "click"; // 移動(dòng)端觸摸、PC單擊 事件 // 購物車 var Cart = { // 更新 info update: function ($id, $number, fun) { var data = { id: $id || "", number: $number || 0 }; CGI.POST("wecart-update.html", data, function (data) { // 回調(diào)方法 fun && fun(data); }); }, // 計(jì)算總價(jià) figurePrice: function () { var goodsList = $(".goodslist"); console.log(goodsList); if (0 === goodsList.length) { this.removeAll(); return false; } // 當(dāng)前商品金額 var price; // 當(dāng)前商品數(shù)量 var number; // 總金額 var allPrice = 0; $.each(goodsList, function (index, item) { item = $(item); price = parseFloat(item.attr("data-price")); number = parseInt(item.find("input").val()); console.log({"數(shù)量": number, "單價(jià)": price}); allPrice += price * number; }); console.log("總價(jià):" + allPrice); // DOM 操作 $(".total").text("¥" + allPrice.toFixed(2)); }, // 移除所有 removeAll: function () { // DOM 操作 $("#emptyBox").show(); $(".box").hide(); } }; // 遞增、遞減 $(".numBox").on(CLICK, function (e) { // numBox var _t = $(this); var dom = $(e.target); // 商品數(shù)量 DOM var numDom = _t.find("input"); //console.log(numDom); // 數(shù)量 var _v = parseInt(numDom.val()), now_v; // 最大購買數(shù) var max = parseInt(numDom.attr("data-max-count")); if (dom.hasClass("plus")) { // 遞增 // 最大購買數(shù)量限制 if (_v === max) { return false; } now_v = (_v < 1) ? 1 : (_v >= max ? max : _v + 1); } else if (dom.hasClass("minus")) { // 遞減 // 最小購買數(shù)量限制 if (_v === 1) { return false; } now_v = (_v < 1) ? 1 : (_v > max ? max : _v - 1); } else { return false; } var cartId = dom.parents(".goodslist").attr("data-cashcoupon-id"); // ajax Cart.update(cartId, now_v, function (data) { // 更改數(shù)量 numDom.val(now_v); // 遞減數(shù)量按鈕 var minus = _t.find(".minus"); // 遞增數(shù)量按鈕 var plus = _t.find(".plus"); now_v > 1 && minus.hasClass("bg_gray") && minus.removeClass("bg_gray"); now_v === 1 && !minus.hasClass("bg_gray") && minus.addClass("bg_gray"); now_v < max && plus.hasClass("bg_gray") && plus.removeClass("bg_gray"); now_v >= max && !plus.hasClass("bg_gray") && plus.addClass("bg_gray"); // 計(jì)算總價(jià) Cart.figurePrice(); }); event.preventDefault(); }); // 刪掉商品 $(".del").on(CLICK, function () { var dom = $(this).parents(".goodslist"); var cartId = dom.attr("data-cashcoupon-id"); cartId && Cart.update(cartId, 0, function (data) { // 提示 SD.Toast({"text": "刪除成功!"}); // 移除當(dāng)先列 dom.remove(); // 計(jì)算總價(jià) Cart.figurePrice(); }); }); // 刪掉所有商品 $(".delAll").on(CLICK, function (event) { SD.Confirm({ content: "你確定要清空購物車嗎?", //lock: false, ok: { text: "殘忍清空", fun: function () { Cart.update("", 0, function (data) { // 提示 SD.Toast({"text": "刪除成功!"}); // DOM 操作 Cart.removeAll(); }); } }, cancel: { text: "再忍忍" } }); });
實(shí)現(xiàn)二:Avalon版
  

以 MV* 框架實(shí)現(xiàn):Angular、Avalon)
通過后端接口獲取購物車數(shù)據(jù),JS動(dòng)態(tài)渲染頁面

view:

html

商品總價(jià)(不含運(yùn)費(fèi)){{price|currency}} 去結(jié)算

{{el.cashcoupon.name}}

{{el.cashcoupon.price|currency}} {{el.cashcoupon.mktprice|currency}}
商品總價(jià)(不含運(yùn)費(fèi)){{price|currency}}
清空全部

JS 業(yè)務(wù)代碼

javascriptdefine("cart", ["avalon", "request"], function (avalon) {

    var avalonAjax = avalon.ajax;

    var model = avalon.define({
        $id: "cart",
        toggle: true,
        price: 0, // 總金額
        goodsList: [],
        // 遞加數(shù)量
        plus: function (index) {
            model.goodsList[index].quantity = parseInt(model.goodsList[index].quantity) + 1;

            // 計(jì)算總數(shù)量 和 總金額
            count();
        },
        // 遞減數(shù)量
        minus: function (index) {
            if (model.goodsList[index].quantity <= 1) {
                return false;
            }
            model.goodsList[index].quantity = parseInt(model.goodsList[index].quantity) - 1;

            // 計(jì)算總數(shù)量 和 總金額
            count();
        },
        // 移除當(dāng)前
        remove: function (index, perish) {
            perish();   // 移除
        },
        // 移除所有
        removeAll: function () {
            avalon.vmodels.cart.goodsList.clear();

            // 計(jì)算總數(shù)量 和 總金額
            count();
        }
    });

    // 獲取數(shù)據(jù)
    var getData = function () {
        if (avalonAjax) {
            avalon.getJSON("", {method: "ecoupon.cart.list"}, function (data) {
                model.price = data.totalAmount;
                model.goodsList = data.cartList;
            })
        }
    }();

    // 計(jì)算總數(shù)量 和 總金額
    function count() {
        var _count = 0;
        var _price = 0;
        model.goodsList.forEach(function (goods, index) {
            _count += parseInt(goods.quantity);
            _price += parseFloat(goods.cashcoupon.price) * parseInt(goods.quantity);
        });
        avalon.vmodels.page.cartNum = _count;
        model.price = _price.toFixed(2);
    };

    // 購物車數(shù)量監(jiān)聽(目前只能監(jiān)聽商品種類變化, 不能監(jiān)聽商品數(shù)量變化)
    model.goodsList.$watch("length", function () {
        count();
    });

    return model;

});
  

zepto 版本中,js 業(yè)務(wù)代碼大量使用了 選擇器 來 操作DOM,導(dǎo)致 js 與 view 極度耦合。

  

avalon版本,利用avalon可以大大加快我們項(xiàng)目的開發(fā)速度,可以使我們遠(yuǎn)離 DOM的世界,我們的編程變成了只圍繞 model層而不圍繞 DOM,即操作 model就是操作 DOM,同時(shí)能讓我們開發(fā)人員離開 DOM都能輕松進(jìn)行前端開發(fā)。avalon中定義的 VM處理業(yè)務(wù)邏輯與提供數(shù)據(jù)源,HTML中的綁定負(fù)責(zé)渲染與響應(yīng)用戶點(diǎn)擊拖拽等行為,這樣就最大保證了視圖邏輯相分離。

優(yōu)點(diǎn)

JS 與 view 解耦。遠(yuǎn)離 DOM的世界,圍繞 model層

控制器、路由從后端放到前端,更加適合 Web APP開發(fā)。SPA應(yīng)用可以提供更好的用戶體驗(yàn)

業(yè)務(wù)實(shí)現(xiàn)的方式轉(zhuǎn)變(由直接操作 DOM變?yōu)?操作 VM,更加適合后端童鞋思維方式)

更容易實(shí)現(xiàn)前后端分離

官方講代碼量比 jQuery減少50%

....

缺點(diǎn)

MV* 框架學(xué)習(xí)成本高,概念多(控制器、路由、指令、過濾器、服務(wù)、依賴注入...)[哈哈、后端同學(xué)最喜歡這種了,學(xué)習(xí)起來無壓力]

發(fā)展時(shí)間沒有 jQuery這種時(shí)間長,組件相比 jQuery相差比較大(大多數(shù)需要自己實(shí)現(xiàn))

動(dòng)畫

SEO(貌似有解決方案了)

...

  

具體選擇就看場景了吧,動(dòng)畫效果、特效多用 jQuery這種,業(yè)務(wù)復(fù)雜用 MV* 這種

原文發(fā)在:http://www.webdevs.cn/article/93.html

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/85506.html

相關(guān)文章

  • [ 前端框架 ] 前端 MV*框架意義

    摘要:從協(xié)作關(guān)系上講,很多前端開發(fā)團(tuán)隊(duì)每個(gè)成員的職責(zé)不是很清晰,有了前端的框架,這個(gè)狀況會(huì)大有改觀??蚣艿睦砟钍前亚岸税凑章氊?zé)分層,每一層都相對比較獨(dú)立,有自己的價(jià)值,也有各自發(fā)揮的余地。 簡介: MV框架又是為什么興起的呢?它的出現(xiàn),伴隨著一些 Web 產(chǎn)品逐漸往應(yīng)用方向發(fā)展,遇到了在 C/S 領(lǐng)域相同的問題:由于前端功能的增強(qiáng)、代碼的膨脹,導(dǎo)致不得不做前端的架構(gòu)這個(gè)事情了。經(jīng)常有人質(zhì)疑...

    fxp 評論0 收藏0
  • 前端每周清單半年盤點(diǎn)之 JavaScript 篇

    摘要:前端每周清單專注前端領(lǐng)域內(nèi)容,以對外文資料的搜集為主,幫助開發(fā)者了解一周前端熱點(diǎn)分為新聞熱點(diǎn)開發(fā)教程工程實(shí)踐深度閱讀開源項(xiàng)目巔峰人生等欄目。背后的故事本文是對于年之間世界發(fā)生的大事件的詳細(xì)介紹,闡述了從提出到角力到流產(chǎn)的前世今生。 前端每周清單專注前端領(lǐng)域內(nèi)容,以對外文資料的搜集為主,幫助開發(fā)者了解一周前端熱點(diǎn);分為新聞熱點(diǎn)、開發(fā)教程、工程實(shí)踐、深度閱讀、開源項(xiàng)目、巔峰人生等欄目。歡迎...

    Vixb 評論0 收藏0
  • Vue.js新手入門指南[轉(zhuǎn)載]

    摘要:就是一個(gè)用于搭建類似于網(wǎng)頁版知乎這種表單項(xiàng)繁多,且內(nèi)容需要根據(jù)用戶的操作進(jìn)行修改的網(wǎng)頁版應(yīng)用。單頁應(yīng)用程序顧名思義,單頁應(yīng)用一般指的就是一個(gè)頁面就是應(yīng)用,當(dāng)然也可以是一個(gè)子應(yīng)用,比如說知乎的一個(gè)頁面就可以視為一個(gè)子應(yīng)用。 最近在逛各大網(wǎng)站,論壇,以及像SegmentFault等編程問答社區(qū),發(fā)現(xiàn)Vue.js異?;鸨貜?fù)性的提問和內(nèi)容也很多,樓主自己也趁著這個(gè)大前端的熱潮,著手學(xué)習(xí)了一...

    MartinHan 評論0 收藏0
  • javascript框架學(xué)習(xí)計(jì)劃

    摘要:前言終于要做這個(gè)計(jì)劃了,前端框架千千萬,絕不能一頭扎進(jìn)去盲目開始,本片文章總結(jié)一下目前前各種端框架,以及它們的用途主要解決什么問題,然后最后做出學(xué)習(xí)計(jì)劃。希望入了前端坑的同學(xué)們可以有所幫助。但是庫與框架很難嚴(yán)格區(qū)分,所以統(tǒng)一稱為解決方案。 前言:終于要做這個(gè)計(jì)劃了,前端框架千千萬,絕不能一頭扎進(jìn)去盲目開始,本片文章總結(jié)一下目前前各種端框架,以及它們的用途主要解決什么問題,然后最后做出學(xué)...

    airborne007 評論0 收藏0
  • 讓React應(yīng)用“動(dòng)”起來

    摘要:因?yàn)槠浣M件只是根據(jù)提供的及屬性,生成動(dòng)畫的數(shù)據(jù),業(yè)務(wù)應(yīng)用中拿到生成的數(shù)據(jù)后根據(jù)需要添加需要?jiǎng)赢嫷慕M件樣式。除了上述簡單的動(dòng)畫應(yīng)用,在復(fù)雜動(dòng)畫的實(shí)現(xiàn)方面,表現(xiàn)非常優(yōu)越。 WEB應(yīng)用中動(dòng)畫很重要 不管是web應(yīng)用還是原生應(yīng)用,也不論是PC端應(yīng)用還是移動(dòng)端應(yīng)用,動(dòng)畫都扮演了一個(gè)重要的角色。 盡管動(dòng)畫并不會(huì)添加應(yīng)用的實(shí)際動(dòng)能,但一個(gè)好的動(dòng)畫,一個(gè)流暢且優(yōu)雅,選擇在恰當(dāng)時(shí)機(jī)出現(xiàn)的動(dòng)畫,能為應(yīng)用增...

    xiyang 評論0 收藏0

發(fā)表評論

0條評論

最新活動(dòng)
閱讀需要支付1元查看
<