摘要:中定義的處理業務邏輯與提供數據源,中的綁定負責渲染與響應用戶點擊拖拽等行為,這樣就最大保證了視圖邏輯相分離。遠離的世界,圍繞層控制器路由從后端放到前端,更加適合開發。
最近分別使用 Zepto 和 Avalon框架寫了個 SPA項目,貼出來討論下 JS DOM操作為主 JS庫 與 MV* 框架的對比
案例(MV* 框架 與 DOM操作 JS庫 實例對比) 購物車頁面 JS業務邏輯(忽略 Ajax請求--Ajax請求時機根據產品具體情況而定)以列表方式展示購物車商品
每件商品有"+"、"-" 按鈕,點擊該按鈕則:
檢測是否達到購買極限(如:最小購買數量不能小于 1件)
達到購買極限則給該按鈕添加相應的 class 以便提示用戶該按鈕不能再點擊
反之則去掉該按鈕上的該 class(如:現在商品數量為 1,"-" 為不可用狀態,現在點擊 "+" 則 "-"變為可用狀態)
改變該件商品數量
計算 并 更新該商品總價金額
重新計算 并 更新 購物車所有商品金額
移除單種商品
從視圖上找到該 DOM
然后移除該 DOM
重新計算 并 更新 購物車所有商品金額
移除購物車所有商品
顯示購物車無商品 div,引導用戶到商品列表等其它頁面
實現: 實現一:Zepto 版以 DOM操作 JS庫實現:jQuery、Zepto、MooTools)
通過后端控制器渲染頁面
view:
<{css src="page/cart.css"}>購物車 style="display: none;"<{/if}> ><{if !empty($cart.cartList)}>購物車空空如也
<{script src="page/cart.js"}> <{/if}>商品總價(不含運費) <{$cart.totalAmount|cur}> " class="topBtn">去結算<{foreach from=$cart.cartList item=item}><{/foreach}><{$item.cashcoupon.name}>
- +<{$item.cashcoupon.price|cur}><{$item.cashcoupon.mktprice|cur}>商品總價(不含運費)<{$cart.totalAmount|cur}>
JS 邏輯
javascript實現二:Avalon版
// 全局常量 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"; // 移動端觸摸、PC單擊 事件 // 購物車 var Cart = { // 更新 info update: function ($id, $number, fun) { var data = { id: $id || "", number: $number || 0 }; CGI.POST("wecart-update.html", data, function (data) { // 回調方法 fun && fun(data); }); }, // 計算總價 figurePrice: function () { var goodsList = $(".goodslist"); console.log(goodsList); if (0 === goodsList.length) { this.removeAll(); return false; } // 當前商品金額 var price; // 當前商品數量 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({"數量": number, "單價": price}); allPrice += price * number; }); console.log("總價:" + 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); // 商品數量 DOM var numDom = _t.find("input"); //console.log(numDom); // 數量 var _v = parseInt(numDom.val()), now_v; // 最大購買數 var max = parseInt(numDom.attr("data-max-count")); if (dom.hasClass("plus")) { // 遞增 // 最大購買數量限制 if (_v === max) { return false; } now_v = (_v < 1) ? 1 : (_v >= max ? max : _v + 1); } else if (dom.hasClass("minus")) { // 遞減 // 最小購買數量限制 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) { // 更改數量 numDom.val(now_v); // 遞減數量按鈕 var minus = _t.find(".minus"); // 遞增數量按鈕 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"); // 計算總價 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": "刪除成功!"}); // 移除當先列 dom.remove(); // 計算總價 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: "再忍忍" } }); });
以 MV* 框架實現:Angular、Avalon)
通過后端接口獲取購物車數據,JS動態渲染頁面
view:
html
JS 業務代碼
javascriptdefine("cart", ["avalon", "request"], function (avalon) { var avalonAjax = avalon.ajax; var model = avalon.define({ $id: "cart", toggle: true, price: 0, // 總金額 goodsList: [], // 遞加數量 plus: function (index) { model.goodsList[index].quantity = parseInt(model.goodsList[index].quantity) + 1; // 計算總數量 和 總金額 count(); }, // 遞減數量 minus: function (index) { if (model.goodsList[index].quantity <= 1) { return false; } model.goodsList[index].quantity = parseInt(model.goodsList[index].quantity) - 1; // 計算總數量 和 總金額 count(); }, // 移除當前 remove: function (index, perish) { perish(); // 移除 }, // 移除所有 removeAll: function () { avalon.vmodels.cart.goodsList.clear(); // 計算總數量 和 總金額 count(); } }); // 獲取數據 var getData = function () { if (avalonAjax) { avalon.getJSON("", {method: "ecoupon.cart.list"}, function (data) { model.price = data.totalAmount; model.goodsList = data.cartList; }) } }(); // 計算總數量 和 總金額 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); }; // 購物車數量監聽(目前只能監聽商品種類變化, 不能監聽商品數量變化) model.goodsList.$watch("length", function () { count(); }); return model; });
zepto 版本中,js 業務代碼大量使用了 選擇器 來 操作DOM,導致 js 與 view 極度耦合。
優點avalon版本,利用avalon可以大大加快我們項目的開發速度,可以使我們遠離 DOM的世界,我們的編程變成了只圍繞 model層而不圍繞 DOM,即操作 model就是操作 DOM,同時能讓我們開發人員離開 DOM都能輕松進行前端開發。avalon中定義的 VM處理業務邏輯與提供數據源,HTML中的綁定負責渲染與響應用戶點擊拖拽等行為,這樣就最大保證了視圖邏輯相分離。
JS 與 view 解耦。遠離 DOM的世界,圍繞 model層
控制器、路由從后端放到前端,更加適合 Web APP開發。SPA應用可以提供更好的用戶體驗
業務實現的方式轉變(由直接操作 DOM變為 操作 VM,更加適合后端童鞋思維方式)
更容易實現前后端分離
官方講代碼量比 jQuery減少50%
....
缺點MV* 框架學習成本高,概念多(控制器、路由、指令、過濾器、服務、依賴注入...)[哈哈、后端同學最喜歡這種了,學習起來無壓力]
發展時間沒有 jQuery這種時間長,組件相比 jQuery相差比較大(大多數需要自己實現)
動畫
SEO(貌似有解決方案了)
...
具體選擇就看場景了吧,動畫效果、特效多用 jQuery這種,業務復雜用 MV* 這種
原文發在:http://www.webdevs.cn/article/93.html
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/85506.html
摘要:從協作關系上講,很多前端開發團隊每個成員的職責不是很清晰,有了前端的框架,這個狀況會大有改觀。框架的理念是把前端按照職責分層,每一層都相對比較獨立,有自己的價值,也有各自發揮的余地。 簡介: MV框架又是為什么興起的呢?它的出現,伴隨著一些 Web 產品逐漸往應用方向發展,遇到了在 C/S 領域相同的問題:由于前端功能的增強、代碼的膨脹,導致不得不做前端的架構這個事情了。經常有人質疑...
摘要:前端每周清單專注前端領域內容,以對外文資料的搜集為主,幫助開發者了解一周前端熱點分為新聞熱點開發教程工程實踐深度閱讀開源項目巔峰人生等欄目。背后的故事本文是對于年之間世界發生的大事件的詳細介紹,闡述了從提出到角力到流產的前世今生。 前端每周清單專注前端領域內容,以對外文資料的搜集為主,幫助開發者了解一周前端熱點;分為新聞熱點、開發教程、工程實踐、深度閱讀、開源項目、巔峰人生等欄目。歡迎...
摘要:就是一個用于搭建類似于網頁版知乎這種表單項繁多,且內容需要根據用戶的操作進行修改的網頁版應用。單頁應用程序顧名思義,單頁應用一般指的就是一個頁面就是應用,當然也可以是一個子應用,比如說知乎的一個頁面就可以視為一個子應用。 最近在逛各大網站,論壇,以及像SegmentFault等編程問答社區,發現Vue.js異常火爆,重復性的提問和內容也很多,樓主自己也趁著這個大前端的熱潮,著手學習了一...
摘要:前言終于要做這個計劃了,前端框架千千萬,絕不能一頭扎進去盲目開始,本片文章總結一下目前前各種端框架,以及它們的用途主要解決什么問題,然后最后做出學習計劃。希望入了前端坑的同學們可以有所幫助。但是庫與框架很難嚴格區分,所以統一稱為解決方案。 前言:終于要做這個計劃了,前端框架千千萬,絕不能一頭扎進去盲目開始,本片文章總結一下目前前各種端框架,以及它們的用途主要解決什么問題,然后最后做出學...
摘要:因為其組件只是根據提供的及屬性,生成動畫的數據,業務應用中拿到生成的數據后根據需要添加需要動畫的組件樣式。除了上述簡單的動畫應用,在復雜動畫的實現方面,表現非常優越。 WEB應用中動畫很重要 不管是web應用還是原生應用,也不論是PC端應用還是移動端應用,動畫都扮演了一個重要的角色。 盡管動畫并不會添加應用的實際動能,但一個好的動畫,一個流暢且優雅,選擇在恰當時機出現的動畫,能為應用增...
閱讀 3048·2021-11-25 09:43
閱讀 1026·2021-11-24 10:22
閱讀 1352·2021-09-22 15:26
閱讀 681·2019-08-30 15:44
閱讀 2463·2019-08-29 16:33
閱讀 3684·2019-08-26 18:42
閱讀 908·2019-08-23 18:07
閱讀 1832·2019-08-23 17:55