用 Weex Vanilla 写 Todolist 的尝试
knhk5997
8年前
<p>关于如何在 Weex 上使用 Vanilla 代码写页面, 在前面有一篇文章已经介绍过了:</p> <p><a href="/misc/goto?guid=4959742125719232459" rel="nofollow,noindex">https://hashnode.com/post/run...</a></p> <p>大致上, 可以参考这个 Demo, 其实就是一些 DOM 操作,</p> <p><a href="/misc/goto?guid=4959742125811659421" rel="nofollow,noindex">https://github.com/alibaba/we...</a></p> <p>所以我明确的一个事实是 Weex 确实有一套 DOM API,</p> <p>而且这套 API 应该说是所有基于 Weex 的框架的基础, 像 Weex, Rax, 甚至如果有 Angular 版本.</p> <p>在 Weex 仓库里可以看到目前有 4 个框架, 其中 Vanilla 对应没有框架,</p> <p><a href="/misc/goto?guid=4959742125896731304" rel="nofollow,noindex">https://github.com/apache/inc...</a></p> <p>但实际上这个代码已经过时了, 比如后来的 weex 全局变量没有的完成,</p> <p>所以为了方便我在本地开发, 我自己基于 Vue fork 了一个版本, 用来试验,</p> <p><a href="/misc/goto?guid=4959742125984373434" rel="nofollow,noindex">https://gist.github.com/jiyin...</a></p> <p>试验项目可以从 GitHub 上看, 用单个文件生成的 Todolist:</p> <p><a href="/misc/goto?guid=4959742126076214924" rel="nofollow,noindex">https://github.com/mvc-works/...</a></p> <p>最终的界面:</p> <p style="text-align:center"><img src="https://simg.open-open.com/show/5234eb4889a79ef973ebcef97dd52afe.jpg"></p> <p>在这个 Todolist 当中我实现了基本的增删改功能, 但明显确实一下功能:</p> <ul> <li> <p>清除已读的任务</p> </li> <li> <p>排序</p> </li> </ul> <p>没有做是因为太难实现了, 虽然也不是那么难, 但作为试验项目主要的目的吧,</p> <p>我主要还是未来试验 Weex 的 DOM API 能不能写出像样的页面,</p> <p>经过简单的封装, DOM 部分的写法在 CoffeeScript 里挺清晰的,</p> <pre> <code class="language-javascript"># DOM tree mainTree = -> div style: styleBody, div style: styleContainer, div style: styleHeader, input ref: 'input' style: styleInput attr: {value: '', placeholder: 'Some task...'} event: {input: onDraft} text style: styleButton attr: {value: 'Add task'} event: {click: onAdd} text ref: 'raw' attr: {value: getRaw()} style: styleContent div ref: 'content' style: styleContent # mounting document doc.documentElement.appendChild (helicalExpandTree mainTree())</code></pre> <p>熟悉 DOM 操作的应该能脑补出我的代码来:</p> <pre> <code class="language-javascript">helicalExpandTree = (tree) -> # console.log '\n\nExpanding:', JSON.stringify(tree) [name, props, children] = tree element = doc.createElement name, style: props.style attr: props.attr if props.event for key, value of props.event element.addEvent key, value if children? # console.log 'CHILDREN:', JSON.stringify(children) for child in children childElement = helicalExpandTree child # console.log '\n\nChild to append:', JSON.stringify(childElement) element.appendChild childElement if props.ref? domRefs[props.ref] = element element</code></pre> <p>然后是事件处理, 这就有点问题了, 实际上有两个地方需要处理, Model 和 View,</p> <p>熟悉 jQuery 的同学应该就能猜到了, 需要通过 event.target 做 DOM 操作,</p> <p>两边都处理, 保证界面上没有出现状态不一致的情况, 当然写起来很啰嗦, 维护性差,</p> <pre> <code class="language-javascript">onRemove = (taskId) -> (event) -> store.tasks = store.tasks.filter (task) -> task.id isnt taskId # DOM operations taskElement = event.target.parentNode taskElement.parentNode.removeChild taskElement modifyRaw()</code></pre> <p>如果页面当中还有 Tab 的话, Tab 页之间的状态管理会让页面变得非常复杂,</p> <p>当然为了方便使用, 我模仿了 React 的 ref 写法用来指定 DOM 的特定引用,</p> <p>这样在小的页面当中也没有使用 jQuery 选择 DOM 节点的必要了.</p> <p>所以看上去整个页面还是可以跑通的, 虽然效果实在很奇怪.</p> <pre> <code class="language-javascript">onAdd = (event) -> newTask = id: getId(), done: 'false', text: store.draft store.draft = '' store.tasks.unshift newTask # DOM operations console.log 'DOM operations!!!' domRefs.input.setAttr 'value', '' newElement = helicalExpandTree (taskTree newTask) console.log '\nnewElement:', newElement domRefs.content.appendChild newElement modifyRaw()</code></pre> <p>其实可以从这个试验反思一下 Vue React 这些东西在移动端是否合适,</p> <p>可以用这些框架主要是为了桌面平台的单页面 App 建造起来的,</p> <p>附带了各种状态管理, 组件化, DSL, 编程风格在里边, 以及各种开发工具,</p> <p>最主要的是声明式的写法确实提高了开发速度和组件的复用.</p> <p>不过手机上状态管理的没有桌面端复杂倒是, 未必需要 React 那么强的功能.</p> <p>手写 DOM 操作的方法基本上都是效率低下, 可维护性极差, 之类的,</p> <p>除非是为了写几乎静态的页面, 这种方案完全可以被扔进历史的废纸篓...</p> <p>不过也有一点好处, 就是没有太多抽象, 页面启动非常快, 提交很小.</p> <p>虽然 Weex 一直运行在一个 js runtime 中, 但初始化组件多多少少有一点开销.</p> <p>也许说是微乎其微... 但是从理论上而言, 启动过程需要执行的代码总是有区别的.</p> <p>当然总体上说这样写几乎没什么用, 只是证明 Native DOM API 能正常用:</p> <p><a href="/misc/goto?guid=4959742126159799289" rel="nofollow,noindex">http://weex.apache.org/refere...</a></p> <p>没有明确的观点, 只是换着思路想想写 Weex 遇到的一些问题...</p> <p> </p> <p>来自:https://segmentfault.com/a/1190000008726905</p> <p> </p>