Successfully reported this slideshow.

旺铺前端设计和实现

975 views

Published on

  • Be the first to comment

旺铺前端设计和实现

  1. 1. 旺铺前端设计和实现 网站技术部-建站平台 魏琪君12年8月17日星期五
  2. 2. 大纲 1. APP ⼀一种方便快捷的开发方式 2. may/loader 统⼀一的模块定义方式,异步加载机制 3. 原理和模式 ⼀一些设计上的思考 4. 调试和诊断 调试和诊断也是系统的⼀一部分12年8月17日星期五
  3. 3. APP是什么? 1. 从页面结构上说, app是组成页面的基本单元,⼀一个页面由很多APP拼合而成 2. 从代码组织上说,app是⼀一种新的代码组织方式 codes groovy (php, nodejs) template vm (php, mustache) javascript css dataProvider ... 从而让前后端更加紧密地协作 3. app是按需加载的基本单元 通过tengine来实现js/css的静态按需加载,它是以app为颗粒度的 在diy后台, 前端也是以app为基本单元加载⼀一个app的js和css12年8月17日星期五
  4. 4. 实例展示 1. app目录结构,资源形式 2. dataProvider 3. 自动编辑框架12年8月17日星期五
  5. 5. APP的优点 1. 提高开发效率 开发调试方便,修改代码,刷新浏览器马上可以看到效果 不需要书写java, 只需要配置相应的服务(dataprovider),即可在模板中使用 得益于旺铺的架构,APP只需要关注和实现自己的业务,就可以在旺铺中正常展示 更好的开发环境,“⼀一键搭应用”, “在线开发” 等 2. 前后端融合得更紧密 配置采用的是前端熟悉的json格式,dataProvider等方式,让前端能够独立地开发APP 良好⼀一致的前端接口,丰富的组件库,让开发可以方便地书写前端代码12年8月17日星期五
  6. 6. may 1. 统⼀一模块定义和使用方式 2. 延用我们以往的开发思维和经验 3. 期望演化出⼀一套简单实用的业务型框架12年8月17日星期五
  7. 7. 以前的写法 (function($, WP) { var Util = WP.widget.Util; // import // 定义 WP.widget.Tabs = function() { ... }; })(jQuery, Platform.winport); (function($, WP) { var Tabs = WP.widget.Tabs; ... })(jQuery, Platform.winport)12年8月17日星期五
  8. 8. 现在的写法 define(‘widget.Tabs’, [‘jQuery’, ‘Class’], function($, Class) { return new Class({ init: function(div, options) { } }); }); define([‘widget.Tabs’], function(Tabs) { var tabs = new Tabs(...); }); 使用define定义⼀一个模块 define(id?, depends, factory) id: 模块名称 depends: 依赖的模块 factory: 模块工厂, 可以返回任何值, 当然也可以是普通数据结构12年8月17日星期五
  9. 9. AMD简介 1. api 说明 https://github.com/amdjs/amdjs-api/wiki/AMD 2. 实现 requirejs curl ... (注 seajs遵守的是CMD规范) 3. API define(id?, dependencies, factory) require(dependencies, callback) 4. 例子 define(‘widget/Tabs’, [‘jquery’], function($) { return ... }); require([‘widget/Tabs’], function(Tabs) { / })12年8月17日星期五
  10. 10. WHY NOT AMD? AMD(或seajs) 我们需要的 1. 简单⼀一致的模块定义 简单⼀一致的模块定义 2. 异步加载 组件的按需加载时需要 3 单⼀一入口 或期望由require来使用模块 已习惯多入口,即js载入后马上执行其内容 4. 由工具合并模块,减少请求 对多人开发支持得不够好,容易 5. 丰富的插件机制(如css载入, 原有js的包装等) 简单⼀一致的模块定义,适当的按需加载, 但能够延用现在的开发习惯12年8月17日星期五
  11. 11. may/loader的特性 1. 简单⼀一致的模块定义 define(‘widget.Tabs’, [‘jQuery’, ‘Class’], function() { ... }); 2. 匿名模块自动加载执行 define([‘widget.Tabs’], function(Tabs) { }); 3. 异步并行加载 define(‘A’, ..), define(‘B’, [‘A’]) define(‘C’, [‘B’]) define([‘C’], ...) 4. 支持css的异步加载 如 define(‘widget.A’, [‘http://.../css/.../a.css’], function() {...})12年8月17日星期五
  12. 12. 小摘要:CSS加载的原理 loader中的实现 IE中使用onload来监控是否完成 其他浏览器使用 img.onerror 来监控是否载入完毕 [参考文献] http://www.phpied.com/when-is-a-stylesheet-really-loaded/ http://thudjs.tumblr.com/post/637855087/stylesheet-onload-or-lack-thereof requirejs seajs12年8月17日星期五
  13. 13. 目前组件 1. loader 提供define模块定义方法, 并行异步加载功能 2. context 基于事件的模型,将节点和模块进行联系 3. log 简单的日志打印,有多实例和简单的过滤功能,IE6下也可以展示 4. class 方便类的创建 5. executor 用于调用⼀一个模块,或函数, 方便异常的统⼀一处理,执行时间的日志显示12年8月17日星期五
  14. 14. 原理和模式 ⼀一些设计和实现上的思考12年8月17日星期五
  15. 15. 页面组成 1. 页面是由⼀一个个模块组成(app, widget 及其他非ui组件), 它们都由统⼀一的语法define定义 2. 页面中渲染的东西就是app 3. 有⼀一类 具有相同样式,相同形为,可DIY的app,被称为版块(mod)12年8月17日星期五
  16. 16. 自定义事件的使用 当需要反转两个模块的依赖时,可以使用自定义事件(observer模式) 比如导横条编辑不走正常的编辑逻辑,那么可以这样实现 site.on(‘app-before-edit’, function() { doTopNavEdit(); // 做特有的编辑 return false; // 不走正常编辑逻辑 }); 备注: 查看jQuery.cache[1].events,可以得到旺铺中的合局自定义事件的使用12年8月17日星期五
  17. 17. 约定 APP开发 1. ⼀一个app的css需要带上appName的前缀,以避免冲突 mod-$appName ... mod-$appName-$template... app-$appName... .mod-form-$appName... .mod-form-$appName-$template... 2. 非匿名模块名称需要和文件名⼀一致,以提高可读性,并实现按需加载 define(‘widget.Tabs’, ...) 3. app中定义的模块需要以 app.$appName. 作为包名, 以实现app中模块的按需加载 define(‘app.offerGeneral.OfferGeneralFormHandler’) 4. 组件初始化方法(构造函数或静态构造函数),期望有两个参数 element 和 options 以方便 autoWire (通过 AutoWire,我们不需要书写js就能调用组件) 如 图片缩放 <img .. data-autowire=’{“widget.ImageResizer”, “size”: 200 }’ ... 轮播 <ul data-autowire=’{“widget.Tabs”, “effect”: “rool”}’ alitalk <a href= autowire=”widget.Alitalk” data-alitalk=””>...12年8月17日星期五
  18. 18. 布局和APP的关系12年8月17日星期五
  19. 19. 稳定依赖 和 正交性 1. 引入中间层 regionType: small normal big full fly 2. 每个布局(layout)的单元格(region) 有⼀一个属性 regionType 3. app配置信息中定义: regionTypes: [‘small’], 表示可以放在small的region中,不管布局12年8月17日星期五
  20. 20. 规则和流程 数据和代码12年8月17日星期五
  21. 21. 定义⼀一种数据结构(DSL),描述你的业务[规则] 用代码以⼀一定的[流程]解析结构 cache: { small: { 64: { value: 8, items: [4, 8, 12] }, 150: { value: 4, items: [4, 6, 8] } }, normal: { 120: { value: 8, items: [4, 8, 12, 16] }, 150: { value: 6, items: [3, 6, 9, 12] }, 220: { value: 4, items: [2, 4, 6, 8] } }, big: { 120: { value: 10, items: [5, 10, 15, 20] }, 150: {12年8月17日星期五
  22. 22. 数据结构示例2 APP编辑框架12年8月17日星期五
  23. 23. [ { "title": "标题设置", "items": [ { "type": "text", "label": "版块标题", "name": "title", "value": "${appdata.title}", "maxlength": 10, "prompt": "请为该板块命名" }] }, { "title": "产品信息筛选", "items": [ { "type": "categorySelect", "name": "catId", "value": "${appdata.catId}", "dataProvider": "$offerCategoryList" }, { "type": "text", "label": "产品关键字", "name": "keywords", "value": "${appdata.keywords}", "maxlength": 50, "prompt": "请输入关键词筛选" }, { "type": "range", "label": "价格范围", "firstName": "priceStart",12年8月17日星期五
  24. 24. 数据结构示例3 TRACELOG // 打点数据开始 var Data = { body: [ // 布局入口/退出布局 [a.layout-mode-switcher, function() { return (isLayoutMode() ? wp_design_layoutmode_unfold_ : wp_design_layoutmode_fold_) + Component.getPageName(); }], // 添加布局 [a.segment-fly-adder, wp_design_layoutmode_layout_add2], // 删除布局 [div.segment-bar a.delete, wp_design_layoutmode_layout_delete], // 上移布局 [div.segment-bar a.up, wp_design_layoutmode_layout_move_up], // 下移布局 [div.segment-bar a.down, wp_design_layoutmode_layout_move_down], // 左右交换 [div.segment-bar a.switch, wp_design_layoutmode_layout_change], // 添加板块 [div.box-adder, layoutTrace(wp_design_layoutmode_widget_add, wp_design_widget_add)], // 删除板块 [div.box-bar a.delete, layoutTrace(wp_design_layoutmode_widget_delete, wp_design_widget_delete)], // 设置板块12年8月17日星期五
  25. 25. 旺铺模块⼀一览表 核心 前后台都使用, 用于 [自定义事件] [远程调用] [APP和站点信息的获取]12年8月17日星期五
  26. 26. 容器 用于管理app模块和页面业务模块12年8月17日星期五
  27. 27. 容器 用于管理app模块和页面业务模块 AppContext.register(‘view’, appName, Initializer) AppContext.register(‘edit’, appName, Handler) AppContext.register(‘view.template’, appName, Initializer) AppContext.register(‘edit.template’, appName, Handler)12年8月17日星期五
  28. 28. 组件 旺铺中使用的ui等组件12年8月17日星期五
  29. 29. DIY接口 给其他模块提供服务12年8月17日星期五
  30. 30. 编辑 自动生成编辑页面 策略模式 工厂模式12年8月17日星期五
  31. 31. widget.Validation 在js中实现策略模式方便,也非常常用,让代码简洁 使用验证器 var validation = new Validation(elm, { handler: ‘instant’, rules: { type: ‘require’, message: ‘请输入内容’ } });12年8月17日星期五
  32. 32. 编辑 用于APP编辑 装饰器模式 和 代理模式12年8月17日星期五
  33. 33. 调试和诊断也是系统的⼀一部分 1. 日志: 设置日志级别 http://www.sz99and1.cn/?debug-log-level=info 过滤日志 http://www.sz99and1.cn/?debug-log-level=info&debug-log-filter=ViewContext 方便IE日志查看和js执行 http://www.sz99and1.cn/?debug-log-level=info&debug-console=true 在线调试或线上排查时,采用非min文件 http://www.sz99and1.cn/?debug-style=true 2. 功能 在diy后台隐藏shim,以方便开发 http://esite.china.alibaba.com/page/index.htm?site_id=winport&debug-hide-shim=true 可以直接使用 AppService, TemplateService, CustomStyleService 进行DIY的操作12年8月17日星期五

×