本文的Demo和源代碼已放到GitHub,若是您以爲本篇內容不錯,請點個贊,或在GitHub上加個星星!javascript
https://github.com/zwl-jasmine95/Vue_testcss
如下全部知識都是基於vue.js 2.0版本html
Vue.js(讀音 /vjuː/,相似於 view) 是一套構建用戶界面的漸進式框架。與其餘重量級框架不一樣的是,Vue 採用自底向上增量開發的設計。Vue 的核心庫只關注視圖層,它不只易於上手,還便於與第三方庫或既有項目整合。前端
另外一方面,當與單文件組件和 Vue 生態系統支持的庫結合使用時,Vue 也徹底可以爲複雜的單頁應用程序提供驅動。vue
Vue.js是當下很火的一個JavaScript MVVM庫,它是以數據驅動和組件化的思想構建的。相比於Angular.js,Vue.js提供了更加簡潔、更易於理解的API,使得咱們可以快速地上手並使用Vue.js。java
MVVM:git
DOM Listeners和Data Bindings兩個工具,它們是實現雙向綁定的關鍵。
從View側看,ViewModel中的DOM Listeners工具會幫咱們監測頁面上DOM元素的變化,若是有變化,則更改Model中的數據;
從Model側看,當咱們更新Model中的數據時,Data Bindings工具會幫咱們更新頁面中的DOM元素。github
Vue.js提供了一些經常使用的內置指令:express
Vue.js 的核心是一個容許採用簡潔的模板語法來聲明式的將數據渲染進 DOM。 我的感受實現原理仍是和angularJS很像的。bootstrap
咱們試一下寫一個簡單的hello world!:
1 <body> 2 <div id="app"> 3 {{message}} 4 </div> 5 6 <script type="text/javascript" src="lib/js/vue.js"></script> 7 <script type="text/javascript"> 8 /** 9 * 採用簡潔的模板語法來聲明式的將數據渲染進 DOM 10 */ 11 var app = new Vue({ 12 el:'#app', 13 data:{ 14 message:'Hello World!' 15 } 16 }); 17 </script> 18 </body>
能夠經過app.message來查看數據值。可是在寫代碼的過程當中須要注意很重要的兩點:
1)咱們編寫的js代碼必定要放在body標籤的最下面,否則會報錯‘沒有找到#app’,由於js代碼放在head標籤裏時頁面DOM結果還沒加載完。
2){{message}}這裏其實至關於一個變量,能夠任意命名,只要和js裏對應便可。
數據和 DOM 已經被綁定在一塊兒,一切都是響應式的。能夠經過app.message改變數據值。
______________ 除了文本插值,咱們還能夠採用指令的方式綁定 DOM 元素屬性,指令帶有前綴 v-
,以表示它們是 Vue 提供的特殊屬性。
v-bind
指令能夠在其名稱後面帶一個參數,中間放一個冒號隔開,這個參數一般是HTML元素的特性(attribute),例如:v-bind:class
v-bind:argument="expression"
1 <body> 2 <div id="app-2"> 3 <span v-bind:title="message"> 4 鼠標懸停幾秒鐘查看此處動態綁定的提示信息! 5 </span> 6 </div> 7 8 <script type="text/javascript" src="lib/js/vue.js"></script> 9 <script type="text/javascript"> 10 /** 11 * 採用簡潔的模板語法來聲明式的將數據渲染進 DOM 12 */ 13 var app2 = new Vue({ 14 el: '#app-2', 15 data: { 16 message: '頁面加載於 ' + new Date() 17 } 18 }) 19 </script> 20 </body>
這裏該指令的做用是:「將這個元素節點的 title
屬性和 Vue 實例的 message
屬性保持一致」。
使用Vue的過程就是定義MVVM各個組成部分的過程的過程。
在建立Vue實例時,須要傳入一個選項對象,選項對象能夠包含數據、掛載元素、方法、模生命週期鉤子等等。
在這個示例中,選項對象的el屬性指向View,el: '#app'
表示該Vue實例將掛載到<div id="app">...</div>
這個元素;data屬性指向Model,data: message
表示咱們的Model是message對象。
Vue.js有多種數據綁定的語法,最基礎的形式是文本插值,使用一對大括號語法,在運行時{{ message }}
會被數據對象的message屬性替換,因此頁面上會輸出"Hello World!"。
雙大括號以及v-text會將數據解釋爲純文本,而非 HTML 。爲了輸出真正的 HTML ,須要使用 v-html
指令。
v-if是條件渲染指令,根據條件表達式的值來執行元素的插入或者刪除行爲。
v-if="expression"
expression是一個返回bool值的表達式,表達式能夠是一個bool屬性,也能夠是一個返回bool的運算式。
1 <div class="app"> 2 <span v-if="true">你好!vue.js!</span> 3 </div>
這一段代碼能夠還用js來實現:
<body> <div class="app"> <!--這裏不必定要用id,class也行的,只要js裏的選擇器對應--> <span v-if="tag">你好!vue.js!</span> </div> <script type="text/javascript" src="lib/js/vue.js"></script> <script type="text/javascript"> var app = new Vue({ el:'.app', //注意選擇器 data:{ tag:true } }); </script> </body>
儘管用了class而不是id,可是在控制檯也是能夠經過app.tag來查看變量的:
拓展:
v-show
也是條件渲染指令,和v-if指令不一樣的是,使用v-show
指令的元素始終會被渲染到HTML,它只是簡單地爲元素設置CSS的style屬性。
還能夠用v-else
指令爲v-if
或v-show
添加一個「else塊」。v-else
元素必須當即跟在v-if
或v-show
元素的後面——不然它不能被識別。
(v-else
元素是否渲染在HTML中,取決於前面使用的是v-if
仍是v-show
指令。)
1 <body> 2 <div id="app"> 3 <p v-if="tag">你好!vue.js!</p> 4 <p v-else>這裏是例外狀況</p> 5 </div> 6 7 <script type="text/javascript" src="lib/js/vue.js"></script> 8 <script type="text/javascript"> 9 var app = new Vue({ 10 el:'#app', //注意選擇器 11 data:{ 12 tag:true 13 } 14 }); 15 </script> 16 </body>
在控制檯中改變tag的值:
v-for
指令基於一個數組渲染一個列表,它和JavaScript的遍歷語法類似:
v-for="item in items"
items是一個數組,item是當前被遍歷的數組元素。
v-for
指令能夠綁定數組的數據來渲染一個項目列表:
1 <body> 2 <div class="app"> 3 <p>前端學習之路:</p> 4 <ol> 5 <li v-for="item in items">{{item.text}}</li> 6 </ol> 7 </div> 8 9 <script type="text/javascript" src="lib/js/vue.js"></script> 10 <script type="text/javascript"> 11 var app = new Vue({ 12 el:'.app', 13 data:{ 14 items:[ 15 {text:'HTML'}, 16 {text:'CSS'}, 17 {text:'JavaScript'}, 18 {text:'jQuery'} 19 ] 20 } 21 }); 22 </script> 23 </body>
在控制檯裏,輸入 app.items.push({ text: '新項目' })
,你會發現列表中添加了一個新項:
另外:v-for還有一種特殊寫法能夠獲取索引值:
index能夠直接用做索引值
v-on
指令用於給監聽DOM事件,它的用語法和v-bind是相似的,例如監聽<a>元素的點擊事件:
<a v-on:click="doSomething">
有兩種形式調用方法:綁定一個方法(讓事件指向方法的引用),或者使用內聯語句。
1 <body> 2 <div id="app"> 3 <p>{{ message }}</p> 4 <button v-on:click="reverseMessage">逆轉消息</button> 5 </div> 6 7 <script type="text/javascript" src="lib/js/vue.js"></script> 8 <script type="text/javascript"> 9 var app = new Vue({ 10 el: '#app', 11 data: { 12 message: 'Hello Vue.js!' 13 }, 14 // 在 `methods` 對象中定義方法 15 methods: { 16 reverseMessage: function () { 17 //reverse() 方法用於顛倒數組中元素的順序。 18 //方法中的this指向app 19 this.message = this.message.split('').reverse().join('') 20 } 21 } 22 }) 23 </script> 24 </body>
——————>
Vue.js爲最經常使用的兩個指令v-bind
和v-on
提供了縮寫方式。v-bind指令能夠縮寫爲一個冒號,v-on指令能夠縮寫爲@符號。
Vue 提供了 v-model
指令,使表單輸入和應用狀態間的雙向綁定變得垂手可得。
1 <body> 2 <div id="app"> 3 <p>{{ message }}</p> 4 <input type="text" v-model="message"> 5 <button v-on:click="alertMessage">彈出輸入框內容</button> 6 </div> 7 8 <script type="text/javascript" src="lib/js/vue.js"></script> 9 <script type="text/javascript"> 10 var app = new Vue({ 11 el: '#app', 12 data: { 13 message: 'Hello Vue.js!' 14 }, 15 // 在 `methods` 對象中定義方法 16 methods: { 17 alertMessage: function () { 18 19 //方法中的this指向app 20 alert(this.message); 21 } 22 } 23 }) 24 </script> 25 </body>
改變輸入框的值,會發現上面的p標籤的值也改變了。而後點擊按鈕,彈框中會顯示改變的輸入框值,這就是雙向數據綁定。(也能夠經過控制檯來改變輸入框以及p標籤的值)
一開始就學習vue.js的內置指令,估計有些人對vue.js的執行仍是有點不理解,下面作簡單的講解。
每一個 Vue.js 應用都是經過構造函數 Vue
建立一個 Vue 的根實例 啓動的:
1 var vm = new Vue({ 2 // 選項 3 })
雖然沒有徹底遵循 MVVM 模式, Vue 的設計無疑受到了它的啓發。所以在文檔中常常會使用 vm
(ViewModel 的簡稱) 這個變量名錶示 Vue 實例。
在實例化 Vue 時,須要傳入一個選項對象,它能夠包含數據、模板、掛載元素、方法、生命週期鉤子等選項。
(這是我用思惟導圖工具xMind畫的,後面三個就不具體列出來了,更加具體的內容能夠在官方API查看。)
new一個vue對象的時候能夠設置屬性,其中最重要的包括三個,分別是data、methods、watch。
其中data表明vue對象的數據,methods表明vue對象的方法,watch設置了對象監聽的方法。以下:
在第二節的內置指令中已經用到了data和methods。,其餘的後面用到了再系統講解。
另外能夠擴展Vue構造器,從而用預約義選項建立可複用的組件構造器:
1 var MyComponent = Vue.extend({ 2 // 擴展選項 3 }) 4 // 全部的 `MyComponent` 實例都將以預約義的擴展選項被建立 5 var myComponentInstance = new MyComponent()
全部的 Vue.js 組件其實都是被擴展的 Vue 實例。
每一個 Vue 實例都會代理其 data
對象裏全部的屬性:
1 var data = { a: 1 } 2 var vm = new Vue({ 3 data: data 4 }) 5 vm.a === data.a // -> true 6 // 設置屬性也會影響到原始數據 7 vm.a = 2 8 data.a // -> 2 9 // ... 反之亦然 10 data.a = 3 11 vm.a // -> 3
注意只有這些被代理的屬性是響應的。若是在實例建立以後添加新的屬性到實例上,它不會觸發視圖更新。
除了 data 屬性, Vue 實例暴露了一些有用的實例屬性與方法。這些屬性與方法都有前綴 $
,以便與代理的 data 屬性區分。
1 var data = { a: 1 } 2 var vm = new Vue({ 3 el: '#example', 4 data: data 5 }) 6 vm.$data === data // -> true 7 vm.$el === document.getElementById('example') // -> true 8 // $watch 是一個實例方法 9 vm.$watch('a', function (newVal, oldVal) { 10 // 這個回調將在 `vm.a` 改變後調用 11 })
每一個 Vue 實例在被建立以前都要通過一系列的初始化過程。例如,實例須要配置數據觀測(data observer)、編譯模版、掛載實例到 DOM ,而後在數據變化時更新 DOM 。在這個過程當中,實例也會調用一些 生命週期鉤子 ,這就給咱們提供了執行自定義邏輯的機會。例如,created
這個鉤子在實例被建立以後被調用:
var vm = new Vue({ data: { a: 1 }, created: function () { // `this` 指向 vm 實例 console.log('a is: ' + this.a) } }) // -> "a is: 1"
也有一些其它的鉤子,在實例生命週期的不一樣階段調用,如 mounted
、 updated
、destroyed
。鉤子的 this
指向調用它的 Vue 實例。一些用戶可能會問 Vue.js 是否有「控制器」的概念?答案是,沒有。組件的自定義邏輯能夠分佈在這些鉤子中。
生命週期圖示:
主要是利用v-for來實現的:(源代碼: github上 demo1/table.html)
html:
1 <table id="myTable" class="table table-striped"> 2 <thead> 3 <tr> 4 <th>姓名</th> 5 <th>性別</th> 6 <th>年齡</th> 7 </tr> 8 </thead> 9 <tbody> 10 <tr v-for="item in items"> 11 <td>{{item.name}}</td> 12 <td>{{item.sex}}</td> 13 <td>{{item.age}}</td> 14 </tr> 15 </tbody> 16 </table>
js:
var vm = new Vue({ el:'#myTable', data:{ items:[ { name:'張姍', sex:'女', age:'42' }, { name:'李四', sex:'男', age:'33' }, { name:'王五', sex:'男', age:'58' } ] } });
將v-for嵌套在tr標籤中,這樣就能夠生成下面的表格了。案例比較簡單。
(源代碼: github上 demo1/editTable.html)
首先咱們先肯定一下須要作什麼:
咱們能夠在上面的表單中輸入要添加的表格行的具體內容,而後點擊添加按鈕便可在表格中增長一行。
點擊表格每一行後面的刪除按鈕,便可刪除該表格行。
1)佈局
在實現功能以前,現將表單模塊和表格模塊利用HTML實現,這裏爲了節省時間,直接是使用bootstrap框架。
1 <form class="form-horizontal" role="form"> 2 <div class="form-group"> 3 <label for="name" class="col-sm-2 control-label">姓名</label> 4 <div class="col-sm-10"> 5 <input type="text" class="form-control" id="name" placeholder="請輸入名字"> 6 </div> 7 </div> 8 <div class="form-group"> 9 <label for="age" class="col-sm-2 control-label">年齡</label> 10 <div class="col-sm-10"> 11 <input type="text" class="form-control" id="age" placeholder="請輸入年齡"> 12 </div> 13 </div> 14 <div class="form-group"> 15 <label for="sex" class="col-sm-2 control-label">性別</label> 16 <div class="col-sm-10"> 17 <select name="" id="sex" class="form-control"> 18 <option value="男">男</option> 19 <option value="女">女</option> 20 </select> 21 </div> 22 </div> 23 <div class="form-group"> 24 <div class="col-sm-offset-2 col-sm-10"> 25 <button type="button" class="btn btn-primary">添加</button> 26 </div> 27 </div> 28 </form> 29 30 <table id="editTable" class="table table-striped"> 31 <thead> 32 <tr> 33 <th>姓名</th> 34 <th>年齡</th> 35 <th>性別</th> 36 <th>操做</th> 37 </tr> 38 </thead> 39 <tbody> 40 <tr v-for="item in items"> 41 <td>{{item.name}}</td> 42 <td>{{item.age}}</td> 43 <td>{{item.sex}}</td> 44 <td><button type="button" class="btn btn-primary">刪除</button></td> 45 </tr> 46 </tbody> 47 </table>
2)數據綁定
接下來咱們使用v-model將表單輸入框綁定到數據層。
先在data裏建立一個新的對象-newItem,用來存放新增的表格行:
而後將數據綁定到輸入框,例如:
3)添加新增按鈕事件
定義名爲createItem的函數:
1 methods:{ 2 creatItem:function () { 3 this.items.push(this.newItem); //this指向data 4 // 添加完newItem對象後,重置newItem對象 5 this.newItem = {name: '', age: 0, sex: '女'} 6 } 7 }
4)添加刪除按鈕事件
定義名爲deleteItem的函數,並將該表格行的索引做爲參數傳入;
1 //事件處理 2 methods:{ 3 /** 4 * 根據表格行的索引刪除該表格行 5 * @param {[number]} index [表格行的索引] 6 * @return 7 */ 8 deleteItem:function (index) { 9 this.items.splice(index,1); 10 } 11 }
完整代碼:
https://github.com/zwl-jasmine95/Vue_test/blob/master/demo1/editTable.html
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <title>實時表格編輯</title> 6 <link rel="stylesheet" href="../lib/css/bootstrap.min.css"> 7 <style> 8 body{ 9 padding:50px; 10 } 11 </style> 12 </head> 13 <body> 14 <div id="editTable"> 15 <form class="form-horizontal" role="form"> 16 <div class="form-group"> 17 <label for="name" class="col-sm-2 control-label">姓名</label> 18 <div class="col-sm-10"> 19 <input type="text" class="form-control" id="name" placeholder="請輸入名字" v-model="newItem.name"> 20 </div> 21 </div> 22 <div class="form-group"> 23 <label for="age" class="col-sm-2 control-label">年齡</label> 24 <div class="col-sm-10"> 25 <input type="text" class="form-control" id="age" placeholder="請輸入年齡" v-model="newItem.age"> 26 </div> 27 </div> 28 <div class="form-group"> 29 <label for="sex" class="col-sm-2 control-label">性別</label> 30 <div class="col-sm-10"> 31 <select name="" id="sex" class="form-control" v-model="newItem.sex"> 32 <option value="男">男</option> 33 <option value="女">女</option> 34 </select> 35 </div> 36 </div> 37 <div class="form-group"> 38 <div class="col-sm-offset-2 col-sm-10"> 39 <button type="button" class="btn btn-primary" v-on:click="creatItem">添加</button> 40 </div> 41 </div> 42 </form> 43 44 <table class="table table-striped"> 45 <thead> 46 <tr> 47 <th>姓名</th> 48 <th>年齡</th> 49 <th>性別</th> 50 <th>操做</th> 51 </tr> 52 </thead> 53 <tbody> 54 <tr v-for="(item,index) in items"> 55 <td>{{item.name}}</td> 56 <td>{{item.age}}</td> 57 <td>{{item.sex}}</td> 58 <td><button type="button" class="btn btn-primary" v-on:click="deleteItem(index)">刪除</button></td> 59 </tr> 60 </tbody> 61 </table> 62 </div> 63 64 <script type="text/javascript" src="../lib/js/vue.js"></script> 65 <script type="text/javascript"> 66 var vm = new Vue({ 67 el:'#editTable', 68 data:{ 69 newItem:{ 70 name:'', 71 sex:'女', 72 age:'0' 73 }, 74 items:[ 75 { 76 name:'張姍', 77 sex:'女', 78 age:'42' 79 }, 80 { 81 name:'李四', 82 sex:'男', 83 age:'33' 84 }, 85 { 86 name:'王五', 87 sex:'男', 88 age:'58' 89 } 90 ] 91 }, 92 //事件處理 93 methods:{ 94 creatItem:function () { 95 this.items.push(this.newItem); //this指向data 96 // 添加完newItem對象後,重置newItem對象 97 this.newItem = {name: '', age: 0, sex: '女'} 98 }, 99 100 /** 101 * 根據表格行的索引刪除該表格行 102 * @param {[number]} index [表格行的索引] 103 * @return 104 */ 105 deleteItem:function (index) { 106 this.items.splice(index,1); 107 } 108 } 109 110 }); 111 </script> 112 </body> 113 </html>