1、前言javascript
前幾日使用微信網頁版時,好奇這個網頁用了什麼前端框架。用Chrome的開發人員模式一探到底,發現原來用了一個名叫 Angular 的框架。好吧,既然微信用了。那我也最好仍是看看。等等,你這篇文章的標題不是「初探Vue」嗎?鬼扯什麼Angular呢?html
好吧,我認可有些跑題。前端
是的,我本來是要學着用Angular的,但是翻看網貼和資料後。發現有不少相似的框架,着力解決「在瀏覽器端怎樣以優雅的方式動態生成html網頁」的問題。當中就有前Google員工,咱大中華子民@youyuxi 尤小右同窗開創的框架 Vue。vue
OK,總算回到正題了。java
因而藉着這個由頭。翻看了一些對照各種流行前端框架優劣的文章。終於。我選擇先拿 Vue 用用,試着改造個人部分已有業務。ajax
我選擇Vue的緣由是:它彷佛能夠優雅並且簡單地解決個人問題——頁面佈局和數據模型能夠有很是清晰的邊界,並且能夠以鬆散的方式結合或關聯。這裏還要插一句:我以爲前端的展示,最後能和js 百分百的兼容。數組
我討厭、反感使用jsp標籤,使用s:iterator,使用el表達式!因此。可使用js語法來實現渲染,是我求之不得的!瀏覽器
好吧,實際體驗又是怎樣?前端框架
2、列表的渲染微信
固然,通常的體驗都是關於Hello, world 怎樣實現。
但那個太0基礎,咱們直接上高級一些的。
假如我有一個表格需要呈現。該怎樣作?
1. 首先要引入 vue 庫的 js,參見後文連接;注意:開發期間必定要引入開發版,不然查起問題來全然找不到北。
2. 要渲染的表格(略去table頭),形如:
<tbody id="dataList" > <tr v-for="item in items" id="row_{{$index}}" > <td>{{item.dataId}}</td> <td>{{item.appKey}}</td> .... </tr> </tbody>
3. js的部分,需要建立 vue 對象,來關聯DOM元素和數據。並終於實現數據同步。
比方下面代碼:
vueItems = new Vue({ el: '#dataList', data: { items: [ ] } });4. OK。到眼下爲止。咱們的 vueItems 對象已經和 id 爲 "dataList" 的 DOM 元素掛鉤了。並且。經過在 html 裏面 tr 一節的 "v-for" 屬性。代表了要經過對 vueItems 對象的 數組元素進行遍從來渲染出表格的行數據。
5. 所以,接下來就是往 vueItems.items 裏面放入數據的過程。稍等一下,爲什麼是 vueItems.items, 而不是 vlueItems.data.items 呢?假設你和我同樣有這個想法。那麼很是不幸你被誤導了。構建 vue 對象時,傳入的 對象的 data 屬性,並不在興許的 vue 對象中真實存在。
要訪問數組的模型,必須用 vueItems.items。
6. OK。不論數據來源於動態網頁的生成過程,仍是ajax 請求獲得,總歸會有一個 JS 的數組對象做爲原始的數據。
若是它就是 list 對象。那麼。這時需要對list進行遍歷。將list對象通過處理後。造成 vueItems 的真正用來渲染的數據。個人慣例是我寧願用js來實現。而不肯意把這個過程放到模版裏。
因此就有相似下面的代碼:
for (var key in list) { <span style="white-space:pre"> </span>var vueItem = {}; var dataItem = list[key]; vueItem.app_name = dataItem.app_name == null ?"--" : dataItem.app_name; vueItem.app_key = dataItem.app_key == "" ? "--" : dataItem.app_key; vueItem.consume_fund = dataItem.consume_fund / 1000; vueItem.reason = dataItem.reason == 0 ? "成功" : "錯誤碼(" + dataItem.reason + ")"; vueItems.items.push(vueItem); }
當中,最要緊的是就是最後一句 :
vueItems.items.push(vueItem);這是Vue 這個框架奇妙的地方:將頁面渲染的細節隱藏起來。代碼簡潔、優雅。
我調試了代碼,表格的行依照要求渲染出來,大功告成!除了有個細節之外,即包括 {{}}內容的模版行會顯示一下,而後隱藏。這個好解決。就是把tbody先設爲隱藏,等數據載入好了。再顯示就能夠。因此改進後的數據模版是這種:
<tbody id="dataList" style="display:none;"> <tr v-for="item in items" id="row_{{$index}}" > <td>{{item.dataId}}</td> <td>{{item.appKey}}</td> .... </tr> </tbody>而後js代碼裏要加上一句:
$("#dataList").show();
一切顯得很是完美。
正當我準備收工的時候,壞了。
由此也引出下一個章節。
3、意料以外的異常
我忽然發現,當我頁面上的條件更改後。又一次獲取數據,再次使用vue作渲染,結果居然拋出了異常。
這個異常不是在個人js裏面拋出,而是在另外的線程。在 vue 的延時更新的定時器裏拋出的。
Uncaught TypeError: Cannot read property 'removeChild' of null remove @ vue.js:1176 (anonymous function) @ vue.js:1028 applyTransition @ vue.js:1056 removeWithTransition @ vue.js:1027 singleRemove @ vue.js:4483 remove @ vue.js:4985 diff @ vue.js:4816 update @ vue.js:4728 Directive._bind._update @ vue.js:7708 Watcher.run @ vue.js:3257 runBatcherQueue @ vue.js:2990 flushBatcherQueue @ vue.js:2964 nextTickHandler @ vue.js:434
看到這個錯誤,我一下傻了。
老革命遇到新問題了。
這,,。這框架怎麼了?不是很是行的嘛?不是大牛開發的嗎?。!
!
我重複看了代碼。沒問題啊。難道真的是框架的問題。
OK,我弄一個乾淨的列表的Demo,試試。
結果,新作的Demo沒問題。
這下沒轍了。又懷疑其它,,,,,,折騰了十幾分鍾。。。。
。這裏略去N字以及苦水若干升。
絕望之中,我細緻看了看這個異常的內容:Cannot read property 'removeChild' of null
我彷佛悟到一些什麼。
我一拍大腿。明確了。NND(我TM豬頭啊,...這裏又略去N字)。
原來,我改造代碼時。忘記將原先的一行代碼去掉了,這行代碼是直接訪問DOM將表格的數據清除。因爲當用戶再次點擊查詢時,需要將原數據刪除。而後又一次append新的行。
我將上述這句代碼刪除。這回最終OK 了!
原來,在Vue裏面。假設DOM元素已經綁定了Vue框架,則不能再經過DOM直接進行刪除,必須要經過Vue的對象來刪除。至少我使用的Vue 1.0.13 版本號是這個狀況。
好吧。切切!
之後不能再犯這樣的低級錯誤了。
4、後記
前述那個異常。到底是要容錯仍是應該拋出異常?彷佛容錯也說得通。因此我將這個狀況發了個推告知給做者。讓他評估一下。因爲時差的關係,他尚未回覆我。