前端框架 Vue 初探

jopen 8年前發布 | 53K 次閱讀 Vue.js 前端技術

一、前言

前幾日使用微信網頁版時,好奇這個網頁用了什么前端框架。用Chrome的開發者模式一探究竟,發現原來用了一個名叫  Angular 的框架。好吧,既然微信用了,那我也不妨看看。等等,你這篇文章的標題不是“初探Vue”嗎?鬼扯什么Angular呢?

好吧,我承認有些跑題。是的,我原本是要學著用Angular的,但是翻看網貼和資料后,發現有許多類似的框架,著力解決“在瀏覽器端如何以優雅的方式動態生成html網頁 ”的問題 。其中就有前Google員工,咱大中華子民 @ youyuxi 尤小右同學開創的框架 Vue。

OK,總算回到正題了。

于是借著這個由頭,翻看了一些對比各類流行前端框架優劣的文章。最終,我選擇先拿 Vue 用用,試著改造我的部分已有業務。

我選擇Vue的原因是:它似乎能夠優雅并且簡單地解決我的問題——頁面布局和數據模型可以有很清晰的邊界,并且能夠以松散的方式結合或關聯。這里還要插一句:我認為前端的展現,最后能和js 百分百的兼容。我討厭、反感使用jsp標簽,使用s:iterator,使用el表達式!所以,能夠使用js語法來實現渲染,是我夢寐以求的!

好吧,實際體驗又是如何?

二、列表的渲染

當然,一般的體驗都是關于Hello, world 如何實現。但那個太初級,我們直接上高級一些的。

假如我有一個表格需要呈現,該如何做?

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

}</pre>

其中,最要緊的是就是最后一句 :

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

一切顯得很完美!

正當我準備收工的時候,壞了。由此也引出下一個章節。

三、意料之外的異常

我突然發現,當我頁面上的條件更改后,重新獲取數據,再次使用 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 版本是這個情況。

好吧!切切!以后不能再犯這種低級錯誤了!

四、后記

前述那個異常,到底是要容錯還是應該拋出異常?似乎容錯也說得通。所以我將這個情況發了個推告知給作者,讓他評估一下。因為時差的關系,他還沒有回復我。

來自: http://blog.csdn.net/musicwind/article/details/50519471

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