谷歌也推出了基於組件的第二代Angular框架,致力於開發全平臺應用——Web、移動 Web、移動應用、原生應用和桌面原生應用,其最爲核心的特色是:MVC、模塊化、自動化雙向數據綁定、語義化標籤、依賴注入等等。javascript
後期之秀Vue.js,其做者尤雨溪在谷歌就任時建立並於2014年發佈,自發布以來,因爲其設計靈活,方便集成到現有項目中,並能輕鬆構建複雜的應用程序,所以Vuejs大受歡迎,如今成爲三大前端主流框架之一。css
在你閱讀本文時,你必定疑惑爲何選擇Vue,如下的幾個理由是否是能打動你選擇Vue?html
一、很容易集成上手 到現有項目。你能夠在現有的網站中輕鬆集成Vue,無需引入新的工具設置複雜的流程,若是你習慣使用jQuery,那你也很容易上手Vue的。 前端
二、基於組件的架構。容許應用程序模塊化,組件化,方便快速構建現代化的單頁面應用程序(SPA)。 vue
三、生態的完整性。幾乎你能想到的插件,你都能在社區裏找到。更重要的是,其重要的的庫好比路由,狀態管理等都是有Vue官方團隊進行維護,不像React生態,官方並非很積極的提供解決方案。java
四、 普遍的使用。從國外的GitLab到國內的阿里巴巴,尤爲國內愈來愈多公司的使用,讓其成爲國內前端必備技能。同時Vue.js成爲PHP流行框架Laravel的默認前端庫。因爲其使用的普遍性,將來會有更多的人去投入到這個框架中,讓其生態更增強大,收益最大的就是咱們每位開發者。react
首先說明下,經過本篇Vue.js基礎知識的學習,筆者將帶着你們完成以下圖所示的練習:npm
主要實現如下功能:數組
爲了方便你們快速入門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": "amelia.austin@example.com",
"phone": "(651)-507-3705",
"department": "Engineering"
},
{
"firstName": "bobbie",
"lastName": "murphy",
"photoUrl": "https://www.qianduandaren.com/demo/vue/img/women/2.jpg",
"email": "bobbie.murphy@example.com",
"phone": "(925)-667-7604",
"department": "Management"
}
]
}
});複製代碼
如今咱們有了數據,就須要進行界面數據的渲染和呈現,咱們須要使用模板語法——一雙大括號 ( {{}} ),進行數據綁定。以下段代碼所示:
<h1 class="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-*指令)
v-for
前面咱們介紹了加載數據的示例,你可能猜到了咱們須要使用循環遍歷的方式遍歷集合用於數據的展示,v-for指令的做用就是遍歷數據集合中的每項內容,以下段代碼所示:
<tbody> <tr v-for="employee in employees"> <td> <img src="https://www.qianduandaren.com/demo/vue/img/women/1.jpg" 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>複製代碼
從上述代碼咱們能夠看出,咱們在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>複製代碼
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 found</td> </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 found</td> </tr> </tbody>複製代碼
從上述代碼中,咱們加入了一個 isLoadingData 屬性,這在咱們動態加載數據的邏輯處理十分有用,由於是異步加載數據涉及網絡延遲等問題,數據加載前須要有個信息提示用戶數據正在加載中。
v-bind
有時候,你須要將數據綁定到html元素的屬性上,例如url上的href屬性,img的src屬性。
還記得咱們上面的例子,咱們渲染數據時把img屬性寫死了,如今咱們可使用v-bind指令進行數據綁定,代碼以下:
<img v-bind:src="employee.photoUrl" class="ui mini rounded image" />複製代碼
除了上述寫法外,咱們能夠用更簡短的語法,只須要在屬性前使用:前綴便可,代碼以下:
<img :src="employee.photoUrl" class="ui mini rounded image" />複製代碼
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標籤區域的內容也隨之改變。
v-on
咱們可使用v-on:綁定事件監聽器,事件類型由參數指定。表達式能夠是一個方法的名字或一個內聯語句,若是沒有修飾符也能夠省略。
以下段代碼所示,邏輯簡單,點擊按鈕,將數據heading的屬性更改成Hello World,咱們實現了內聯語句的綁定:
<button v-on:click="heading = 'Hello World!'">Click Me</button>複製代碼
除了使用 v-on:click 語法外,咱們可使用更短的語法進行綁定——@click, 在上面的例子咱們實現了屬性的更改,咱們還能夠綁定自定義用戶方法,以下段代碼所示:
new Vue({
el: "#main",
data: {
status: ""
},
methods: {
updateStatus(event) {
const buttons = ['left', 'middle', 'right'];
this.status = `You clicked the ${buttons[event.button]} button.`;
}
}
});複製代碼
<div id="main"> <button @mousedown="updateStatus" @contextmenu.prevent="">Toggle Me!</button> <p>{{ status }}</p> </div>複製代碼
上述代碼,咱們將mousedown事件綁定了updateStatus方法,用於幫助用戶肯定是點擊了鼠標左鍵仍是右鍵,同時咱們添加了第二個事件監聽contextmenu.prevent,用來阻止鼠標右鍵默認的上下文菜單行爲。相似的還有其它常見事件修飾符:
Vue對象裏專門有Methods的屬性,方便咱們自定義相關的方法,並在模板裏很容易的調用,正如上個示例,咱們是這樣定義方法的:
methods: {
updateStatus(event) {
const buttons = ['left', 'middle', 'right'];
this.status = `You clicked the ${buttons[event.button]} button.`;
}
}複製代碼
有時候你須要自定義相關的方法監聽計算模板中的數據並進行相應,若是你想避免沒必要要的方法開銷,你可使用Vue的」計算屬性「方案。
一個計算屬性其實就是一個函數,用來緩存和返回數據。其函數依賴一個數據項,數據項發生改變,其函數就要從新運算,進行新的數據輸出。
爲了實踐這個屬性,咱們在數據項裏增長一個排序字段屬性,以下所示:
data: {
heading: "Staff Directory",
sortBy: "firstName"
employees: [
...
]
}複製代碼
接下來,咱們在標題列裏添加點擊處理事件,以便更改sortBy的屬性,以下段代碼所示:
<tr> <th>Avatar</th> <th @click="sortBy = 'firstName'">First Name</th> <th @click="sortBy = 'lastName'">Last Name</th> <th @click="sortBy = 'email'">Email</th> <th @click="sortBy = 'phone'">Phone</th> <th @click="sortBy = 'department'">Department</th> </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的值將會從新計算。
基於前面的知識內容,咱們最終完成的index.html代碼以下:
<!DOCTYPE html> <html lang="en"> <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 Staff Directory - Jump Start Vue.js</title> <link rel="stylesheet" href="https://www.qianduandaren.com/demo/vue/semantic.min.css"> <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>Avatar</th> <th @click="sortBy = 'firstName'">First Name</th> <th @click="sortBy = 'lastName'">Last Name</th> <th @click="sortBy = 'email'">Email</th> <th @click="sortBy = 'phone'">Phone</th> <th @click="sortBy = 'department'">Department</th> </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": "amelia.austin@example.com", "phone": "(651)-507-3705", "department": "Engineering" }, { "firstName": "bobbie", "lastName": "murphy", "photoUrl": "https://www.qianduandaren.com/demo/vue/img/women/2.jpg", "email": "bobbie.murphy@example.com", "phone": "(925)-667-7604", "department": "Management" }, { "firstName": "kristin", "lastName": "terry", "photoUrl": "https://www.qianduandaren.com/demo/vue/img/women/3.jpg", "email": "kristin.terry@example.com", "phone": "(021)-544-1184", "department": "Sales" }, { "firstName": "brandon", "lastName": "griffin", "photoUrl": "https://www.qianduandaren.com/demo/vue/img/men/1.jpg", "email": "brandon.griffin@example.com", "phone": "(509)-317-9506", "department": "Management" }, { "firstName": "tammy", "lastName": "gibson", "photoUrl": "https://www.qianduandaren.com/demo/vue/img/women/4.jpg", "email": "tammy.gibson@example.com", "phone": "(815)-727-0663", "department": "Support" }, ] }, computed: { sortedEmployees() { return this.employees.sort((a, b) => a[this.sortBy].localeCompare(b[this.sortBy])); } } }); </script> </body> </html>複製代碼
本篇文章的內容就到這裏,接下來給你們留個做業題(答案將在下期文章進行公佈),基於本文的例子,咱們增長一個輸入框,實現僱員信息的檢索功能(輸入僱員的全名或名字的部份內容,顯示信息結果)。在下篇文章裏,我將繼續介紹如何工程化的構建Vue項目和Vue相關的工具,敬請期待。