![](https://img.laitimes.com/img/__Qf2AjLwojIjJCLyojI0JCLicmbw5iN2UmZ4YjM5YzMkRGO1kTZ4QTN1IjY2YGN1E2NhJjZz8CX0JXZ252bj91Ztl2Lc52YucWbp5GZzNmLn9Gbi1yZtl2Lc9CX6MHc0RHaiojIsJye.png)
開篇
自從Facebook2013年推出React架構以來,基于UI元件的前端架構越來越流行,主要得益于元件的重用性,資料狀态的管理等特性。
谷歌也推出了基于元件的第二代Angular架構,緻力于開發全平台應用——Web、移動 Web、移動應用、原生應用和桌面原生應用,其最為核心的特點是:MVC、子產品化、自動化雙向資料綁定、語義化标簽、依賴注入等等。
後期之秀Vue.js,其作者尤雨溪在谷歌就職時建立并于2014年釋出,自釋出以來,由于其設計靈活,友善內建到現有項目中,并能輕松建構複雜的應用程式,是以Vuejs大受歡迎,現在成為三大前端主流架構之一。
本篇文章閱讀時間預計10分鐘。
01
為什麼選擇Vue?
在你閱讀本文時,你一定疑惑為什麼選擇Vue,以下的幾個理由是不是能打動你選擇Vue?
1、很容易內建上手 到現有項目。你可以在現有的網站中輕松內建Vue,無需引入新的工具設定複雜的流程,如果你習慣使用jQuery,那你也很容易上手Vue的。
2、基于元件的架構。允許應用程式子產品化,元件化,友善快速建構現代化的單頁面應用程式(SPA)。
3、生态的完整性。幾乎你能想到的插件,你都能在社群裡找到。更重要的是,其重要的的庫比如路由,狀态管理等都是有Vue官方團隊進行維護,不像React生态,官方并不是很積極的提供解決方案。
4、 廣泛的使用。從國外的GitLab到國内的阿裡巴巴,尤其國内越來越多公司的使用,讓其成為國内前端必備技能。同時Vue.js成為PHP流行架構Laravel的預設前端庫。由于其使用的廣泛性,未來會有更多的人去投入到這個架構中,讓其生态更加強大,受益最大的就是我們每位開發者。
02
讓我們開始行動吧!
首先說明下,通過本篇Vue.js基礎知識的學習,筆者将帶着大家完成如下圖所示的練習:
主要實作以下功能:
- 完成頁面效果的布局
- 引入Vue架構,實作資料的渲染
- 點選表頭,實作資訊按照表頭的屬性進行排序
引入Vue
為了友善大家快速入門Vue, 本篇文章用最簡單的JS檔案引入方式來引入Vue架構,下篇文章筆者将詳細介紹用建構的方式建立vue項目,如下所示建立一個index.html檔案引入Vue檔案:
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js">script>
注:引入開發版是為了友善我們進行開發和調試,生産環境應該引入vue.min.js版本
接下來我們建立Vue執行個體,代碼如下:
new Vue({ el: "#main"});
此段代碼的意思就是聲明Vue執行個體,并查找DOM的id等于main的元素,用于接下來的資料内容呈現。
加載資料
為了讓上述Vue的執行個體,加載資料,我們需要提供資料。Vue内提供data屬性,用于加載資料源。data屬性是響應式的,當這些屬性的值發生改變時,視圖将會産生“響應”,即比對更新為新的值,并影響UI的顯示。
接下來我們在data屬性裡添加一些資料,在實際的應用場景,你會通過接口請求資料,為了友善示範,我們寫死一些資料,示例如下:
new Vue({ el: "#main", data: { heading: "前端達人開發部", employees: [ { "firstName": "amelia", "lastName": "austin", "photoUrl": "https://www.qianduandaren.com/demo/vue/img/women/1.jpg", "email": "[email protected]", "phone": "(651)-507-3705", "department": "Engineering" }, { "firstName": "bobbie", "lastName": "murphy", "photoUrl": "https://www.qianduandaren.com/demo/vue/img/women/2.jpg", "email": "[email protected]", "phone": "(925)-667-7604", "department": "Management" } ] }});
模闆文法{{}}
現在我們有了資料,就需要進行界面資料的渲染和呈現,我們需要使用模闆文法——一雙大括号 ( {{}} ),進行資料綁定。如下段代碼所示:
<h1 className="ui center aligned header">{{heading}}h1>
你可以在這雙大括号裡包含任何有效的JavaScrip代碼,如下所示,我們在其包含了一個運算語句:
<div id="app"> <p>The price is: ¥{{ price * 1.20 }} (inc. VAT)p>div><script>new Vue({ el: '#app', data: { price: 25 }});script>
雙括号區域将會顯示:
The price is: ¥30 (inc. VAT)
在執行個體中,界面呈現前執行了JS語句的運算并将值進行顯示。
指令
實作更複雜的頁面程式,不能隻是簡簡單單的資料呈現,是以Vue的模闆文法還包含循環和條件顯示的邏輯指令,讓我們更好的處理頁面展現邏輯。指令的職責是,當表達式的值改變時,将其産生的連帶影響,響應式地作用于DOM。(類似AngularJS的ng-*指令)
1、v-for
前面我們介紹了加載資料的示例,你可能猜到了我們需要使用循環周遊的方式周遊集合用于資料的展現,v-for指令的作用就是周遊資料集合中的每項内容,如下段代碼所示:
<tbody><tr v-for="employee in employees"> <td> <img src="https://www.qianduandaren.com/demo/vue/img/women/1.jpg" className="ui mini rounded image"/> td> <td>{{employee.firstName}}td> <td>{{employee.lastName}}td> <td>{{employee.email}}td> <td>{{employee.phone}}td> <td>{{employee.department}}td>tr>tbody>
從上述代碼我們可以看出,我們在tr的屬性裡,添加了v-for指令,其代表在此DOM區域内進行循環,我們在此循環顯示了雇員的資訊。在這裡我們将圖檔的src屬性寫死了,下面我們很快會介紹到用新的指令進行替代。
與react一樣,在Vue中渲染清單時,強烈建議您為每個元素提供一個唯一的鍵。這有助于Vue架構在添加和删除元素時進行優化。你可以使用 :key 指令定義唯一的鍵值:
<tr v-for="user in users" :key="user.id>
如果實在沒有唯一的鍵值,你可以使用數組索引,示例代碼如下:
<tr v-for="(employee, index) in employees" :key="index">..tr>
2、v-if
另一個常見的指令就是條件渲染,v-if 隻有當data屬性或表達式的計算結果為true時,使用該指令才會導緻Vue呈現元素,如下段代碼所示:
<tbody><tr v-for="employee in employees"> ...tr><tr v-if="employees.length === 0"> <td colSpan="6">No employees foundtd>tr>tbody>
上述代碼如果employee為空,則會顯示 No employees found 的資訊,這對于我們日後調用API加載資料的邏輯處理十分有用。
有v-if指令,自然會有v-else-if指令處理更複雜的條件處理,如下段代碼所示:
<tbody><tr v-for="employee in employees"> ...tr><tr v-if="isLoadingData"> <td colSpan="6"><img src="spinner.gif"/>td>tr><tr v-else-if="employees.length === 0"> <td colSpan="6">No employees foundtd>tr>tbody>
從上述代碼中,我們加入了一個 isLoadingData 屬性,這在我們動态加載資料的邏輯處理十分有用,因為是異步加載資料涉及網絡延遲等問題,資料加載前需要有個資訊提示使用者資料正在加載中。
3、v-bind
有時候,你需要将資料綁定到html元素的屬性上,例如url上的href屬性,img的src屬性。
還記得我們上面的例子,我們渲染資料時把img屬性寫死了,現在我們可以使用v-bind指令進行資料綁定,代碼如下:
<img v-bind:src="employee.photoUrl" className="ui mini rounded image"/>
除了上述寫法外,我們可以用更簡短的文法,隻需要在屬性前使用:字首即可,代碼如下:
<img :src="employee.photoUrl" class="ui mini rounded image" />
4、v-model
Vue還支援表單雙向綁定的概念,允許我們通過表單輸入動态更改資料的内容,如下段代碼所示:
<div id="app"> <input v-model="text" placeholder="edit me"> <p>Text is: {{ text }}p>div><script> new Vue({ el: '#app', data: { text: 'Good golly, Miss Molly'}});script>
從上面的示例中,v-model指令将資料綁定到表單輸入框内,我們更改輸入框的值,p标簽區域的内容也随之改變。
5、v-on
我們可以使用v-on:綁定事件監聽器,事件類型由參數指定。表達式可以是一個方法的名字或一個内聯語句,如果沒有修飾符也可以省略。
如下段代碼所示,邏輯簡單,點選按鈕,将資料heading的屬性更改為Hello World,我們實作了内聯語句的綁定:
<button v-on:click="heading = 'Hello World!'">Click Mebutton>
除了使用 v-on:click 文法外,我們可以使用更短的文法進行綁定——@click, 在上面的例子我們實作了資料内容的更改,我們還可以綁定使用者自定義方法,如下段代碼所示:
js部分:
new Vue({ el: "#main", data: { status: "" }, methods: { updateStatus(event) { const buttons = ['left', 'middle', 'right']; this.status = `You clicked the ${buttons[event.button]} button.`; } }});
Html部分:
<div id="main"> <button @mousedown="updateStatus" @contextmenu.prevent="">Toggle Me!button><p>{{ status }}p>div>
上述代碼,我們将mousedown事件綁定了updateStatus方法,用于幫助使用者确定是點選了滑鼠左鍵還是右鍵,同時我們添加了第二個事件監聽contextmenu.prevent,用來阻止滑鼠右鍵預設的上下文菜單行為。類似的還有其它常見事件修飾符:
- .stop:阻止事件冒泡。
- .prevent:阻止浏覽器預設行為,比如頁面滾動等。
- .capture:翻轉事件傳播方向,本來事件是按照最内元素到外元素執行的,叫事件冒泡,.capture正好相反,讓元素從外到内傳播事件。
- .self:元素隻在綁定的元素上執行。
- .once:綁定的事件隻執行一次,之後失效。
Methods
Vue對象裡專門有Methods的屬性,友善我們自定義相關的方法,并在模闆裡很容易的調用,正如上個示例,我們是這樣定義方法的:
methods: { updateStatus(event) { const buttons = ['left', 'middle', 'right']; this.status = `You clicked the ${buttons[event.button]} button.`; }}
Computed
有時候你需要自定義相關的方法監聽計算模闆中的資料并進行相應,如果你想避免不必要的方法開銷,你可以使用Vue的“計算屬性”方案。
一個計算屬性其實就是一個函數,用來緩存和傳回資料。其函數依賴一個資料項,資料項發生改變,其函數就要重新運算,進行新的資料輸出。
為了實踐這個屬性,我們在資料項裡增加一個排序字段屬性,如下所示:
data: { heading: "Staff Directory", sortBy: "firstName" employees: [ ...]}
接下來,我們在标題列裡添加點選處理事件,以便更改sortBy的屬性,如下段代碼所示:
<tr> <th>Avatarth> <th @click="sortBy = 'firstName'">First Nameth><th @click="sortBy = 'lastName'">Last Nameth><th @click="sortBy = 'email'">Emailth><th @click="sortBy = 'phone'">Phoneth><th @click="sortBy = 'department'">Departmentth>tr>
最後,讓我們在Vue屬性中,添加一個計算屬性,該屬性根據鍵值進行資料排序,如下段代碼所示:
computed: { sortedEmployees() { return this.employees.sort((a, b) => a[this.sortBy].localeCompare(b[this.sortBy])) }}
接下來我們更改v-for區域的代碼,将我們的計算屬性添加進去,示例代碼如下:
<tr v-for="(employee, index) in sortedEmployees" :key="index">...tr>
由于Vue語句提供的文法糖,輸出資料sortedEmployees被緩存,當sortBy屬性改變時,sortedEmployees的值将會重新計算。
03
最終完成後的代碼
基于前面的知識内容,我們最終完成的index.html代碼如下,你可以點選原文連結預覽效果(請在pc端預覽):
/span>html>><head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Vue新手入門篇(一)title> <link rel="stylesheet" href="https://www.qianduandaren.com/demo/vue/css/semantic.min.css" target="_blank" rel="external nofollow" > <style> h1.ui.center.header { margin-top: 3em; } style>head><body><main id="main"> <h1 class="ui center aligned header">{{ heading }}h1> <div class="ui container"> <table class="ui celled table"> <thead> <tr> <th>Avatarth> <th @click="sortBy = 'firstName'">First Nameth> <th @click="sortBy = 'lastName'">Last Nameth> <th @click="sortBy = 'email'">Emailth> <th @click="sortBy = 'phone'">Phoneth> <th @click="sortBy = 'department'">Departmentth> tr> thead> <tbody> <tr v-for="(employee, index) in sortedEmployees" :key="index"> <td> <img :src="employee.photoUrl" class="ui mini rounded image" /> td> <td>{{ employee.firstName }}td> <td>{{ employee.lastName }}td> <td>{{ employee.email }}td> <td>{{ employee.phone }}td> <td>{{ employee.department }}td> tr> tbody> <tfoot> <tr> <th colspan="6">th> tr> tfoot> table> div>main><script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js">script><script> new Vue({ el: "#main", data: { heading: "前端達人開發部", sortBy: 'department', employees: [ { "firstName": "amelia", "lastName": "austin", "photoUrl": "https://www.qianduandaren.com/demo/vue/img/women/1.jpg", "email": "[email protected]", "phone": "(651)-507-3705", "department": "Engineering" }, { "firstName": "bobbie", "lastName": "murphy", "photoUrl": "https://www.qianduandaren.com/demo/vue/img/women/2.jpg", "email": "[email protected]", "phone": "(925)-667-7604", "department": "Management" }, { "firstName": "kristin", "lastName": "terry", "photoUrl": "https://www.qianduandaren.com/demo/vue/img/women/3.jpg", "email": "[email protected]", "phone": "(021)-544-1184", "department": "Sales" }, { "firstName": "brandon", "lastName": "griffin", "photoUrl": "https://www.qianduandaren.com/demo/vue/img/men/1.jpg", "email": "[email protected]", "phone": "(509)-317-9506", "department": "Management" }, { "firstName": "tammy", "lastName": "gibson", "photoUrl": "https://www.qianduandaren.com/demo/vue/img/women/4.jpg", "email": "[email protected]", "phone": "(815)-727-0663", "department": "Support" }, ] }, computed: { sortedEmployees() { return this.employees.sort((a, b) => a[this.sortBy].localeCompare(b[this.sortBy])); } } });script>body>
本篇文章的内容就到這裡,接下來給大家留個作業題(答案将在下期文章進行公布),基于本文的例子,我們增加一個輸入框,實作雇員資訊的檢索功能(輸入雇員的全名或名字的部分内容,顯示資訊結果)。在下篇文章裡,我将繼續介紹如何工程化的建構Vue項目和Vue相關的工具,敬請期待。
精彩推薦
小技巧丨console的用法,不僅僅隻有console.log()
動畫基礎丨點和直線
太驚豔了,這些畫都是CSS的傑作!
css基礎丨如何了解transform的matrix()用法
css基礎丨如何了解Display的屬性:None,Block,Inline,Inline-Block
ES6基礎丨let和作用域
ES6基礎丨const介紹
ES6基礎丨預設參數值
ES6基礎丨展開文法(Spread syntax)
ES6基礎丨解構指派(destructuring assignment)
ES6基礎丨箭頭函數(Arrow functions)
ES6基礎丨模闆字元串(Template String)
ES6基礎丨Set與WeakSet
ES6基礎丨Map與WeakMap
ES6基礎丨Symbol介紹:獨一無二的值
ES6基礎丨Object的新方法
ES6基礎丨疊代器(iterator)
ES6基礎丨生成器(Generator)
ES6基礎丨你需要知道的Array數組新方法(上)
資料結構基礎丨棧簡介(使用ES6)
資料結構基礎丨隊列簡介(使用ES6)
JavaScript基礎丨前端不懂它,會再多架構也不過隻是會用而已!
JavaScript基礎丨你真的了解JavaScript嗎?
JavaScript基礎丨回調(callback)是什麼?
JavaScript基礎丨Promise使用指南
JavaScript基礎丨深入學習async/await
JS加載慢?谷歌大神帶你飛!(文末送電子書)
19年你應該關注這50款前端熱門工具(上)
19年你應該關注這50款前端熱門工具(中)
19年你應該關注這50款前端熱門工具(下)
專注分享當下最實用的前端技術。關注前端達人,與達人一起學習進步!
長按關注"前端達人"