用 Weex Vanilla 寫 Todolist 的嘗試

knhk5997 7年前發布 | 14K 次閱讀 Weex 移動開發

關于如何在 Weex 上使用 Vanilla 代碼寫頁面, 在前面有一篇文章已經介紹過了:

https://hashnode.com/post/run...

大致上, 可以參考這個 Demo, 其實就是一些 DOM 操作,

https://github.com/alibaba/we...

所以我明確的一個事實是 Weex 確實有一套 DOM API,

而且這套 API 應該說是所有基于 Weex 的框架的基礎, 像 Weex, Rax, 甚至如果有 Angular 版本.

在 Weex 倉庫里可以看到目前有 4 個框架, 其中 Vanilla 對應沒有框架,

https://github.com/apache/inc...

但實際上這個代碼已經過時了, 比如后來的 weex 全局變量沒有的完成,

所以為了方便我在本地開發, 我自己基于 Vue fork 了一個版本, 用來試驗,

https://gist.github.com/jiyin...

試驗項目可以從 GitHub 上看, 用單個文件生成的 Todolist:

https://github.com/mvc-works/...

最終的界面:

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

  • 清除已讀的任務

  • 排序

沒有做是因為太難實現了, 雖然也不是那么難, 但作為試驗項目主要的目的吧,

我主要還是未來試驗 Weex 的 DOM API 能不能寫出像樣的頁面,

經過簡單的封裝, DOM 部分的寫法在 CoffeeScript 里挺清晰的,

# 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 操作的應該能腦補出我的代碼來:

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 操作,

兩邊都處理, 保證界面上沒有出現狀態不一致的情況, 當然寫起來很啰嗦, 維護性差,

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 那么強的功能.

手寫 DOM 操作的方法基本上都是效率低下, 可維護性極差, 之類的,

除非是為了寫幾乎靜態的頁面, 這種方案完全可以被扔進歷史的廢紙簍...

不過也有一點好處, 就是沒有太多抽象, 頁面啟動非常快, 提交很小.

雖然 Weex 一直運行在一個 js runtime 中, 但初始化組件多多少少有一點開銷.

也許說是微乎其微... 但是從理論上而言, 啟動過程需要執行的代碼總是有區別的.

當然總體上說這樣寫幾乎沒什么用, 只是證明 Native DOM API 能正常用:

http://weex.apache.org/refere...

沒有明確的觀點, 只是換著思路想想寫 Weex 遇到的一些問題...

 

來自:https://segmentfault.com/a/1190000008726905

 

 本文由用戶 knhk5997 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!