JPEG 有两种存储格式:baseline 和 progressive。Baseline JPEG 会在数据可用时,一行一行自上而下
显示。Progressive JPEG 会先显示模糊图片,然后逐渐清晰
。
Vue.js 是一个基于 MVVM
模型的 web 库。通过双向数据绑定连接 View 和 Model 层。实际的 DOM 操作被封装成 Directives
和 Filters
。
基本定义
每个 Vue 对象的实例是一个 ViewModel。创建方式:
1 2 3 4 5 |
<span class="keyword">var</span> vue = <span class="keyword">new</span> Vue({ el: view, data: model }); |
其中 vue.$el
用于管理 View 层上的 DOM 。而 vue.$data
用于管理 Model 层的数据,可以通过 vue.$data.property
访问 Model 层数据,也可以直接 vue.property
访问。
Hello World 入门
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
<div id=<span class="string">"example"</span>> <h1>{{ title }}</h1> <ul> <li v-repeat=<span class="string">'todo:todoList'</span>>{{ todo | uppercase }}</li> </ul> </div> <span class="comment">// 对应 js</span> <span class="keyword">var</span> demo = <span class="keyword">new</span> Vue({ el: <span class="string">'#example'</span>, data: { title: <span class="string">'todo list'</span>, todoList: [<span class="string">'do work'</span>, <span class="string">'read book'</span>, <span class="string">'shopping'</span>] } }); |
从上面的例子可以看出:
- 模版替换使用的是
{{ variable }}
- Directives 格式是
v-xxx
,如上 v-repeat 。 - Filtrs 格式是
{{ variable | filter }}
,如上 uppercase
事件
在 DOM 节点上通过 v-on
绑定处理函数(可以是表达式)。函数的第一个参数是 DOM Event 对象,该对象附带 targetVM
指向 DOM 对应的 ViewModel。
1 2 3 4 5 6 7 8 9 10 11 |
<div id=<span class="string">"example"</span> v-on=<span class="string">"click : clickHandler"</span>></div> <span class="keyword">var</span> vue = <span class="keyword">new</span> Vue({ el: <span class="string">'#example'</span>, data: {}, methods: { clickHandler: <span class="keyword">function</span>(e){ console.log(e.targetVM); <span class="comment">// 指向vue对象,可以理解为this。</span> } } }); |
自定义指令
内置的指令不够用怎么办?想自定义数据变化对 DOM 的影响怎么破?
Vue.js 允许自定义全局指令,格式:
1 2 3 4 5 6 7 8 9 10 11 12 |
Vue.directive(id, { bind: <span class="keyword">function</span>(){ <span class="comment">// 仅在初始化绑定元素时调用</span> }, update: <span class="keyword">function</span>(newVal, oldVal){ <span class="comment">// 初始化时调用一次,以后每次数据变化,就被调用</span> }, unbind: <span class="keyword">function</span>(){ <span class="comment">// 仅在指令解绑时被调用</span> } }); |
同时,在指令函数中,提供了一些 this
上下文的公开属性(这里列举了几个常用的):
el
: 访问绑定的 DOM 元素,提供 View 层访问。vm
: 访问指令对应的上下文,ViewModel 对象,this.vm.$el = this.el
expression
: 指令绑定的表达式,不包括参数和 filterargs
: 参数
举个栗子。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
<div id=<span class="string">"example"</span> v-demo=<span class="string">"args: message"</span> v-on=<span class="string">"click: onClick"</span>></div> Vue.directive(<span class="string">'demo'</span>, { acceptStatement: <span class="keyword">true</span>, bind: <span class="keyword">function</span>(){ <span class="keyword">this</span>.el.style.cssText = <span class="string">'color: red; background: #666;'</span>; }, update: <span class="keyword">function</span>(newVal, oldVal){ <span class="keyword">this</span>.el.innerHTML = <span class="string">'name = '</span> + <span class="keyword">this</span>.name + <span class="string">'<br/>'</span> + <span class="string">'arg = '</span> + <span class="keyword">this</span>.arg + <span class="string">'<br/>'</span> + <span class="string">'expression = '</span> + <span class="keyword">this</span>.expression + <span class="string">'<br/>'</span>; console.log(<span class="keyword">this</span>.vm.<span class="variable">$data</span>); console.log(<span class="keyword">this</span>.el === <span class="keyword">this</span>.vm.<span class="variable">$el</span>); } }); <span class="keyword">var</span> demo = <span class="keyword">new</span> Vue({ el: <span class="string">'#example'</span>, data: { message: <span class="string">'hello world!'</span> }, methods: { onClick: <span class="keyword">function</span>(){ <span class="comment">// custom directive update will be called.</span> <span class="keyword">this</span>.<span class="variable">$data</span>.message = <span class="string">'hahaha!'</span>; } } }); |
自定义过滤器
Vue.js 允许使用全局函数 Vue.filter()
定义过滤器,将 Model 数据输出到 View 层之前进行数据转化。
1 2 |
Vue.filter(id, <span class="keyword">function</span>(){}); |
双向过滤器允许 View 层数据(input 元素)变回写到 Model 层之前,进行转化,定义方式如下:
1 2 3 4 5 |
Vue.filter(id, { read: <span class="keyword">function</span>(val){}, write: <span class="keyword">function</span>(newVal, oldVal){} }); |
举个栗子:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
<div id=<span class="string">"example"</span>> <p>{{ message }}</p> <input type=<span class="string">'text'</span> v-model=<span class="string">"message | twoWays"</span>></div> </div> Vue.filter(<span class="string">'twoWays'</span>, { read: <span class="keyword">function</span>(val){ <span class="keyword">return</span> <span class="string">'read '</span> + val; }, write: <span class="keyword">function</span>(newVal, oldVal){ console.log(newVal, oldVal); <span class="keyword">return</span> ov + <span class="string">' write'</span>; } }); <span class="keyword">var</span> demo = <span class="keyword">new</span> Vue({ el: <span class="string">'#example'</span>, data: { message: <span class="string">'hello'</span> } }); |
总结
Vue.js 提供的核心是 MVVM 中的 VM,确保视图和数据的一致性。同时,借鉴了 Angular 中的 Directive 和 Filter 的概念,但是却简化了 API。
Rosin 是一个 Fiddler 插件,协助开发者进行移动端页面开发调试。
特性
- 可配置的页面匹配规则
- 拦截 console
- 日志内容的存储,展示,过滤
- 脚本运行错误捕获
原理
- 首先在 fiddler 里面配置了匹配规则
- 访问的页面进过 fiddler 之后,匹配规则会生效,如命中,则在返回的内容中注入脚本。
- 脚本重写了 console 的各种方式(也监听了 onerror 事件)
- 将 console 打出的各种消息 push 到消息队列
- 队列达到阈值或者间隔的时间到,就将消息通过 xhr 发送到
http://__rosin__.qq.com
- rosin 插件在 fiddler 中捕获上面的请求(并且隐藏了,所以看不到这个请求),将请求的 body 部分显示到面板上面
- 将 log 存储到本地
D:Program Files (x86)Fiddler2ScriptsRosinLog
1 2 3 4 5 6 7 8 9 10 11 12 |
add: <span class="keyword">function</span>() { <span class="keyword">Array</span>.prototype.push.apply(<span class="keyword">this</span>._queueArr, arguments); <span class="comment">// 定时发送消息</span> clock.start(); <span class="comment">//队列达到阈值就触发上传</span> <span class="keyword">if</span> (<span class="keyword">this</span>._queueArr.length >= THRESHOLD) { <span class="keyword">this</span>._post(<span class="keyword">this</span>._queueArr.splice(<span class="number">0</span>, <span class="keyword">this</span>._queueArr.length)); <span class="keyword">return</span>; } } |
Log 格式:
JSConsole
JSConsole 是一个 JS 命令行调试工具。
如何使用
- 在
http://jsconsole.com/
中输入:listen
创建一个 session(主要是生成一个 GUID) - 在页面中引入脚本
1 2 |
<script src="http://jsconsole.com/remote.js?FAE031CD-74A0-46D3-AE36-757BAB262BEA"></script> |
原理
- 引入的 remote.js 脚本创建一个隐藏的 iframe,Url 指向了
http://jsconsole.com/remote.html
,并且把上面的 GUID 带上 - 重写 console 中的方法,这里的问题是:
如何把消息 push 到 jsconsole.com
? - 页面调用 console 等方法时,实际通过 postMessage 是向 iframe 发送了一条消息。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
log: <span class="keyword">function</span> () { <span class="keyword">var</span> argsObj = stringify(arguments.length == <span class="number">1</span> ? arguments[<span class="number">0</span>] : [].slice.call(arguments, <span class="number">0</span>)); ar response = []; [].<span class="keyword">forEach</span>.call(arguments, <span class="keyword">function</span> (args) { response.push(stringify(args, <span class="keyword">true</span>)); }); <span class="keyword">var</span> msg = JSON.stringify({ response: response, cmd: <span class="string">'remote console.log'</span>, type: msgType }); <span class="keyword">if</span> (remoteWindow) { remoteWindow.postMessage(msg, origin); } <span class="keyword">else</span> { queue.push(msg); } msgType = <span class="string">''</span>; } |
- iframe 中内嵌的页面收到消息后,通过 EventSource 向 server 发送信息内容(类似于 socket)
- 日志显示在 jsconsole.com 上面
- AppCan 是 HTMl5 移动开发应用平台,支持跨平台,可以简单、快速、高效开发移动应用。
- 倡导 Hybrid App 开发。
- 为 HTML5 开发提供底层 Native 交互能力。
主要优势
- 跨平台
- 原生体验,引入 Native UI 控件和交互
- 模拟调试:提供模拟器和调试工具
- 多窗口机制,秒杀 phoneGap
- 一键打包
- …
###开发工具 IDE
AppCan IDE 基于 Eclipse 定制,支持跨平台、本地打包、模拟调试、真机同步等功能
模拟调试
左边部分是手机的一些模拟器。
中间部分是手机屏幕,支持横竖屏切换和分辨率选择。
右边是 chrome 调试窗口,这里内置了 chromium。
本地打包
支持将 web 应用直接打成 APK(android)安装包。
真机同步
将应用生成 “AppCan 调试中心” 模式的安装包,使用手机安装,确保手机和 pc 在同一个网络内。手机上安装成功后,打开 app,输入 pc 的 IP,登录成功后,可以看到应用的 List,打开调试的应用,可以 pc 上 IDE 的控制台上看到请求。
- 打开手机上的 “AppCan 调试中心” APP,输入 pc 的 ip 地址,登录,即可看到应用的 List。
- 手机上打开应用后,pc 上 IDE 控制台看到调试信息
插件 API
AppCan 提供了丰富的底层插件,包括网络通讯,界面布局,功能扩展,第三方 SDK 等能力。API 文档可以参考 [这里], 覆盖了移动开发应用中的常用场景。(http://newdocx.appcan.cn/index.html?templateId=315)。
JS SDK
AppCan 将常用的 UI 和功能性模块封装成了一个开发库,开发者只需要引入 appcan.min.js 即可,另外把对 backbone, zepto, underscore 的依赖也打包在基础库中了
JS SDK 文档参考这里
###总结
AppCan 是一种基于 H5 实现跨平台 App 开发的解决方案,封装了一些常用的 UI 组件供 js 调用,提供了实现一整套流程的 IDE,包括调试,打包等。