H5 小型項(xiàng)目技術(shù)棧

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è)思想,我們可以自己組裝需要的類庫(kù)。

2.1、路由管理模塊

路由模塊目前比較出名(成熟)的是page.js,26.3KBdirector.js,19.9KB,這兩個(gè)框架完全可以滿足小項(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è)模塊,稱之為控制器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類似
}

大致是這么個(gè)流程,再配合gulp等項(xiàng)目構(gòu)建、打包工具(具體gulpfile.js配置項(xiàng)可參看這里),項(xiàng)目基本就完成了。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

推薦閱讀更多精彩內(nèi)容