1赋访、前言
本文主要記錄做小項(xiàng)目時(shí)所需要用到的技術(shù)棧。小項(xiàng)目的場(chǎng)景如:特定的活動(dòng)頁(yè)啄枕,某app的運(yùn)營(yíng)推廣頁(yè)婚陪,Hybrid App里的H5頁(yè)面等。
2频祝、技術(shù)棧構(gòu)成
既然是小項(xiàng)目泌参,自然不會(huì)考慮時(shí)下較火的一些框架,如Vue常空,React沽一,Angular等。先來(lái)考慮一個(gè)小項(xiàng)目中前端需要用到的技術(shù)點(diǎn):
- 路由管理
- 模板引擎(非靜態(tài)頁(yè)面需要用到)
- DOM操作
以上三點(diǎn)其實(shí)在Vue框架中都有體現(xiàn)漓糙,分別對(duì)應(yīng)vue-router铣缠,vue內(nèi)置的模板引擎,vue的虛擬DOM算法等昆禽,只是Vue對(duì)此進(jìn)行了封裝攘残,使用起來(lái)更便捷。借著這個(gè)思想为狸,我們可以自己組裝需要的類(lèi)庫(kù)歼郭。
2.1、路由管理模塊
路由模塊目前比較出名(成熟)的是page.js辐棒,26.3KB和director.js病曾,19.9KB,這兩個(gè)框架完全可以滿(mǎn)足小項(xiàng)目的需求漾根,但還是有點(diǎn)重泰涂,前端路由本來(lái)不是很復(fù)雜,可以自己寫(xiě)一個(gè):
var Router = {
routes: {},
mode: null,
config: function(options) {
this.mode = options && options.mode && options.mode == 'history'
&& !!(history.pushState) ? 'history' : 'hash';
this.routes=options && options.routes;
return this;
},
add: function(re, handler) {
this.routes[re]=handler;
return this;
},
navigate: function(path) {
path = path ? path : '';
if(this.mode === 'history') {
history.pushState(null, null, path);
} else {
window.location.href = window.location.href.replace(/#(.*)$/, '') + '#' + path;
}
Router.routes[path]();
return this;
},
start:function(){
var path=location.hash||‘#home’;
if(this.mode === 'history') {
window.on('popstate',function(){
this.navigate(path);
})
} else {
window.on('hashchange',function(){
this.navigate(path);
})
}
}
}
// 1辐怕、配置
Router.config({
mode: 'history',
routes:{
'/home':function(){},
...
}
});
// 2逼蒙、添加路由處理函數(shù)
Router
.add(/home, function() {
console.log('home');
})
// 3、開(kāi)始監(jiān)聽(tīng)
Router.start();
2.2寄疏、模板引擎
前端圈模板引擎就多了去了是牢,目前我們部門(mén)使用的doT.js,這里有一個(gè)JS模板引擎性能對(duì)比分析陕截,關(guān)于doT的使用方式可參見(jiàn)這篇文章驳棱,關(guān)于doT模板只想說(shuō)一句,它是可以和服務(wù)端做同構(gòu)的农曲,也就是說(shuō)前后端可以用同一套模板社搅。
2.3、DOM操作
移動(dòng)端當(dāng)然選擇Zepto.js了,DOM操作大家都知道形葬,這部分介紹使用zepto的最佳實(shí)踐:
- 使用ID選擇器$('#id')選擇元素合呐,避免使用組合選擇器
- 對(duì)需要復(fù)用的元素做緩存,用find查找子元素
- 盡量使用zepto靜態(tài)方法
- 使用事件代理笙以,而不是直接綁定元素
- 盡量使用鏈?zhǔn)綄?xiě)法提高編程效率和代碼運(yùn)行效率
3淌实、代碼組織方式
vue實(shí)際上是一種MVVM模式,即Model源织,View翩伪,ViewModel微猖。通常一個(gè)頁(yè)面都是由Model(ajax數(shù)據(jù))和View(模板html)兩部分的谈息,但還缺一個(gè)組合這兩部分的模塊。前端MVC中的C就是這么一個(gè)模塊凛剥,稱(chēng)之為控制器Controller侠仇。對(duì)于小型項(xiàng)目MVC已經(jīng)可以應(yīng)對(duì)了,與之相似的還有MVP模式犁珠,其實(shí)前端就是這么一個(gè)發(fā)展過(guò)程:原生JS直接DOM=>jQuery操作DOM=>MVC模式=>MVP模式=>MVVM模式=>MVNV*模式÷叽叮現(xiàn)在以一個(gè)實(shí)例演示如何在小型項(xiàng)目中用上MVC模式:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>MVC</title>
</head>
<body>
<main>
<div id="home"></div>
<a href="#about"></a>
</main>
<template id='home-tmpl'>
{{~it.content :value:key}}
<div>{{value}}</div>
{{~}}
</template>
<script src='./zepto.min.js'></script>
<script src='./router.js'></script>
<script src='./doT.js'></script>
<script src='./index.js'></script>
</body>
</html>
// 路由初始化
Router.config({
default: 'home',
routes: {
'home': function() {},
'about': function() {}
}
});
Router.add('home', Home.controller)
.add('about', About.controllter)
.start();
var Home = {
$home: $('#home'),
tmpl: $('#content-tmpl').html(),
render: function(tmpl, data) {
var tmpl_after = doT.template(tmpl, data);
$home.html(tmpl_after);
},
modelAdapter: function(data) {
var fixData = null;
//對(duì)原始數(shù)據(jù)做處理...
return fixData;
},
eventInit: function() {
// 事件代理(不必等到頁(yè)面渲染完才開(kāi)始綁定)
$home.on('click', '.selector', function(event) {
event.preventDefault();
});
},
controller: function() {
$.ajax({
url: '/path/to/file',
type: 'GET',
dataType: 'json',
data: {
'key': 'value'
},
success: function(result) {
var data = this.modelAdapter(result);
this.render(this.tmpl, data);
},
error: function(err) {
console.log(err);
}
})
}
}
var About = {
// 與Home類(lèi)似
}
大致是這么個(gè)流程,再配合gulp等項(xiàng)目構(gòu)建犁享、打包工具(具體gulpfile.js配置項(xiàng)可參看這里)余素,項(xiàng)目基本就完成了。