本文介紹seajs和hanlebars,并實現(xiàn)前端控件組件化.
我想實現(xiàn)的是把組件單獨一個文件夾,js和css,html都放在文件夾中,要使用組件的頁面利用seajs引入組件,并直接調(diào)用組件的方法或者事件。這個方案是自己的思考,歡迎大家拍磚。
主要演員 seajs 和 handlebars
seajs是一個前端模塊化js庫,作用類似于requirejs,都用來前端js的模塊化和按需依賴加載的工作。功能都差不多,seajs是淘寶玉伯開發(fā)的,國產(chǎn),所以國內(nèi)使用者比較多,requirejs國外的,存在時間比seajs要久許多,國外用的比較多。 兩者最大的區(qū)別在于定義模塊的語法不同,一個是AMD規(guī)范,一個是CMD規(guī)范。seajs是CMD規(guī)范,所以他的語法更像nodejs,寫起來會比requirejs優(yōu)雅一些。不過缺點也很多,比如很多第三方庫都是按照AMD規(guī)范寫的,會有兼容性問題,就需要自己改寫模塊或者使用spm工具處理。
handlebars是一個前端js模板引擎 我在之前的文章介紹過handlebars及簡單的用法,大家可以去看下點我
任務(wù)1,頁面框架配置,seajs初始化
新建html頁面,引入需要的類庫
seajs用于做js模塊管理,seajs-text可以用于加載handlebars的模板內(nèi)容
配置seajs
//basePath由服務(wù)端配置域名varbasePath="http://localhost:8080/app/";// seajs 的簡單配置seajs.config({base:basePath,alias:{"jquery":"../bower_components/jquery/jquery.seejs.min.js","handlebars":"../bower_components/handlebars/handlebars.seajs.min.js"}});// 加載入口模塊seajs.use("./scripts/seajs+handlebars.js");````注意,jquery默認是不支持AMD標準,也不支持seajs,所以這里用的````jquery.seejs.min.js和handlebars.seajs.min.js````都是自己手動改過的,jquery修改的方法就是在源碼中級加上幾行代碼,如下:````jsdefine(function(){//jquery源代碼寫在中間return$.noConflict();});
handlebars修改比jquery少了那句return $.noConflict();就可以了。
basePath可以根據(jù)實際環(huán)境設(shè)置。使用alias設(shè)置別名后,就可以在sea中使用require()的方法獲取到源碼
seajs.use("./scripts/seajs+handlebars.js");設(shè)置了頁面的js入口
入口seajs+handlebars.js
// 所有模塊都通過 define 來定義
define(function(require, exports, module) {
$(function(){
var Handlebars = require('handlebars');
var tpl = require("./data.tpl");
var demoTplc = Handlebars.compile(tpl);
$("body").html( demoTplc("hello world"));
});
});
data.tpl
{ {this} }
加載Handlebars和tpl模板,然后直接調(diào)用Handlebars.compile進行模板編譯后渲染dom。執(zhí)行后bady的內(nèi)容就變成了hello world。大家可以下載demo,打開seajs+handlebars.html看下效果
組件化方案
之前的代碼可以完成用seajs動態(tài)加載handlebars模板并渲染的功能,但并沒有實現(xiàn)組件化。現(xiàn)在我們來實現(xiàn)組件的封裝。首先建立一個文件夾,包括
components
- Boxes
-index.js? //js代碼處理數(shù)據(jù)和事件
-index.css //boxes樣式
-boxes.tpl //boxes html模板
里面的內(nèi)容作為demo,我寫的簡單一些。
boxes.tpl
this is a boxes!
{ {this} }
index.css
.c-boxes{background-color:red;}.c-boxesh1{color:blue;}
index.js
define(function(require,exports,module){varHandlebars=require('handlebars');varbox={init:function(){returnbox;},clicked:function(){},render:function($dom,data){vartpl=require('./boxes.tpl');vartplc=Handlebars.compile(tpl);// var _clicked = clicked;$dom.html(tplc(data));box.$dom=$dom;$dom.click(function(){box.clicked&&box.clicked();});}};module.exports=box;});
index.js稍微復雜一些,封裝了一個對象,并定義了對象的點擊事件的外部接口。rander方法使用了前面相似的方式,渲染了bandlerbars模板,并注入點擊事件
這樣一個組件就已經(jīng)封裝好了。
組件的使用
前面定義了一個boxes組件,現(xiàn)在我們來使用他.html頁面和之前的頁面是一樣的,唯一的區(qū)別是入口js換成了componentization.js
componentization.js
define(function(require,exports,module){// 通過 require 引入依賴var$=require('jquery');varBoxes=require('boxes');$(function(){//實例化組件varbox=Boxes.init();box.render($("body"),"hello world!");box.clicked=function(){console.log("clicked");};});});
box定義好后,使用起來非常簡單,直接調(diào)用box.render()方法就可以了,也順帶個box綁定了點擊事件,效果可以看demo中的 componentization.html 頁面
組件化其他的思考
組件的模板和js都通過seajs加載和封裝了,唯一遺憾的是css需要單獨引入。 seajs也有css引入的插件sea-css,但是試了一下沒成功。 所以我的解決方案是使用gulp完成,遍歷component下的所有css文件,組合成并壓縮成一個css,然后再使用的頁面中統(tǒng)一引用這個合并的css
具體gulp腳本
//css components 組合 構(gòu)建任務(wù)
gulp.task('css-concat', function () {
gulp.src(css_components_Src)
.pipe(concat('allComponent.css'))//合并后的文件名
.pipe(gulp.dest(cssDst));
});
demo
本文示例demo見demo-web
文本的demo在文件夾Handlebars中
使用方式
Handlebars目錄下執(zhí)行http-server -p 8080
usage.html =》 handlerbars的使用及模板預(yù)編譯
componentization.html =》 前端開發(fā)框架 - seajs+handlebars模塊化開發(fā)
錯誤處理
如果本地沒有http-server命令,請安裝nodejs環(huán)境,并通過npm安裝 http-server 命令:npm install -g http-server