用 Vue.js 替換 jQuery:無需構建步驟
已發表: 2022-03-10最近圍繞 JavaScript 框架的所有炒作是不可能忽略的,但它們可能不適合您的項目。 也許你不想為一些你可以不用的小抽象建立一個完整的構建系統。 也許將項目轉移到構建系統,因此,不同的部署方法將意味著您可能無法向客戶收費的大量額外時間和精力。 也許您不想用 JavaScript 編寫所有 HTML。 名單還在繼續。
有些人可能不知道的是,您可以像合併 jQuery 一樣將 Vue 合併到您的項目中,而無需構建步驟。 Vue 是靈活的,因為我們可以直接在 HTML 中使用它。
因此,如果您當前的頁面結構如下所示:
<main> <div class="thing"> <p>Some content here</p> </div> </main> <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script> <script> //some jquery code here </script>
您可以在這裡更改腳本標記,並且仍然像以前一樣串聯使用 HTML 和 JS,只重構少量代碼。 不必用 JavaScript 重寫 HTML,不必使用 webpack,也不必搭建龐大的系統:
<main> <div class="thing"> <p>Some content here</p> </div> </main> <script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.3/vue.min.js"></script> <script> //some vue code here </script>
您可以替換標籤並保持原樣。 最好的部分是,您可能會認為代碼會變得更加複雜,但在閱讀本文並查看示例時,您可能會發現 Vue 非常簡單、易讀且易於維護和適應。 就大小而言,它們也相當可比——使用它們就像來自 CDN、縮小、Vue 版本 2.5.3 是86KB 。 jQuery 3.2.1 是87KB 。
讓我們介紹一下 jQuery 中的一些常見用例,以及我們如何將它們切換到 Vue,以及我們甚至想要這樣做的原因。
捕獲用戶輸入
在網站上需要 JavaScript 的一個非常常見的用例是從表單中捕獲用戶輸入,所以讓我們從那裡開始。 為了簡單和清晰起見,我們實際上不會合併完整的表格,但我們會在最後完成它。
為了在用戶類型中捕獲信息,下面是我們在 jQuery 和 Vue 中如何做到這一點——並排:
<div> <label for="thing">Name:</label> <input type="text" /> <p class="formname"></p> </div>
// this is an alias to $(document).ready(function() { $(function() { //keypress wouldn't include delete key, keyup does. We also query the div id app and find the other elements so that we can reduce lookups $('#app').keyup(function(e) { var formname = $(this).find('.formname'); //store in a variable to reduce repetition var n_input = $(this).find('#thing').val(); formname.empty(); formname.append(n_input); }); });
<div> <label for="name">Name:</label> <input type="text" v-model="name" /> <!--v-model is doing the magic here--> <p>{{ name }}</p> </div>
//this is a vue instance new Vue({ //this targets the div id app el: '#app', data: { name: '' //this stores data values for 'name' } })
我使用這個例子是因為它揭示了 Vue 的一些優勢。 Vue 是響應式的,這使得它特別能夠響應變化。 你可以看到,當我們更新我們輸入的內容時,它會立即改變——沒有延遲。
您還可以看到,在 jQuery 版本中,DOM 處於控制之中——我們從 DOM 中獲取內容、監聽它並響應它。 這將我們與當前設置 DOM 的方式聯繫在一起,並迫使我們考慮如何遍歷它。 如果要更改 HTML 元素的結構,我們必須調整代碼以適應這些更改。
在 Vue 版本中,我們存儲狀態——我們跟踪一個我們想要更新和更改的屬性,並通過一個稱為指令的東西跟踪我們想要更改的元素。 這意味著它直接附加到我們需要定位的 HTML 元素上。 DOM 的結構可以改變,HTML 可以移動,這些都不會影響我們的性能或捕獲這些事件。 在我們的例子中,我們使用輸入上的 v-model 屬性來連接到我們存儲在 JavaScript 中的數據。
但! 這不像按回車鍵存儲東西那樣常見的用例,所以讓我們接下來看看。
在單個事件上存儲用戶輸入
Vue 工作方式的有趣之處在於,它無需在存儲和檢索數據時考慮特定的 DOM 事件。 本質上,我們已經知道我們想要捕捉什麼; 我們通過選擇一個用來改變它的事件來賦予它形狀。 相比之下,jQuery 與 DOM 所做的事情緊密耦合,並依賴於那些 DOM 事件來構建它存儲的變量,這些變量可以放置在任何地方,而不是一個一致的組(在數據中)進行檢索。 我們可以在上一個示例的更新版本中看到這一點,其中信息是通過 Enter 鍵收集的:
<div> <label for="thing">Name:</label> <input type="text" /> <p class="formname"></p> </div>
// this is an alias to $(document).ready(function() { $(function() { //We query the div id app and find the other elements so that we can reduce lookups $('#app').change(function(e) { var n_input = $(this).find('#thing').val(); $(this).find('.formname').append(n_input); }); });
<div> <label for="name">Name:</label> <input type="text" v-model.lazy="name" /> <p>{{ name }}</p> </div>
new Vue({ el: '#app', data: { name: '' } });
在這個版本中,jQuery 得到了一些簡化,因為我們不必在每次擊鍵時都捕獲內容,但我們仍在從 DOM 中提取內容並逐步響應這些變化。 我們在 jQuery 中的代碼總是有點像這樣:
“去獲取這個元素,看看它在做什麼,堅持這些變化,對這些變化做點什麼。”
相比之下:在 Vue 中,我們可以控制正在發生的變化,並且 DOM 根據我們的命令響應這些變化。 我們將它直接附加到我們想要更新的東西上。 在我們的例子中,我們有一個稱為修飾符的小抽象: v-model.lazy
。 Vue 現在知道在更改事件發生之前不要開始存儲它。 很簡約!
切換類
我們將介紹的下一件事是切換 CSS 類,因為正如萬能的、經常觀看的 Googly 告訴我的那樣,它是最常見的 jQuery 功能。
<div> <button aria-pressed="false">Toggle me</button> <p class="toggle">Sometimes I need to be styled differently</p> </div>
.red { color: red; } JS $(function() { $('button').click(function(e) { $('.toggle').toggleClass('red'); $(this).attr('aria-pressed', ($(this).attr('aria-pressed') == "false" ? true : false)); }); });
<div> <button @click="active = !active" :aria-pressed="active ? 'true' : 'false'">Toggle me</button> <p :class="{ red: active }">Sometimes I need to be styled differently</p> </div>
.red { color: red; } JS new Vue({ el: '#app', data: { active: false } })
同樣,我們在這裡看到的是,在 jQuery 版本中,我們將狀態存儲在 DOM 中。 該元素具有類,jQuery 根據類的存在做出決定,它通過 ping DOM 來檢查。 在 Vue 版本中,我們存儲一個條件,並根據該狀態對其進行樣式設置。 我們不是向 DOM 詢問這些信息,我們自己持有它。
我們將active
存儲在數據中,按鈕切換條件, .red
根據該條件進行更改。 甚至可訪問性的狀態aria-pressed
的表述也更快,因為我們不必在 Vue 的腳本中設置任何內容,我們可以根據 ' active
的狀態直接在模板中內聯的狀態之間切換。
您還會注意到,在最後幾個示例中,您可能認為開始使用 Vue.js 比使用 jQuery 需要更多的代碼,但它們實際上相當可比。
隱藏和顯示
另一個常見的 jQuery 用例是隱藏和顯示某些東西。 jQuery 在使這項任務變得非常簡單方面一直做得非常好,所以讓我們來看看它與 Vue 並排的樣子。
<div> <button type="button" aria-expanded="false"> Toggle Panel </button> <p class="hello">hello</p> </div>
$(function() { $('#toggle').on('click', function() { $('.hello').toggle(); $(this).attr('aria-expanded', ($(this).attr('aria-expanded') == "false" ? true : false)); }); });
<div> <button @click="show = !show" :aria-expanded="show ? 'true' : 'false'"> Toggle Panel </button> <p v-if="show">hello</p> </div>
new Vue({ el: '#app', data: { show: true } })
jQuery 和 Vue 都很好地保持了這個任務的簡單性,但有幾個原因讓我真正使用 Vue 來完成類似切換之類的事情。 Vue 有一個名為 Vue devtools 的工具。 這與 Chrome 開發工具沒有什麼不同,但是當我們使用它時,我們會得到一些關於 Vue 發生了什麼的特殊信息。
在 jQuery 和 Vue 版本中,我們可以看到元素隱藏和出現。 但是,如果出現問題怎麼辦? 如果我們的代碼沒有按照我們預期的方式工作怎麼辦? 為了開始使用 jQuery 進行調試,我們可能會添加一些console.log
或設置一些斷點來嘗試追踪出錯的地方。
現在, console.log
沒有什麼問題,但是在 Vue 開發工具的幫助下,我們實際上可以親身體驗 Vue(無法抗拒)Vue 認為正在發生的事情。 在下面的這個 gif 中,你可以看到當我們切換按鈕時,Vue 開發工具會相應地更新 true/false 的狀態。 如果 DOM 沒有按照我們預期的方式工作,我們可以在 Vue 中實時查看數據。 這使得調試變得容易得多; 它實際上非常棒。
我喜歡的另一件事是v-if
很容易擴展到其他條件。 如果我切換的東西會頻繁顯示和隱藏,我可以決定使用一個叫做v-show
的東西而不是v-if
: v-if
將完全卸載元素,而v-show
只會切換它的可見性。 這種區別非常重要,因為在樣式中切換可見性而不是完全卸載/安裝 DOM 節點的性能要高得多。 我可以根據很多條件顯示或隱藏某些內容,甚至是用戶輸入或其他條件的存在。 這通常是 jQuery 可能會有點混亂的地方,它在多個位置 ping DOM 並協調它們。 以下是基於用戶輸入的存在協調顯示某些內容的示例:
<div> <label for="textarea">What is your favorite kind of taco?</label> <textarea v-model="tacos"></textarea> <br> <button v-show="tacos">Let us know!</button> </div>
new Vue({ el: '#app', data() { return { tacos: '' } } })
<div> <label for="textarea">What is your favorite kind of taco?</label> <textarea></textarea> <br> <button v-show="tacos">Let us know!</button> </div>
$(function() { var button = $('.button'); var textarea = $('#textarea'); button.hide(); textarea.keyup(function() { if (textarea.val().length > 0) { button.show(); } else { button.hide(); } }) });
在這個例子中,你可以看到讓 Vue 保持狀態的價值——我們對變化的反應非常自然,而且代碼更少。 一旦習慣了這種風格,理解起來會更快,因為您不必逐行跟踪邏輯。 很多人稱這種差異為“命令式與聲明式”。
提交表格
jQuery 的規範用例歷來是通過 AJAX 調用提交表單,所以我們也應該看看它。 Vue 實際上並沒有像 AJAX 這樣的內置東西; 在 Vue 應用程序中,通常使用 Axios(用於發出 HTTP 請求的 JavaScript 庫)之類的東西來幫助完成此任務。
這個例子比其他例子稍微複雜一些。 我們將在這裡做一些事情:
- 在我們開始輸入表單之前,該按鈕將顯示為灰色,然後它將接收一個“活動”類並變為藍色;
- 當我們提交表單時,我們會阻止頁面加載;
- 提交表單後,我們將在頁面上顯示響應數據。
<div> <form action="/"> <div> <label for="name">Name:</label><br> <input type="text" name="name" required/> </div> <div> <label for="email">Email:</label><br> <input type="email" name="email" required/> </div> <div> <label for="caps">HOW DO I TURN OFF CAPS LOCK:</label><br> <textarea name="caps" required></textarea> </div> <button class="submit" type="submit">Submit</button> <div> <h3>Response from server:</h3> <pre class="response"></pre> </div> </form> </div>
$(function() { var button = $("button"); var name = $("input[name=name]"); name.keyup(function() { if (name.val().length > 0) { button.addClass('active'); } else { button.removeClass('active'); } }); $("form").submit(function(event) { event.preventDefault(); //get the form data var formData = { name: $("input[name=name]").val(), email: $("input[name=email]").val(), caps: $("input[name=caps]").val() }; // process the form $.ajax({ type: "POST", url: "//jsonplaceholder.typicode.com/posts", data: formData, dataType: "json", encode: true }).done(function(data) { $(".response") .empty() .append(JSON.stringify(data, null, 2)); }); }); });
在這裡,我們將看到第 2-10 行處理按鈕類的處理,類似於我們之前的處理方式。 我們將一個名為 event 的參數傳遞給表單,然後說event.preventDefault()
以防止重新加載頁面。 然後我們從表單輸入中收集所有表單數據,處理表單,然後將響應放入來自 AJAX 請求的.done()
調用中。
<div> <form @submit.prevent="submitForm"> <div> <label for="name">Name:</label><br> <input type="text" v-model="name" required/> </div> <div> <label for="email">Email:</label><br> <input type="email" v-model="email" required/> </div> <div> <label for="caps">HOW DO I TURN OFF CAPS LOCK:</label><br> <textarea v-model="caps" required></textarea> </div> <button :class="[name ? activeClass : '']" type="submit">Submit</button> <div> <h3>Response from server:</h3> <pre>{{ response }}</pre> </div> </form> </div>
new Vue({ el: '#app', data() { return { name: '', email: '', caps: '', response: '', activeClass: 'active' } }, methods: { submitForm() { axios.post('//jsonplaceholder.typicode.com/posts', { name: this.name, email: this.email, caps: this.caps }).then(response => { this.response = JSON.stringify(response, null, 2) }) } } })
在 Vue 版本中,我們決定需要在表單中填充哪些字段,然後將它們與我們之前使用的 v-model 附加在一起。 我們檢查名稱是否存在以切換類。 無需傳入事件並編寫event.preventDefault()
,我們所要做的就是在我們的表單元素上編寫@submit.prevent
,這已經為我們處理好了。 要提交帖子本身,我們使用 Axios,我們會將響應存儲在 Vue 實例中作為響應。
我們仍然需要做很多事情來獲得生產就緒的表單,包括驗證、錯誤處理和編寫測試,但是在這個小例子中,您可以看到 Vue 在處理大量事物更新和變化,包括用戶輸入。
結論
如果適合你,使用 jQuery 絕對沒問題! 本文旨在展示 Vue 對於不需要大量開銷的小型站點也是一個非常好的抽象。 Vue 在大小上相當,易於推理,並且如果您沒有帶寬,無需用 JavaScript 重寫您的 HTML 並採用構建系統,將小部分功能切換到 Vue 是相當簡單的。 這一切都讓人不得不考慮。
由於 Vue 的靈活性,如果您想隨著時間的推移採用更複雜的結構,也很容易將此代碼轉換為構建步驟和組件結構。 嘗試它實際上很有趣,所以當你準備好這樣做時,請查看 vue-cli。 這個工具的作用是讓你能夠用幾個終端命令搭建整個生產級的 Vue 和 webpack 構建。 這使您可以使用單文件組件,您可以在一個文件中串聯使用 HTML、CSS 和腳本,從而構成單個可重用組件。 除非您想做一些特別的事情,否則您不必配置 webpack 構建,因此您可以節省大量設置時間。 他們甚至有一個內置命令來為生產部署做好一切準備。
靈活地選擇將 Vue 合併到項目中的任何一種方式的好處是,您不必立即改變工作風格,甚至可以隨著時間的推移慢慢做出改變。 這就是為什麼人們稱 Vue 為漸進式框架的原因。