如何構建你的第一個 Vue.js 組件

2021-12-18 OSC開源社區

原文:How to build your first Vue.js component

連結:https://medium.freecodecamp.org/build-your-first-vue-js-component-2dc204bca514

譯者:涼涼_

記得當那天使用 CakePHP 開發的時候,我很喜歡它簡易入門的特性。其文檔不僅結構嚴密,詳盡,而且對用戶友好。多年以後,我在 Vue.js 上找到了同樣的感覺。然而,與 Cake 相比,Vue 文檔還有一個缺點:(缺乏)真實的項目教程。

不管框架的文檔有多好,對與所有人來說都是不夠的。閱讀有關的概念並不是總能幫助你了解更多東西,也不能幫助你理解如何使用它們來實際做出某些事情。如果你和我一樣,你會在實踐過程中學到更多,在你編碼的時候參考文檔,因為你需要它們。

在本教程中,我們將構建一個星級評分系統組件。我們將在需要時介紹幾個 Vue.js 概念,並介紹為什麼要使用它們。

TL;DR: 這篇文章詳細的介紹了如何使用 vue.js 和為什麼使用 vue.js 。它旨在幫助掌握 Vue.js 的一些核心概念,並教你如何為未來的項目做出設計決策。如果你想了解整個思維過程,請繼續閱讀。否則,你可以直接查看 CodeSandbox 上的最終代碼。

入門指南


Vue.js(正確地)以一個簡單的腳本引入足以開始運行,但是當你想使用single-file components,情況會有所不同。 現在,你不必這樣構建組件。 你可以很容易地用 Vue.component 定義一個全局組件。

問題在於,這樣做需要權衡使用字符串模板,沒有 CSS 支持,也沒有構建步驟(所以沒有預處理器)。 然而,我們想要更深入地學習如何構建一個真正的在項目中使用的實際組件。出於這些原因,我們將使用由 Webpack 提供支持的實際設置。

為了保持簡單並減少配置時間,我們將使用 vue-cli 和簡單的 webpack-simple Vue.js模板。

首先,你需要全局安裝 vue-cli。啟動你的終端並鍵入以下內容:

你現在可以通過幾個按鍵生成隨時可用的 Vue.js 樣板。然後繼續輸入:

你會碰到幾個問題。 選擇除「使用sass」之外的所有默認值,你應該回答 yes(y)。然後,vue-cli 將初始化項目並創建 package.json 文件。完成後,可以導航到項目目錄,安裝依賴關係,然後運行項目:

就這麼簡單!Webpack 將開始在埠 8080(如果可用)上為你的項目提供服務並在瀏覽器中啟動它。如果一切順利,你應該看到這樣的歡迎頁面。

我們做到了嗎?

可以說我們做到了!為了正確調試你的Vue.js組件,你需要正確的工具。 繼續並安裝Vue.js devtools瀏覽器擴展(Firefox/Chrome/Safari)。

你的第一個組件

Vue.js最好的功能之一是single-file components(SFC)。 它們允許您在一個文件中定義組件的結構,樣式和行為,而不存在混合HTML,CSS和JavaScript的常見缺陷。

SFC以.vue擴展名結尾,並具有以下結構:

讓我們開始創建我們的第一個組件:在/src/components中創建一個Rating.vue文件,然後複製/粘貼上面的代碼片段。然後,打開/src/main.js並調整現有的代碼:

最後,添加一些HTML代碼到你的Rating.vue文件:

現在看看你的瀏覽器中的頁面,你應該看到列表。Vue.js會將您的<Rating>組件附加到index.html中的#app元素。如果檢查HTML,則應該看不到#app元素的符號:Vue.js將其替換為組件。

旁註:你有沒有注意到你甚至不需要重新加載頁面?這是因為Webpack的vue-loader帶有一個熱加載功能。與實時重新加載或瀏覽器同步相反,每次更改文件時,熱重新加載都不會刷新頁面。而是監視組件更改,只刷新它們,保持狀態不變。

現在,我們已經花了一些時間來設置,是時候真正寫出有意義的代碼了。

模板

我們將使用 vue-awesome,一個用 Font Awesome icons 構建的 Vue.js 的 SVG 圖標組件。我們可以只加載我們需要的圖標,使用 npm(或 Yarn)進行安裝:

然後編輯你的組件,如下所示:

好吧,讓我們慢一點,解釋一下。

Vue.js 使用原生 ES6 模塊來處理依賴和導出組件。<script>塊中的前兩行分別導入圖標,所以最終捆綁包中不需要圖標。第三個圖標是從 vue-awesome 導入的 Icon 組件,所以你可以在你的項目中使用它。

圖標是一個 Vue.js SFC,就像我們正在構建的這一個。如果你打開這個文件,你會發現它和我們的結構完全一樣。

export default 模塊將對象文字導出為我們組件的視圖模型。我們在組件屬性中註冊了 Icon 組件,所以我們可以在本地使用它。

最後,我們在 HTML <template> 中使用了 Icon,並傳遞了一個 name 屬性來定義我們想要的圖標。通過將組件轉換為 kebab-case(例如:MyComponent 變成 <my-component>),可以將組件用作自定義 HTML 標記。我們不需要在組件內嵌入任何東西,所以我們使用了一個自閉合標籤。

旁註:你有沒有注意到我們在 HTML 中添加了一個<div>標籤?這是因為我們還在根級別的<span>中添加了一個計數器,Vue.js 中的組件模板只接受一個根元素。如果你不遵守,會得到一個編譯錯誤。

樣式

如果你已經使用過 CSS,你應該知道一個主要的挑戰就是要處理它的全局性。嵌套一直被認為是解決這個問題的方法。但現在我們知道它很快就會導致特殊性問題,使得樣式難以覆蓋,不能被重用,並且這將是一個難以衡量的噩夢。

於是發明了像 BEM 這樣的方法來繞過這個問題,並且通過命名空間類來保持低的特異性。有一段時間,這是編寫乾淨和可擴展的 CSS 的理想方法。然後,像 Vue.js 或 React 這樣的框架和庫就出現了,並將 scoped styling 引入表中。

React 具有樣式化的組件,Vue.js 具有 scoped styling CSS。它可以讓你編寫特定組件的 CSS,而不必拿出一些技巧來保持它的包含結構。您使用「普通」類名編寫常規 CSS,Vue.js 通過將數據屬性分配給 HTML 元素並將其附加到編譯樣式來處理範圍限定。

讓我們在組件上添加一些簡單的類:

和 css 樣式:

看到那個scoped屬性了嗎? 這是告訴 Vue.js 去範圍化樣式,所以他們作用範圍不會涵蓋到其他地方。 如果您在 index.html 中正確地複製/粘貼 HTML 代碼,您將注意到您的樣式不適用:這是因為它們的作用域是組件。

那麼預處理器呢?

Vue.js 使得從簡單的 CSS 切換到您最喜歡的預處理器變得輕而易舉。你所需要的只是適當的 Webpack 加載器和<style>塊上的簡單屬性。我們在生成項目時對「使用sass」選擇「是」,所以 vue-cli 已經為我們安裝並配置了 sass-loader。現在,我們需要做的就是將 lang="scss" 添加到開始的<style>標籤中。

現在我們可以使用 Sass 編寫組件級樣式,導入變量,顏色定義或混合等部分。如果您更喜歡縮進語法(或「sass」符號),只需在 lang 屬性中將 scss 切換 sass 即可。

行為

現在我們的組件看起來不錯,現在是時候讓它開始工作了。目前,我們有一個硬編碼的模板。讓我們設置一些初始的模擬狀態,並調整模板,使其顯示出來:

我們在這裡所做的是使用 Vue 的數據來設置組件狀態。你在 data 中定義的每個屬性都是有響應性的:如果它發生變化,它將反映在視圖中。

我們正在創建一個可重用的組件,因此 data 需要成為工廠函數而不是對象文字。這樣我們就得到了一個新的對象,而不是一個可以跨幾個組件共享的現有對象。

我們的 data 工廠返回兩個屬性:stars,當前「活動」的 star 數和 maxStars,還有一個就是組件中 star 的總數。因為我們會適配我們的模板規則,所以它反映了組件的實際狀態。

Vue.js 帶有一堆指令,可以讓您將演示邏輯添加到模板中,而無需將其與純 JavaScript 代碼混合。v-fordirective 遍歷任何可迭代的對象(數組,對象文字,映射等)。它也可以把一個數字作為一個範圍重複 x 次、這就是我們用 v-for="star in maxStars" 所做的,所以我們對組件中的每個星星都有一個<li>。

您可能已經注意到一些屬性以冒號為前綴,這是 v-bind 指令的縮寫,它將屬性動態綁定到表達式。我們可以把它寫成長的形式,v-bind:class。

當 star 處於活動狀態時,我們需要在 <li> 元素上添加 active 類。在我們的項目下,這意味著每個 <li> 的索引小於 stars 應該有 active 類。我們在 :class 指令中使用了一個表達式,噹噹前 star 小於總 star 數時,才會追加 active。同樣條件下我們使用三元運算符來定義 Icon 組件使用的什麼樣的圖標:star 或 star-o。

那計數器呢?

現在我們的 star 列表是綁定到實際的數據,現在我們是時候對計數器也執行相同的操作。最簡單的方法是使用帶有 mustache 語法的文本插值:

很簡單,不是嗎? 現在在這種況下,這是訣竅。 但是,如果我們需要一個更複雜的 JavaScript 表達式,最好將其抽象到一個計算屬性中。

在這裡,這是矯枉過正。 我們可以避開模板內表達式,並保持可讀性。然而,當你不得不處理更複雜的邏輯時,記住計算的屬性。

另一件我們需要做的是提供一種方法來隱藏計數器,如果我們不需要它的時候。 最簡單的方法是使用帶有布爾值的 v-if 指令。

交互

我們差不多完成了,但是我們仍然需要實現組件中最有趣的部分:響應性。我們將使用 v-on,這是處理事件和方法的 Vue.js 指令,可以附加所有方法的 Vue.js 屬性。

我們在 <li> 上添加了 @click 屬性,這是 v-on:click 的簡寫。該指令包含對我們在組件的 methods 屬性中定義的 rate 方法的調用。

「等一下...這看起來非常像熟悉的 HTML 的 onclick 屬性。在 HTML 中使用內聯 JavaScript 不是一個過時和不好的做法嗎?」

確實如此,但是即使語法看起來很像 onclick,但比較兩者是一個錯誤。當你構建一個 Vue.js 組件時,你不應該把它看作是分離的 HTML/CSS/JS,而應該是一個使用多種語言的組件。當項目在瀏覽器中開啟服務或編譯生產時,所有的 HTML 和指令都被編譯成普通的 JavaScript。如果您檢查已渲染的 HTML,您將看不到您的指令的任何標誌,也沒有任何 onclick 屬性。Vue.js 會編譯好你的組件並創建合適的綁定。

這也是為什麼您可以從模板訪問組件的上下文的原因:因為指令綁定到視圖模型。與具有單獨 HTML 的傳統項目相反,模板是組件的組成部分。

回到我們的 rate 方法。我們需要將 stars 變為 clicked 元素的索引,所以我們通過 @click 指令的索引,可以做到以下幾點:

去查看您的瀏覽器頁面,並嘗試點擊 star:它運行成功了!

如果你打開瀏覽器開發者工具欄中的 Vue 面板並選擇 <Rating> 組件,當你點擊 star 時,你會看到數據的變化。這表明你的 star 屬性是響應性的:當你改變它的時候,它會把它的改變指派給視圖。

 這個概念被稱為數據綁定,如果您使用過 Backbone.js 或 Knockout 之類的框架,您應該熟悉這個概念。 不同之處在於,Vue.js 和 React 一樣,只能在一個方向上進行:這就是所謂的單向數據綁定。不過這個話題值得寫一篇單獨的文章。

在這一點上,我們可以認為已完成 —— 但我們可以做更多的工作來改善用戶體驗。

現在,我們實際上不能給出 0 的等級,因為點擊一個 star 會將它的比率設置為它的索引。更好的方案是重新點擊同一顆 star,並切換至其當前狀態,而不是保持 active 狀態。

現在,如果點擊的 star 的索引等於 star 當前值,我們就減少它的值。 否則,我們給它分配 star 值。

如果我們想要徹底解決,我們還應該添加一個控制層,以確保 star 從來沒有被賦予一個沒有意義的值。我們需要確保 star 永遠不會小於 0,也絕不會比 maxStars 更大,而且它是一個合適的數字。

傳遞 props 屬性

現在,組件的數據在數據屬性中被硬編碼。如果我們希望我們的組件實際上是可用的,我們需要能夠從其實例傳遞自定義數據。在 Vue.js 中,我們用 props 做到這一點。

和在 main.js 文件裡:

這裡有三件事要注意:

首先,我們使用 v-bind 簡寫從組件實例傳遞 props 屬性:這就是 Vue.js 所謂的動態語法。當你想要傳遞一個字符串值時,你不需要知道它的具體值,為此,字面值語法(沒有 v-bind 的普通屬性)將起作用。但對我們而言,由於我們正在傳遞數字和布爾值,所以這很重要。

props 和數據屬性在編譯時被合併,所以我們不需要改變在視圖模型或模板中調用屬性的方式。出於同樣的原因,我們不能在 props 數據屬性中使用相同的名稱。

最後,我們定義了一個級別屬性,並將其作為 star 數值屬性中的值傳遞給它。我們之所以這樣做,不是直接使用級別屬性,而是因為級別改變,值會發生變化。在 Vue.js 中,props 從父級傳遞給子級,而不是反過來傳遞,所以你不會改變父級的狀態。這將違背 單向數據流 的原則,使事情難以調試。這就是為什麼你不應該試圖改變子組件內的 prop。相反,定義一個使用 props 的初始值作為自聲的本地數據屬性。

最後的潤色

在這一天馬上過去之前,我們應該了解 Vue.js 最後一個驚奇的地方:prop 的驗證。

Vue.js 允許你在傳遞給組件之前控制 prop。您可以執行四個主要的事情:檢查類型,要求定義一個 prop 屬性,設置默認值,並執行自定義驗證。

我們使用類型檢查來確保將正確類型的數據傳遞給組件。這將對我們忘記使用動態語法來傳遞非字符串值的錯誤特別有用。我們也確保通過要求它填寫 grade 屬性。對於其他 props 屬性,我們定義了默認值,所以即使沒有傳遞自定義數據,組件也能正常工作。

現在我們可以簡單地通過執行以下操作來實例化組件:

就是這樣!您剛剛創建了第一個 Vue.js 組件,並探索了許多概念,包括使用 vue-cli、single-file components 生成樣板程序,導入組件, scoped styling, directives, event handlers, computed properties, custom methods, one-way data flow, props 和 prop validation。這都是 Vue.js 所提供的表層特性!

這是一個非常詳細的教程,所以碰到不明白的地方,建議再次閱讀,在部分章節之間暫停和探索和,並嘗試擺弄下 CodeSandbox 上的源碼。

相關焦點

  • Vue.js說說組件
    在較高層面上,組件是自定義的元素,Vue.js的編譯器為它添加特殊功能。在有些情況下,組件也可以是原生HTML元素的形式,以is特性擴展。    如何註冊組件?    需要使用Vue.extend方法創建一個組件,然後使用Vue.component方法註冊組件。
  • 2018 年你需要知道的 Vue.js 組件庫,完善你的應用開發
    (點擊上方公眾號,可快速關注)英文:bitsrc  譯文:開源中國https://my.oschina.net/editorial-story
  • 使用Vue.js、Node和Okta構建安全的用戶管理
    輸入Vue.js. 它按預期工作。它很快。文件是令人難以置信的。模板是雄辯的。關於如何處理狀態管理,有條件呈現,雙向綁定,路由等問題有一致的一致意見。我見過很多開發人員走這條路,所以今天我想帶你了解如何使用Vue.js和Node構建一個基本的應用程式。
  • Vue.js——60分鐘組件快速入門(上篇)
    組件系統是Vue.js其中一個重要的概念,它提供了一種抽象,讓我們可以使用獨立可復用的小組件來構建大型應用,任意類型的應用界面都可以抽象為一個組件樹:那麼什麼是組件呢?#app是Vue實例掛載的元素,應該在掛載元素範圍內使用組件-->            <my-component></my-component>        </div>    </body>    <script src="js/vue.js"></script>
  • 推薦8 個漂亮實用的 vue.js 進度條組件
    為大家精心挑選了 8 個漂亮的 Progress Bars 組件,並附上 GitHub 連結和 vue.js 代碼示例,以及Vue3 快速深入全攻略。1.easy-circular-progress一個簡單的循環進度組件,帶有計數效果。
  • 編寫Vue.js組件前需要知道的10件事
    本文介紹了編寫 Vue.js 組件前需要知道的 10 件事,其中包括:組件可以全局或局部加載;延遲加載 / 異步組件;必需的 Props;使用 $emit 觸發自定義事件;多 Props 綁定和覆蓋等等。 Vue.js 提供了兩種加載組件的方法:一種是 Vue 實例中的全局加載,另一種是組件級的加載。兩種方法都有各自的優點。
  • Vue.js布局
    動態Vue.js布局組件前言vue.js是漸進增強的視圖庫,可以作為.html頁面部分使用,也可以結合vue-router、vuex、axios用來構建單頁面或多頁面應用。
  • 使用 Web3 和 Vue.js 來創建你的第一個以太坊 dAPP(二)
    -2-52248a74d58a譯者:琪花億草, Tocy, rever4433, 無若歡迎回到這個很牛的教程系列的第2部分,在教程中我們親手構建我們的第一個分布式應用程式。如果你錯過了第一部分,你可以在下面找到它:VueJS是一個用於構建UI的javascript框架。乍一看,它看起來與經典的moustache模板類似,但在底層為了使Vue變得響應式發生了很多事情。
  • Vue.js:60分鐘組件快速入門(上篇)
    ,它提供了一種抽象,讓我們可以使用獨立可復用的小組件來構建大型應用,任意類型的應用界面都可以抽象為一個組件樹:#app是Vue實例掛載的元素,應該在掛載元素範圍內使用組件-->            <my-component></my-component>        </div>    </body>    <script src="js/vue.js"></script>
  • Vue.js 教程:構建一個特斯拉汽車餘電計算器
    作為本教程的起點,請克隆這個 Github 存儲庫:https://github.com/petereijgermans11/workshop-reactjs-vuejs然後轉至 vuejs-app 目錄。
  • Vue2.0父子組件間通信
    vue2.0Vue.js是一套構建用戶界面的漸進式框架。與其他重量級框架不同的是,Vue 從根本上採用最小成本、漸進增量的設計。Vue 的核心庫只專注於視圖層,並且很容易與其他第三方庫或現有項目集成。另一方面,當與單文件組件和 Vue 生態系統支持的庫結合使用時,Vue 也完全能夠為複雜的單頁應用程式提供有力驅動。
  • 基於Vue.js的表格分頁組件
    不了解Vue.js的童鞋可以移步我的上一篇文章《【vue.js學習系列2】淺談Vue.js的幾個特點https://zhuanlan.zhihu.com/p/24041292》了解一下。如需高大上的組件,可以移步Vue官方組件庫:https://github.com/vuejs/awesome-vue#libraries--pluginsBootPage是一款支持靜態數據和伺服器數據的表格分頁組件,支持調整每頁顯示行數和頁碼顯示個數,樣式基於bootstrap,就像這樣:
  • 全面了解 Vue.js 函數式組件
    它糟糕得要命~ 但你會愛上它!vue 單文件組件中並未提供 include 等拆分 template 的方案 -- 畢竟語法糖可夠多了,沒有最好。有潔癖的開發者會嘗試將複雜的列模版部分封裝成獨立的組件,來解決這個痛點;這樣已經很好了,但相比於本來的寫法又產生了性能隱患。
  • 【Vue.js入門到實戰教程】11-Vue Loader(下)| 編寫一個單文件 Vue 組件
    然後在 src/main.js 中引入 Bootstrap 的腳本和樣式文件:import Vue from 'vue'import App from './App.vue'import 'bootstrap'import 'bootstrap/dist/css/bootstrap.min.css'...接下來,就可以正式編寫單文件組件了。
  • vue-cli3.x的構建第三方庫按需引用,自定義組件的探索
    的問題參考:https://github.com/webpack-contrib/sass-loader(node-sass遷移為Dart-sass)https://blog.csdn.net/mlonly/article/details/88635809(構建組件庫)目的:構建一個能第三方組件庫(element-ui)進行二次封裝,同時能封裝自定義組件,的純js,css,image
  • 初步認識vue.js框架的使用
    vue.js框架是幹什麼的Vue.js 是一個JavaScriptMVVM庫,是一套構建用戶界面的漸進式框架。它是以數據驅動和組件化的思想構建的,採用自底向上增量開發的設計。相比於Angular.js,Vue.js提供了更加簡潔、更易於理解的API,使得我們能夠快速地上手並使用Vue.js。如何使用vue.js1.下載 vue.min.js 並用 <script> 標籤引入。
  • 【Vue.js 入門到實戰教程】09-Vue 組件插槽 | 父子組件間的內容分發和插槽作用域
    說到這裡,我們可以引用一張 Vue 官網提供的組件架構圖,實際上,一個 Vue.js 應用就是基於下面這樣的一個組件樹來組織和管理頁面元素的:我們可以把全局 Vue 實例看作一個最頂層的隱式組件,其他組件都是通過 Vue.component 在此基礎上註冊,並且這些組件之間可以相互嵌套、內容分發、數據傳遞以及事件通知來建立聯繫,從而通過一個個小組件自下而上層層疊加,最終構建出複雜的頁面布局和功能模塊
  • 「Vue.js開發連載一」Vue.js簡介
    一、簡介Vue.js(讀音 /vju/,類似於view)是一個構建數據驅動的web界面的漸進式框架。Vue。js的目標是通過儘可能簡單的API實現響應的數據綁定和組合的視圖組件。它不僅易於上手,還便於與第三方庫或既有項目整合。
  • Vue.js 父子組件通信的十種方式
    ></div>let MyButton = Vue.extend({  template: '<button @click="triggerClick">click</button>',  data () {    return {      greeting: 'vue.js
  • 如何在 Vue.js 中使用第三方庫
    除非你找到了一個簡單而又健壯的方式來引入這些庫供不同的組件和模塊使用, 不然, 這些第三方庫的管理會給你帶來一些麻煩.本文將介紹一些在 Vue.js 中使用第三方庫的方式.;  }}這種方式是允許的, 但是比較繁瑣, 並且帶來的問題是: 你必須記住在哪些文件引用了該庫, 如果項目不再依賴這個庫時, 得去找到每一個引用該庫的文件並刪除該庫的引用. 如果構建工具沒設置正確, 可能導致該庫的多份拷貝被引用.