前言
最近在幾個spa的項目中都使用前后端完全分離,后端只提供數據接口的方式。慢慢總結了一套前端的通用框架。這個框架沒有語法限制,沒有特別的規則,可接任何語言的后台。一切以快速開發為准則。
技術總覽
技術上來說,使用seajs做模塊調度。
核心模塊有:jquery、jquery-ui、backbone(一個前端MVC框架)、less(一個是css能用變量等編程特性來編寫的js庫)。
已經包括的可用模塊有:contextMenu(jquery右鍵菜單插件)、bootstrap(來自twitter的通用的css和js庫)、uploadify(jquery文件上傳插件)、qtip(jquery提示插件)。
后續可能加入:kindeditor(富文本插件)。
文件結構
根目錄:
core : 存放的是核心的庫文件,如jquery。
module : 中存放的是可選的模塊和用戶自己創建的模塊。
index.php : 是示例的頁面模板,這個模板可以是任何文件,html或者jsp等都行。如果你的應用中有多個頁面,都放在根目錄下就行了。
init.js : 你的應用的初始化文件,可以在里面指定模塊的別名。可以在里面啟動默認的模塊。一切初始化的工作都可以放在這里。
sea.js : seajs核心文件,勿動。
示例 :快速構建一個基礎的應用
觀看本示例時,你需要了解基本的seajs用法。
1.編輯模板文件,在文件結尾插入
<script src="/_PATH_TO_THIS_PACKAGE/sea.js" data-main="/_PATH_TO_THIS_PACKAGE/init"></script>
這件使頁面載入seajs,並指揮seajs默認執行init.js。另外,建議在頁面頭部的script中使用一個全局變量保存當前用戶的信息等。如:
<script> //用來存儲服務器端基礎信息,如當前路徑等等。 window._GLOBAL = { 'user' : { id : 1, name : 'YOUR_NAME'} } </script>
2.編輯init.js,進行初始化工作,如下圖例子。
seajs.config({ alias: { /*以下是核心模塊*/ 'jquery': 'core/jquery-1.7.min', 'jquery-ui': 'core/jquery-ui/jquery-ui-1.8.16.custom.min', 'jquery-ui-css': 'core/jquery-ui/absolution.blue.css', 'jquery-validate' : 'core/jquery.validate.js', 'backbone': 'core/backbone', 'underscore': 'core/underscore-min', 'less' : 'core/less', /*以下是可選的模塊*/ 'jquery-qtip' : 'module/qtip/jquery.qtip.js', /* etc...*/ /* 以下是你自己的模塊*/ 'app-main' : 'module/main/app-main' }, preload : ['core/plugin-less'], debug:2 }); define(function(require) { /*在這里你可以執行任何初始化的工作*/ /* code here */ /*或者直接執行你自己定義的模塊,如下所示*/ var main = require('app-main'); main.execute(); });
3.編輯你的主模塊
define(function(require,exports) { /*載入需要的核心庫*/ var $ = jQuery = require('jquery'); /*載入需要的css文件或者less文件,注意:less文件不能使用別名*/ require("module/main/css/app-main.less"); /* 在主文件里你可以定義一個全局對象, 用這個對象來保存通用的函數, 或者保存調入的模塊信息。 */ window.APP = { app : [], module_use : function( name ){ seajs.use(name,function(app){ app.execute(); }); }, formatDate:function(formatStr, fdate){ var fTime, fStr = 'ymdhis'; if (!formatStr){ formatStr= "y-m-d h:i:s"; } if (fdate){ fdate =fdate * 1000; fTime = new Date( fdate ); }else{ fTime = new Date(); } var formatArr = [ fTime.getFullYear().toString(), (fTime.getMonth()+1).toString(), fTime.getDate().toString(), fTime.getHours().toString(), fTime.getMinutes().toString(), fTime.getSeconds().toString() ] for (var i=0; i<formatArr.length; i++) { formatStr = formatStr.replace(fStr.charAt(i), formatArr[i]); } return formatStr; } }; exports.execute = function(){ console.log("hello world!"); /* 下面是頁面主要的代碼,你可以對頁面進行事件綁定, 根據不同的事件使用require_sync函數異步調用模塊。 */ require('upload').execute(); } });
以上演示的是一個被稱為“主模塊”模塊,這個模塊最重要的是execute函數,它讓該模塊變成一個調度中心。根據頁面事件來異步載入其他模塊。如果你的頁面很簡單,你完全可以把以上代碼整合到init.js中。
4.編寫你的其他模塊,以下是通用的模塊寫法
define(function(require,exports) { /*登記一下當前模塊,如果需要的話*/ window.APP.app.push("_THIS_MODULE_NAME_"); /*載入需要模塊*/ var $ = jQuery = require('jquery'); /*對於jquery插件需要將$變量傳入,具體請參考“詳細說明”*/ require('jquery-ui')($); var Backbone = require('backbone'); var _ = require('underscore'); /* 使用backbone的話,建議使用一個對象來保存所有建立的M、V、C, 同時在V里利用一個instan對象來保存建立視圖的實例。 */ var WORDS = { M : {}, C:{}, V:{ instant :{} } }; WORDS.V.songs = Backbone.View.extend({ tagName : 'ul', className:"song-list", initialize : function(obj){ for( var i in obj ){ this[i] = obj[i]; } this.collection = new WORDS.C.songs(); this.collection.bind("all",this.render,this); }, render : function(){ var root = this; /* code here*/ return this; } }); /*以下掩飾uploadify的用法*/ require('uploadify')($); require('uploadify-swfobj'); require('uploadify-css'); /*uploadify使用flash通信,導致頁面丟失cookie,所以先存起來,上傳完再回復*/ var up_cookie = document.cookie; $("#selector").uploadify({ 'uploader' : '/_PATH_TO_THIS_PACKAGE_/module/uploadify/scripts/uploadify.swf', 'script' : '/_PATH_TO_UPLOAD_SCRIPT', 'queueID' : '_FILE_ARG_NAME_', 'scriptData' : { /*這里設置同時要上傳的參數*/ }, 'onComplete': function(event, ID, fileObj, response, data) { /*code here*/ /*回復cookie*/ document.cookie = up_cookie; }, 'onError': function (event,ID,fileObj,errorObj) { console.log(errorObj); document.cookie = up_cookie; } }); exports.execute = function(){ /*生成一個視圖*/ WORDS.V.instant.words_dialog = new WORDS.V.word_songs(); } /*建議模塊使用exports對外提供清理視圖實例的方法*/ });
詳細說明
1.使用seajs載入jquery插件時,需要簡單將jquery插件封裝以下。讀者可在seajs的官網demo里找到jquery插件的封裝方式。
2.backbone除了MVC以外,event和router非常好用。event可以和任何對象綁定,讓系統有可能使用事件驅動。router是專為spa配置的。backbone中文文檔:http://www.csser.com/tools/backbone/backbone.js.html
3.個人開發者建議使用less來編寫css,可以直接導入bootstrap的less文件。
4.筆者會在近期整理出一套源碼以供下載。
5.開發完畢后可使用less的工具合並less文件。seajs的工具合並js文件。