zoukankan      html  css  js  c++  java
  • 通用前端开发框架

    前言

    最近在几个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文件。

     
  • 相关阅读:
    MiniGUI
    Android-在XML和Java代码中设置背景在不同状态的效果: <selector>/StateListDrawable
    URLEncoder.encode、URLDecoder.decode、escape、encodeURI、encodeURIComponent
    getDimension,getDimensionPixelOffset和getDimensionPixelSize的一点说明
    Android获取屏幕分辨率及DisplayMetrics简介
    细说Android事件传递机制(dispatchTouchEvent、onInterceptTouchEvent、onTouchEvent)
    Android
    Android坐标
    Android Sqlite IN, NOT IN syntax --- not int (?)
    TextView with SingleLine as true and Gravity as Center not passing the events to the ViewPager if it has a Click Event
  • 原文地址:https://www.cnblogs.com/Leo_wl/p/2455052.html
Copyright © 2011-2022 走看看