本文是小羊根據Vue.js文檔進行解讀的第一篇文章,主要內容涵蓋Vue.js的基礎部分的知識的,文章順序基本按照官方文檔的順序,每一個知識點現附上代碼,而後根據代碼給予我的的一些理解,最後還放上在線編輯的代碼以供練習和測試之用;
在最後,我參考SegmentFault上的一篇技博,對Vue進行初入的實戰,目的是將新鮮學到的知識當即派上用場;
若是你仍是前端的小白,相信這篇文章可能會對產生一些幫助和引發思想的碰撞,由於你們的學習歷程是類似的,遇到的困惑也有必定的共通性,若是文章出現謬誤之處,歡迎各位童鞋及時指正;javascript
目錄css
1.Vue.js是什麼html
2.Vue.js的基本語法前端
3.Vue.js的小做品vue
Vue.js(讀音 /vjuː/, 相似於 view) 是一套構建用戶界面的 漸進式框架。與其餘重量級框架不一樣的是Vue 的核心庫只關注視圖層。
Vue.js 的目標是經過儘量簡單的 API 實現響應的數據綁定和組合的視圖組件。java
Vue.js是一種MVVM框架,其中html是view層,js是model層,經過vue.js(使用v-model這個指令)完成中間的底層邏輯,實現綁定的效果。改變其中的任何一層,另一層都會改變;jquery
2.1 Vue構造函數開啓Vue之旅ajax
經過構造函數Vue建立一個Vue的根實例json
1 <div id='#el'></div> 2 --- 3 var vm = new Vue({ 4 //options 5 el:'#el', 6 data:{}, 7 methods:{} 8 }) 9 --- 10 //擴展Vue構造器 11 var MyComponent = Vue.extend({ 12 //擴展選項 13 }) 14 var vm = new MyComponent({})
解讀:segmentfault
2.2 Vue實例的屬性和方法
Vue實例將代理data對象的全部屬性,也就是說部署在data對象上的全部屬性和方法都將直接成爲Vue實例的屬性和方法
1 <div id="app">{{message}} 2 <button v-on:click="sayHello">click me</button> 3 </div> 4 --- 5 var app = new Vue({ 6 el:'#app', 7 data:{ 8 message:'hello world!', 9 sayHello:function(){ 10 console.log(1) 11 } 12 } 13 }) 14 --- 15 //若是想要獲取到app這一實例中選項的對象,Vue提供$進行獲取 16 app.$el === document.getElementById('app')//true 17 app.$data.message//hello world
【TIP】
Vue實例所代理data對象上的屬性只有在實例建立的同時進行初始化才具備響應式更新,若在實例建立以後添加是不會觸發視圖更新的;
2.3數據綁定操做
綁定文本和HTML
1 <div id = "app"> 2 {{msg}} 3 <div v-html="hi"></div> 4 </div> 5 --- 6 var app = new Vue({ 7 el: '#app', 8 data:{ 9 msg: 'hello world!', 10 hi:'<h1>hi</h1>' 11 } 12 })
解讀:
綁定數據在元素的屬性
1 <div id="app" v-bind:title='message' v-bind:style='red' v-once> 2 {{message}} 3 </div> 4 --- 5 var app = new Vue({ 6 el: '#app', 7 data:{ 8 message: 'hello world!', 9 red: 'color:red' 10 } 11 })
解讀:
使用JS表達式處理數據
1 <div id='#app'> 2 <p v-once>{{num + 10 }}</p> 3 <p v-if='seen'>{{message + 'jirengu'}}</p> 4 </div> 5 --- 6 var app = new Vue({ 7 el: '#app', 8 data:{ 9 num:10, 10 message: 'hello world!', 11 seen:true 12 } 13 })
使用過濾器來格式化數據
<div id="app" > <p v-if='seen'>{{message | capitalize}}</p> </div> --- var app = new Vue({ el: '#app', data:{ message: 'hello world!', seen:true, }, filters:{ capitalize:function(value){ if(!value) return '' value = value.toString() return value.charAt(0).toUpperCase() + value.slice(1) } } })
條件指令控制DOM元素的顯示操做
1 <div id="app" > 2 <p v-if='seen'>{{message}}</p> 3 </div> 4 --- 5 var app = new Vue({ 6 el: '#app', 7 data:{ 8 message: 'hello world!', 9 seen:true 10 } 11 })
解讀:
循環指令實現數據的遍歷
1 <div id="app"> 2 <ol> 3 <li v-for='item in items'> 4 {{ item.text }} 5 </li> 6 </ol> 7 </div> 8 --- 9 var app = new Vue({ 10 el: '#app', 11 data:{ 12 items:[ 13 {text:'Vue'}, 14 {text:'React'}, 15 {text:'Angular'} 16 ] 17 } 18 })
解讀:
事件綁定指令能夠實現事件監聽
1 <div id='app'> 2 <p>{{message}}</p> 3 <button v-on:click='reverseMessage'>reverseMesssage</button> 4 </div> 5 --- 6 var app = new Vue({ 7 el: '#app', 8 data:{ 9 message: 'hello world!' 10 }, 11 methods:{ 12 reverseMessage:function(){ 13 this.message = this.message.split('').reverse().join('') 14 } 15 } 16 })
解讀:
小結
本章涉及Vue的基礎的數據綁定操做,內容包括:
2.4計算屬性
使用計算屬性完成一些數據計算操做
1 <div id="app" > 2 <p>Original message : {{message}}</p> 3 <p>Reversed message : {{ReversedMessage}}</p> 4 </div> 5 --- 6 var app = new Vue({ 7 el: '#app', 8 data:{ 9 message: 'hello world!', 10 }, 11 computed:{ 12 ReversedMessage:function(){ 13 return this.message.split('').reverse().join('') 14 } 15 } 16 })
解讀:
計算屬性 VS Methods
1 <div id="app" > 2 <p>Original message : {{message}}</p> 3 <p>Reversed message : {{ReversedMessage}}</p> 4 <p>Reversed message:{{reversedMessage()}}</p> 5 </div> 6 --- 7 var app = new Vue({ 8 el: '#app', 9 data:{ 10 message: 'hello world!', 11 }, 12 computed:{ 13 ReversedMessage:function(){ 14 return this.message.split('').reverse().join('') 15 } 16 }, 17 methods:{ 18 reversedMessage:function(){ 19 return this.message.split('').reverse().join('') 20 } 21 } 22 }) 23 解讀: 24 25 經過Vue實例的methods接口,咱們在模板中調用reversedMessage函數一樣實現需求; 26 methods與computed方法的區別在於:computed的數據依賴於app.message,只要message未變,則訪問ReverseMessage計算屬性將當即返回以前的計算結果,而methods則每次從新渲染時老是執行函數; 27 若是有緩存須要,請使用computed方法,不然使用methods替代; 28 計算屬性的setter 29 30 Vue實例的computed對象默認只有getter,若是你要設置數據,能夠提供一個setter,即設置器; 31 32 <div id="app" > 33 <p>Hi,I'm{{fullName}}</p> 34 </div> 35 --- 36 var app = new Vue({ 37 el: '#app', 38 data:{ 39 message: 'hello world!', 40 name:'Teren' 41 }, 42 computed:{ 43 fullName:{ 44 get:function(){ 45 return this.name 46 }, 47 set:function(value){ 48 this.name = value 49 } 50 } 51 } 52 })
2.5Class與Style的綁定
綁定Class
1 <div id="app" > 2 <!-- 直接綁定對象的內容 --> 3 <p class='static' v-bind:class="{active:isActive,error:hasError}">Hello world!</p> 4 <!-- 綁定對象 --> 5 <p v-bind:class="classObj">こんにちは </p> 6 <p v-bind:class='style' >你好</p> 7 <!-- 綁定數組 --> 8 <p v-bind:class="[staticClass,activeClass,errorClass]"> 9 Olá</p> 10 <button @click='changeColor'>click me</button> 11 </div> 12 --- 13 //css 14 .static{ 15 width: 200px; 16 height: 100px; 17 background: #ccc; 18 } 19 .active{ 20 color:red; 21 } 22 .error{ 23 font-weight: 800; 24 } 25 --- 26 var app = new Vue({ 27 el: '#app', 28 data:{ 29 isActive:true, 30 hasError:true, 31 classObj:{ 32 static:true, 33 active:true, 34 error:true, 35 }, 36 staticClass:'static', 37 activeClass:'active', 38 errorClass:'error', 39 40 }, 41 computed:{ 42 style:function(){ 43 return { 44 active: this.isActive, 45 static:true, 46 error:this.hasError 47 } 48 } 49 }, 50 methods:{ 51 changeColor:function(){ 52 this.isActive = !this.isActive 53 } 54 } 55 })
解讀:
data:{ classObj:{ static:true, active:true, error:true, } 你也能夠經過傳遞數組的方式爲class賦值v-bind:class="[staticClass,activeClass,errorClass]",此時你要在data對象上爲數組的元素的屬性賦值: data:{ staticClass:'static', activeClass:'active', errorClass:'error', }
【TIP】不管是哪一種方式,前提都是css中的class要先設定
綁定style
1 <div id="app" > 2 <p v-bind:style='styleObj'>Hello World!</p> 3 <p v-bind:style='[styleObj,bgObj]'>你好</p> 4 </div> 5 --- 6 var app = new Vue({ 7 el: '#app', 8 data:{ 9 styleObj:{ 10 fontWeight:800, 11 color:'red' 12 }, 13 bgObj:{ 14 width:'100px', 15 height:'80px', 16 background:'#ccc' 17 } 18 }, 19 })
解讀:
2.6條件渲染和列表渲染
前面簡單介紹了一下v-if、v-for和v-on指令,下面的部分將詳細介紹以上3個指令;
條件渲染
1 <div id="app" > 2 <p v-if='ok'>Hello World!</p> 3 <p v-else>Hello Universal</p> 4 <template v-if='motto'> 5 <h1>Steve Jobs</h1> 6 <p>motto:stay hungry ! stay foolish</p> 7 </template> 8 <p v-show='ok'>Show Me</p> 9 </div> 10 --- 11 var app = new Vue({ 12 el: '#app', 13 data:{ 14 ok:true, 15 motto:true, 16 }, 17 })
解讀:
【TIP】 v-if和v-show的區別
列表渲染
1 <div id="app" > 2 <ol> 3 <li v-for='car in cars'> 4 {{car.name}} 5 </li> 6 </ol> 7 <ul> 8 <li v-for='(food,index) in foods'> 9 {{index}}---{{food}}---{{delicious}} 10 </li> 11 </ul> 12 <ul> 13 <li v-for='(value,key,index) in object'> 14 {{index}}.{{key}}.{{value}} 15 </li> 16 </ul> 17 <div> 18 <span v-for='n in 10' style="margin-left:5px">{{n}}</span> 19 </div> 20 <span v-for='n in evenNumbers' style="margin-left:5px">{{n}}</span> 21 </div> 22 <!-- <div> 23 <span v-for='n in odd(counts)' style="margin-left:5px">{{n}}</span> 24 </div> --> 25 </div> 26 --- 27 var app = new Vue({ 28 el: '#app', 29 data:{ 30 delicious:'delicious', 31 cars:[ 32 {name:'Benz'}, 33 {name:'BMW'} 34 ], 35 foods:[ 36 'tomato', 37 'potato', 38 'ice cream' 39 ], 40 object :{ 41 name:'Benz', 42 age:'18' 43 }, 44 numbers:[1,2,3,4,5,6,7,8,9,10], 45 counts:[1,2,3,4,5] 46 }, 47 computed:{ 48 evenNumbers:function(){ 49 return this.numbers.filter(function(number){ 50 return number%2 === 0 51 }) 52 } 53 }, 54 methods:{ 55 odd:function(counts){ 56 return counts.filter(function(count){ 57 return count%2 === 1; 58 }) 59 } 60 } 61 }) 62 解讀: 63 64 v-for指令可以讓咱們循環渲染列表型數據,數據放在data對象中,類型能夠以下: 65 data:{ 66 //數字數組 67 numbers:[1,2,3,4,5,6,7,8,9,10], 68 counts:[1,2,3,4,5] 69 //字符串數組 70 foods:[ 71 'tomato', 72 'potato', 73 'ice cream' 74 ], 75 //對象數組 76 cars:[ 77 {name:'Benz'}, 78 {name:'BMW'} 79 ], 80 //對象 81 object :{ 82 name:'Benz', 83 age:'18' 84 }, 85 } 86 根據不一樣類型的數據,v-for指令在模板中具體採用的語法以下: 87 //數據爲數字數組 88 <div> 89 <span v-for="n in numbers">{{n}}</span> 90 </div> 91 --- 92 //數據爲字符數組 93 <ul> 94 <ol v-for='food in foods'>{{food}}</ol> 95 </ul> 96 --- 97 //數據爲對象 98 <ul> 99 <ol v-for="value in object">{{value}}</ol> 100 </ul> 101 //或者 102 <ul> 103 <ol v-for="(value,key,index) in object">{{index}}.{{key}}.{{value}}</ol> 104 </ul> 105 --- 106 //數據爲對象數組 107 <ul> 108 <ol v-for="car in cars">{{car.name}}</ol> 109 </ul> 110 在 v-for塊中,咱們擁有對父做用域屬性的徹底訪問權限; 111 【demo】 112 113 2.7 事件監聽 114 115 簡單的事件監聽——直接在指令上處理數據 116 117 <div id="#app"> 118 <p v-on:click="counter+=1">{{counter}}</p> 119 </div> 120 --- 121 var app = new Vue({ 122 el: "#app", 123 data:{ 124 counter: 0, 125 } 126 }) 127 複雜的事件監聽——在methods對象定義回調函數 128 129 <div id="#app"> 130 <p v-on:click="greet">{{vue}</p> 131 </div> 132 --- 133 var app = new Vue({ 134 el: "#app", 135 data:{ 136 vue:"hello Vue.js" 137 }, 138 methods:{ 139 greet:function(event){ 140 console.log(this.vue) 141 } 142 } 143 })
事件修飾符——調用事件對象函數的快捷方式
1 <div v-on:click.prevent="greet">1</div>//等價於event.preventDefault() 2 <div v-on:click.stop="greet">2</div>//等價於event.stopPropagation() 3 <div v-on:click.capture="greet">3</div>//等價於事件回調函數採用捕獲階段監聽事件 4 <div v-on:click.self="greet">4</div>//等價於event.target
按鍵修飾符——按鍵事件的快捷方式
常見按鍵別名包括:
- enter
- tab
- delete
- esc
- space
- up
- down
- left
- right
2.8 表單控件綁定
文本控件
1 <div id="app"> 2 <p>{{message}}</p> 3 <input type="text" v-model='message'> 4 </div> 5 --- 6 var app = new Vue({ 7 el:'#app', 8 data:{ 9 message:'Hello World!' 10 }, 11 })
解讀:
單選控件
1 <input id="man" value="man" type="radio" v-model='picked'> 2 <label for="man">Man</label> 3 <br> 4 <input id="woman" value="woman" type="radio" v-model='picked'> 5 <label for="woman">Woman</label> 6 <div style="margin-left:10px">{{picked}}</div> 7 --- 8 var app = new Vue({ 9 el:'#app', 10 data:{ 11 message:'Hello World!', 12 picked:'man' 13 }, 14 })
解讀:
複選框
1 <input type="checkbox" id="Benz" v-model='checked' value='Benz'> 2 <label for="Benz">Benz</label> 3 <input type="checkbox" id="BMW" v-model='checked' value="BMW"> 4 <label for="BMW">BMW</label> 5 <div>Checked Name:{{checked}}</div> 6 --- 7 var app = new Vue({ 8 el:'#app', 9 data:{ 10 message:'Hello World!', 11 picked:'man', 12 selected:"A", 13 checked:[], 14 }, 15 })
2.9 組件
組件能夠擴展 HTML 元素,封裝可重用的代碼。在較高層面上,組件是自定義元素;
經過Vue.component()接口將大型應用拆分爲各個組件,從而使代碼更好具備維護性、複用性以及可讀性註冊組件
1 <div id="app"> 2 <my-component></my-component> 3 </div> 4 --- 5 6 Vue.component('my-component',{ 7 template:'<div>my-first-component</div>' 8 }) 9 10 var app = new Vue({ 11 el:'#app', 12 data:{ 13 } 14 })
解讀:
局部註冊組件
1 <div id="app"> 2 <my-component> 3 <heading></heading> 4 </my-component> 5 </div> 6 --- 7 Vue.component('my-component',{ 8 template:'<div>my-first-component</div>' 9 }) 10 11 var Child = { 12 template: '<h3>Hello World</h3>' 13 } 14 15 var app = new Vue({ 16 el:'#app', 17 components:{ 18 'my-component':Child 19 } 20 })
解讀:
特殊DOM模板將會限制組件的渲染
像這些包含固定樣式的元素<ul>, <ol>, <table>, <select>,
自定義組件中使用這些受限制的元素時會致使渲染失敗;
通的方案是使用特殊的 is屬性:
1 <table> 2 <tr is="my-component"> 3 </table>
建立組件的data對象必須是函數
1 <counter></counter> 2 <counter></counter> 3 <counter></counter> 4 --- 5 Vue.component('counter',{ 6 template:'<button @click="count+=1">{{count}}</button>', 7 data:function(){ 8 return { 9 count: 0 10 } 11 } 12 })
解讀:
使用Props實現父組件向子組件傳遞數據
1 <child some-text='hello'></child> 2 <br> 3 <child v-bind:some-text='message'> </child> 4 --- 5 Vue.component('child',{ 6 template:'<div>{{someText}}</div>', 7 props:['someText'] 8 }) 9 var app = new Vue({ 10 el:'#app', 11 components:{ 12 'my-component':Child 13 }, 14 data:{ 15 message:"你好" 16 } 17 })
解讀:
組件實例的做用域是孤立的。這意味着不能而且不該該在子組件的模板內直接引用父組件的數據。可使用 props 把數據傳給子組件;
能夠用 v-bind動態綁定 props 的值到父組件的數據中。每當父組件的數據變化時,該變化也會傳導給子組件,注意這種綁定方式是單向綁定;
父組件是使用 props 傳遞數據給子組件,但若是子組件要把數據傳遞回去則使用自定義事件!
1 <div id="app"> 2 <p>{{total}}</p> 3 <button-counter v-on:increment='incrementTotal'></button-counter> 4 <button-counter @increment='incrementTotal'></button-counter> 5 </div> 6 --- 7 Vue.component('button-counter',{ 8 template:'<button v-on:click="increment">{{counter}}</button>', 9 data:function(){ 10 return { 11 counter:0 12 } 13 }, 14 methods:{ 15 increment:function(){ 16 this.counter +=1; 17 this.$emit('increment') 18 } 19 } 20 }) 21 22 var app = new Vue({ 23 el:'#app', 24 data:{ 25 total:0 26 }, 27 methods:{ 28 incrementTotal:function(){ 29 this.total += 1; 30 } 31 } 32 })
解讀:
使用Slots分發內容
內容分發指的是混合父組件的內容與子組件本身的模板;
1 <div id="app"> 2 <h1>I'm the parent title</h1> 3 <my-component> 4 <p>This is some original content</p> 5 <p>This is some more original content</p> 6 </my-component> 7 <hr> 8 </div> 9 --- 10 Vue.component('my-component',{ 11 template:"<div><h2>I'm the child title</h2><slot>若是沒有分發內容則顯示我。</slot></div>" 12 }) 13 var app = new Vue({ 14 el:'#app', 15 data:{ 16 }. 17 })
解讀:
1 //子組件app-layout模板 2 <div class="container"> 3 <header> 4 <slot name="header"></slot> 5 </header> 6 <main> 7 <slot></slot> 8 </main> 9 <footer> 10 <slot name="footer"></slot> 11 </footer> 12 </div> 13 //父組件模板 14 <app-layout> 15 <h1 slot="header">Here might be a page title</h1> 16 17 <p>A paragraph for the main content.</p> 18 <p>And another one.</p> 19 20 <p slot="footer">Here's some contact info</p> 21 </app-layout> 22 //渲染結果 23 <div class="container"> 24 <header> 25 <h1>Here might be a page title</h1> 26 </header> 27 <main> 28 <p>A paragraph for the main content.</p> 29 <p>And another one.</p> 30 </main> 31 <footer> 32 <p>Here's some contact info</p> 33 </footer> 34 </div>
解讀:
【TIP】關於組件的命名規範
1 // 在組件定義中 2 components: { 3 // 使用 camelCase 形式註冊 4 'kebab-cased-component': { /* ... */ }, 5 'camelCasedComponent': { /* ... */ }, 6 'TitleCasedComponent': { /* ... */ } 7 }
1 <kebab-cased-component></kebab-cased-component> 2 <camel-cased-component></camel-cased-component> 3 <title-cased-component></title-cased-component>
2.10 vue-resource插件
使用vue-rescource實現先後端的通訊
在vue實例中新增ready對象,當頁面完成加載時發出請求
1 new Vue({ 2 el: '#app', 3 ready: function() { 4 this.$http.get('book.json', function(data) { 5 this.$set('books', data); 6 }).error(function(data, status, request) { 7 console.log('fail' + status + "," + request); 8 }) 9 //post方法:this.$http.post(url,postdata,function callback) 10 }, 11 data: { 12 .... 13 books:'' 14 }, 15 .....
【TIP】
這個$http請求和jquery的ajax仍是有點區別,這裏的post的data默認不是以form data的形式,而是request payload。解決起來也很簡單:在vue實例中添加headers字段:
http: { headers: {'Content-Type': 'application/x-www-form-urlencoded'} }
上面的Vue小做品是小羊仿照SegmentFault的一篇技博的練手之做,建議各位對照源碼親手練習一次,以便初步熟悉Vue的使用;
【注】版權歸Teren全部,轉載請聯繫做者。
參考資料: