脫離資料分散的問題,從 jQuery 換到 Vue.js

在剛接觸前端設計時,我們常會聽見兩個東西,不外乎就是 BootstrapjQuery,今天要談論的則是其中的 jQuery。jQuery 是個跨瀏覽器的 JavaScript 函式庫,透過簡單的幾個函式,就能夠輕鬆地操控頁面上的 DOM、元素。

其方法用起來真的夭壽簡單,但這僅限於你要開發單個頁面而已。倘若你正在開發一個小型網站,或是基本的文章頁面,就會慢慢地發現不易掌控資料,資料分散在頁面的各個角落。

資料分散,太過依賴 DOM、元素內容

因為 jQuery 如此好用,所以就會開始有人寫的很糟糕(就像 PHP 是世界上最好的語言,太過方便,所以被很多人鄙視。

如果我們要做一個商品頁面,可能就會有購物車計數器,用來顯示你的購物車有多少個物品,但一個頁面可能有兩個購物車計數器,所以看起來像這樣。

<div class="counter">0</div>  
<div class="counter-2">0 個商品</div>  
// 透過 Ajax 取得目前購物車的商品數量。
$.get('/get_count.php').done(function(data){
    // 將取得的商品數量顯示在頁面的元素上。
    $(".counter").text(data.count);
    $(".counter-2").text(data.count + " 個商品");
});

那麼假設我們要在這兩個購物車計數器累加呢?一些剛上手的 jQuery 初學者可能會寫成這樣。

// 將 .counter 的數字轉換成數值型態。
var count = parseInt($(".counter").text(), 10);  
// 更新頁面元素的商品數量。
$(".counter").text(count + 1);
$(".counter-2").text((count + 1) + " 個商品");

久而久之就會造成後續維護不易而且不穩定,原因有這些:

  1. 太過依賴元素內容:商品數量應該獨立成一個變數,而不是把頁面上的元素當作一個「存放區」用來擺放商品數量。
  2. 資料分散:商品數量現在分散在頁面上的各個角落,如果要更新商品數量,就必須把這些元素通通再寫一遍。搞不好還會不小心忽略其中一些元素。

那麼解決方案是什麼?我們可以將所有資料集中在一個地方,當我們更新資料的時候,框架就能夠自動幫我們更新頁面上的資料,就像 Vue.js 所做的那樣。

Vue.js 是什麼?

Vue.js 在前端所扮演的角色就是協助你如何在頁面上呈現、處理資料,而且這些都是有循有序的,而非像 jQuery 那樣程式可能會到處散佈在網頁各處。

如果你有聽過 Angular.jsReact.js,那麼你就懂 Vue.js 至少一半了。Vue.js 的效能還有開發效率比前兩個快上了許多(這部分你可以參考「Vue.js - 对比其他框架」文章)。

Vue.js 如何集中資料?

通常我們接收到了外來資料(如:來自 AJAX),以 jQuery 來說,我們會將這個資料以 $.text() 的方式設置到網頁上的元素內。

但是在 Vue.js 中,我們會將接收到的資料存放在一個「集中地」,然後透過 {{username}} 這樣的模板標籤來告訴 Vue.js:「請在這個地方顯示 username 資料」。

這就是所謂的「綁定」。意味著資料內的 username 有所變動的時候,頁面上的呈現也會跟著變動。你可以把它當作在頁面上擺放了一面鏡子,這個鏡子會映照回去資料所擺放的地方,而不是複製一份資料放在頁面上,所以你的資料現在都統一集中在一個地方,這令你更易於管理。

簡易的 Vue.js 實作

現在你知道 Vue.js 大概扮演著什麼樣的角色了,那麼就讓我們開始進行實作吧!首先記得引用 Vue.js 的 JavaScript,就像你平常如何引用 jQuery 函式庫那樣。

<script src="https://vuejs.org/js/vue.min.js"></script>  

接著撰寫我們的 HTML 頁面,{{counter}} 是 Vue.js 的模板標籤,這裡會顯示資料內的 counter,而 v-model="counter" 表示這個元素是跟資料內的 counter 有所綁定的。當我們變動這個輸入欄位的內容,實際上也就是在變動資料內的 counter 值。

<div id="demo">  
    <p>{{counter}}</p>
    <p>{{counter}} 個商品</p>
    <input v-model="counter">
</div>  

下面則是你的 JavaScript 片段,十分地簡潔。這會將 Vue.js 套用到你的 <div id="demo"> 元素內。而且定義了 {counter: 0} 的資料。

var demo = new Vue({  
    el: '#demo',
    data: {
        counter: 0
    }
})

你的網頁程式碼最終會長得像這樣。

現在打開你的瀏覽器瀏覽這個頁面,接著變動輸入欄位內的數字,是不是網頁上的計數器也會跟著變?(點我看線上範例測試

透過 Vue.js 你能夠將你的資料集中到一個地方進行管理,這就是為什麼你能夠只變動一個地方,網頁上其他的數字也跟著改變,因為他們都共享同一份資料!(耶!

用 Vue.js 替換 jQuery 吧

用了 Vue.js 之後我們就會很少用上 jQuery。你可能會好奇像是 $.on 這樣的函式如何在 Vue.js 裡實作,實際上在 Vue.js 裡操作這些方法會更方便,而且你不需要像以往使用 jQuery 的時候需要在元素移動時重新綁定事件。

關於這部分你可以參考官方的簡體中文手冊。順帶一提,Vue.js 的學習曲線非常低,這也是為什麼我選擇 Vue.js 而不是 React.js 的原因(當然還有別的原因)。

那我還需要 jQuery 嗎?

這個問題有兩種。

如果我會了 Vue.js,那我之後還需要用 jQuery 開發網站嗎?

Vue.js 並不是萬能仙丹,當你要開發大型結構、或者是和資料有關的小型網站,我通常會建議使用 Vue.js。但這並不代表你可以直接丟掉 jQuery。當你要開發小型網站(不需和資料溝通)的時候,用上 jQuery 則會比起 Vue.js 還要來得好、且開發快速。

主要的原因在於透過 Vue.js 開發,你需要規劃資料的來龍去脈,這讓你在維護的時候更加方便、清晰和明瞭,但卻稍微犧牲了開發速率。jQuery 優渥之處在於開發非常快速,可惜後續維護不易。

我用了 Vue.js 之後,我可以把他跟 jQuery 一起用嗎?

不建議。因為這會破壞 Vue.js 和網頁的互動,避免與 Vue.js 一同使用 jQuery 的原因列在下面。

  1. 直接對 DOM 操作:jQuery 會直接針對 DOM 進行操作,如果你不知道什麼是 DOM,你可以直接把它當作頁面元素看待。如過這個手續太過頻繁,那麼消耗的效能就會非常大,在手機上同時變動數十個元素更是個大問題。

  2. 破壞 Vue.js 的綁定:因為 Vue.js 有和 DOM 做綁定,這個時候如果你透過 jQuery 來進行頁面上元素的變動,例如:將文章元素移除、或是移動到某個地方,這個時候就會破壞 Vue.js 的綁定而產生更多問題。

  3. 觀念不同:jQuery 並沒有資料流的觀念,通常你要變動資料,就是直接去動「網頁上的元素」,而 Vue.js 並不一樣。在 Vue.js 內你會變動「資料」,進而推動網頁上不同的呈現,簡單說就是你通常只會和資料有所互動,而不是網頁元素,這讓觀念更加簡潔。


歡迎來到前端,一個比後端還要坑的地方。