用 Weex Vanilla 寫 Todolist 的嘗試

關於如何在 Weex 上使用 Vanilla 代碼寫頁面, 在前面有一篇文章已經介紹過了:
https://hashnode.com/post/run...
大體上, 能夠參考這個 Demo, 其實就是一些 DOM 操做,
https://github.com/alibaba/we...
因此我明確的一個事實是 Weex 確實有一套 DOM API,
並且這套 API 應該說是全部基於 Weex 的框架的基礎, 像 Weex, Rax, 甚至若是有 Angular 版本.javascript

在 Weex 倉庫裏能夠看到目前有 4 個框架, 其中 Vanilla 對應沒有框架,
https://github.com/apache/inc...
但實際上這個代碼已通過時了, 好比後來的 weex 全局變量沒有的完成,
因此爲了方便我在本地開發, 我本身基於 Vue fork 了一個版本, 用來試驗,
https://gist.github.com/jiyin...
試驗項目能夠從 GitHub 上看, 用單個文件生成的 Todolist:
https://github.com/mvc-works/...
最終的界面:html

在這個 Todolist 當中我實現了基本的增刪改功能, 但明顯確實一下功能:html5

  • 清除已讀的任務java

  • 排序node

沒有作是由於太難實現了, 雖然也不是那麼難, 但做爲試驗項目主要的目的吧,
我主要仍是將來試驗 Weex 的 DOM API 能不能寫出像樣的頁面,
通過簡單的封裝, DOM 部分的寫法在 CoffeeScript 裏挺清晰的,git

# 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())

熟悉 DOM 操做的應該能腦補出個人代碼來:github

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

而後是事件處理, 這就有點問題了, 實際上有兩個地方須要處理, Model 和 View,
熟悉 jQuery 的同窗應該就能猜到了, 須要經過 event.target 作 DOM 操做,
兩邊都處理, 保證界面上沒有出現狀態不一致的狀況, 固然寫起來很囉嗦, 維護性差,apache

onRemove = (taskId) -> (event) ->
  store.tasks = store.tasks.filter (task) -> task.id isnt taskId
  # DOM operations
  taskElement = event.target.parentNode
  taskElement.parentNode.removeChild taskElement
  modifyRaw()

若是頁面當中還有 Tab 的話, Tab 頁之間的狀態管理會讓頁面變得很是複雜,
固然爲了方便使用, 我模仿了 React 的 ref 寫法用來指定 DOM 的特定引用,
這樣在小的頁面當中也沒有使用 jQuery 選擇 DOM 節點的必要了.
因此看上去整個頁面仍是能夠跑通的, 雖然效果實在很奇怪.編程

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()

其實能夠從這個試驗反思一下 Vue React 這些東西在移動端是否合適,
能夠用這些框架主要是爲了桌面平臺的單頁面 App 建造起來的,
附帶了各類狀態管理, 組件化, DSL, 編程風格在裏邊, 以及各類開發工具,
最主要的是聲明式的寫法確實提升了開發速度和組件的複用.
不過手機上狀態管理的沒有桌面端複雜卻是, 未必須要 React 那麼強的功能.api

手寫 DOM 操做的方法基本上都是效率低下, 可維護性極差, 之類的,
除非是爲了寫幾乎靜態的頁面, 這種方案徹底能夠被扔進歷史的廢紙簍...
不過也有一點好處, 就是沒有太多抽象, 頁面啓動很是快, 提交很小.
雖然 Weex 一直運行在一個 js runtime 中, 但初始化組件多多少少有一點開銷.
也許說是微乎其微... 可是從理論上而言, 啓動過程須要執行的代碼老是有區別的.

固然整體上說這樣寫幾乎沒什麼用, 只是證實 Native DOM API 能正經常使用:
http://weex.apache.org/refere...沒有明確的觀點, 只是換着思路想一想寫 Weex 遇到的一些問題...

相關文章
相關標籤/搜索