本文是小羊根據(jù)Vue.js文檔進(jìn)行解讀的第一篇文章,主要內(nèi)容涵蓋Vue.js的基礎(chǔ)部分的知識(shí)的,文章順序基本按照官方文檔的順序,每個(gè)知識(shí)點(diǎn)現(xiàn)附上代碼,然后根據(jù)代碼給予個(gè)人的一些理解,最后還放上在線編輯的代碼以供練習(xí)和測(cè)試之用;
在最后,我參考SegmentFault上的一篇技博,對(duì)Vue進(jìn)行初入的實(shí)戰(zhàn),目的是將新鮮學(xué)到的知識(shí)立即派上用場(chǎng);
如果你還是前端的小白,相信這篇文章可能會(huì)對(duì)產(chǎn)生一些幫助和引起思想的碰撞,因?yàn)榇蠹业膶W(xué)習(xí)歷程是相似的,遇到的困惑也有一定的共通性,如果文章出現(xiàn)謬誤之處,歡迎各位童鞋及時(shí)指正;

1. Vue.js是什么
Vue.js(讀音 /vju?/, 類似于 view) 是一套構(gòu)建用戶界面的 漸進(jìn)式框架。與其他重量級(jí)框架不同的是Vue 的核心庫(kù)只關(guān)注視圖層。
Vue.js 的目標(biāo)是通過(guò)盡可能簡(jiǎn)單的 API 實(shí)現(xiàn)響應(yīng)的數(shù)據(jù)綁定和組合的視圖組件。
Vue.js是一種MVVM框架,其中html是view層,js是model層,通過(guò)vue.js(使用v-model這個(gè)指令)完成中間的底層邏輯,實(shí)現(xiàn)綁定的效果。改變其中的任何一層,另外一層都會(huì)改變;

2.Vue的基本語(yǔ)法
2.1 Vue構(gòu)造函數(shù)開啟Vue之旅
通過(guò)構(gòu)造函數(shù)Vue創(chuàng)建一個(gè)Vue的根實(shí)例
<div id='#el'></div>
---
var vm = new Vue({
//options
el:'#el',
data:{},
methods:{}
})
---
//擴(kuò)展Vue構(gòu)造器
var MyComponent = Vue.extend({
//擴(kuò)展選項(xiàng)
})
var vm = new MyComponent({})
解讀:
- 使用Vue構(gòu)造函數(shù)創(chuàng)建一個(gè)Vue實(shí)例,然后通過(guò)Vue實(shí)例的
el接口實(shí)現(xiàn)和HTML元素的掛載; - 構(gòu)造函數(shù)Vue需要傳入一個(gè)選項(xiàng)對(duì)象,可包含掛載元素、數(shù)據(jù)、方法和生命周期鉤子等;
- 構(gòu)造函數(shù)Vue可以通過(guò)
extend方法實(shí)現(xiàn)擴(kuò)展,從而可以用預(yù)定義的選項(xiàng)創(chuàng)建可復(fù)用的組件構(gòu)造函數(shù),但是構(gòu)建組件的常用方法是使用Vue.component()接口去實(shí)現(xiàn);
2.2 Vue實(shí)例的屬性和方法
Vue實(shí)例將代理data對(duì)象的所有屬性,也就是說(shuō)部署在data對(duì)象上的所有屬性和方法都將直接成為Vue實(shí)例的屬性和方法
<div id="app">{{message}}
<button v-on:click="sayHello">click me</button>
</div>
---
var app = new Vue({
el:'#app',
data:{
message:'hello world!',
sayHello:function(){
console.log(1)
}
}
})
---
//如果想要獲取到app這一實(shí)例中選項(xiàng)的對(duì)象,Vue提供$進(jìn)行獲取
app.$el === document.getElementById('app')//true
app.$data.message//hello world
【TIP】
Vue實(shí)例所代理data對(duì)象上的屬性只有在實(shí)例創(chuàng)建的同時(shí)進(jìn)行初始化才具有響應(yīng)式更新,若在實(shí)例創(chuàng)建之后添加是不會(huì)觸發(fā)視圖更新的;
2.3數(shù)據(jù)綁定操作
綁定文本和HTML
<div id = "app">
{{msg}}
<div v-html="hi"></div>
</div>
---
var app = new Vue({
el: '#app',
data:{
msg: 'hello world!',
hi:'<h1>hi</h1>'
}
})
解讀:
- HTML部分實(shí)現(xiàn)數(shù)據(jù)的動(dòng)態(tài)綁定,這個(gè)數(shù)據(jù)是vue實(shí)例的屬性值;
- JS部分的語(yǔ)法可以從jQuery角度去理解,相當(dāng)于創(chuàng)建一個(gè)Vue實(shí)例,這個(gè)實(shí)例指向#app,并在Vue提供的固定接口data上定義Vue實(shí)例的屬性;
- 使用
{{message}}的mustache語(yǔ)法只能將數(shù)據(jù)解釋為純文本,為了輸出HTML,可以使用v-html指令;
綁定數(shù)據(jù)在元素的屬性
<div id="app" v-bind:title='message' v-bind:style='red' v-once>
{{message}}
</div>
---
var app = new Vue({
el: '#app',
data:{
message: 'hello world!',
red: 'color:red'
}
})
解讀:
- 定義在Vue實(shí)例的data接口上的數(shù)據(jù)的綁定靈活的,可以綁定在DOM節(jié)點(diǎn)內(nèi)部,也可以綁在屬性上;
- 綁定數(shù)據(jù)到節(jié)點(diǎn)屬性上時(shí),需要使用
v-bind指令,這個(gè)元素節(jié)點(diǎn)的 title屬性和 Vue 實(shí)例的 message屬性綁定到一起,從而建立數(shù)據(jù)與該屬性值的綁定,也可以使用v-bind:href="url"的縮寫方式:href="url"; -
v-once指令能夠讓你執(zhí)行一次性的插值,當(dāng)數(shù)據(jù)改變時(shí),插值處的內(nèi)容不會(huì)更新;
【demo】
使用JS表達(dá)式處理數(shù)據(jù)
<div id='#app'>
<p v-once>{{num + 10 }}</p>
<p v-if='seen'>{{message + 'jirengu'}}</p>
</div>
---
var app = new Vue({
el: '#app',
data:{
num:10,
message: 'hello world!',
seen:true
}
})
使用過(guò)濾器來(lái)格式化數(shù)據(jù)
<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元素的顯示操作
<div id="app" >
<p v-if='seen'>{{message}}</p>
</div>
---
var app = new Vue({
el: '#app',
data:{
message: 'hello world!',
seen:true
}
})
解讀:
-
v-if指令可以綁定一個(gè)屬性值為布爾型的屬性,當(dāng)值為真時(shí),元素將顯示,反之則消失;
循環(huán)指令實(shí)現(xiàn)數(shù)據(jù)的遍歷
<div id="app">
<ol>
<li v-for='item in items'>
{{ item.text }}
</li>
</ol>
</div>
---
var app = new Vue({
el: '#app',
data:{
items:[
{text:'Vue'},
{text:'React'},
{text:'Angular'}
]
}
})
解讀:
-
v-for可以綁定數(shù)組型數(shù)據(jù)進(jìn)行綁定,并使用item in items形式,從而數(shù)據(jù)的遍歷操作;
事件綁定指令可以實(shí)現(xiàn)事件監(jiān)聽
<div id='app'>
<p>{{message}}</p>
<button v-on:click='reverseMessage'>reverseMesssage</button>
</div>
---
var app = new Vue({
el: '#app',
data:{
message: 'hello world!'
},
methods:{
reverseMessage:function(){
this.message = this.message.split('').reverse().join('')
}
}
})
解讀:
-
v-on指令用于監(jiān)聽事件操作,click="reverseMessage"定義點(diǎn)擊事件后執(zhí)行的回調(diào)函數(shù); -
v-on指令也可以采用縮寫方式:@click="method" - 在Vue實(shí)例中,提供methods接口用于統(tǒng)一定義函數(shù);
小結(jié)
本章涉及Vue的基礎(chǔ)的數(shù)據(jù)綁定操作,內(nèi)容包括:
-
{{message}}實(shí)現(xiàn)文本數(shù)據(jù)的綁定,并且文本數(shù)據(jù)可以使用JS表達(dá)式和過(guò)濾器進(jìn)行進(jìn)一步處理;
-v-html="hi"實(shí)現(xiàn)HTML數(shù)據(jù)的綁定; -
v-bind:href="url"實(shí)現(xiàn)屬性數(shù)據(jù)的綁定; -
v-if="seen"和v-for="item in items"指令實(shí)現(xiàn)流程控制; -
v-on:click="method"指令實(shí)現(xiàn)事件監(jiān)聽
2.4計(jì)算屬性
使用計(jì)算屬性完成一些數(shù)據(jù)計(jì)算操作
<div id="app" >
<p>Original message : {{message}}</p>
<p>Reversed message : {{ReversedMessage}}</p>
</div>
---
var app = new Vue({
el: '#app',
data:{
message: 'hello world!',
},
computed:{
ReversedMessage:function(){
return this.message.split('').reverse().join('')
}
}
})
解讀:
- Vue實(shí)例提供
computed對(duì)象,我們可以在對(duì)象內(nèi)部定義需要進(jìn)行計(jì)算的屬性ReverseMessage,而提供的函數(shù)將作為屬性的getter,即獲取器; - 上述的代碼使得
app.ReverseMessage依賴于app.message; - 與先前直接在
{{message.split('').reverse().join('') }}使用表達(dá)式相比,它讓模板過(guò)重并且難以維護(hù)代碼;
計(jì)算屬性 VS Methods
<div id="app" >
<p>Original message : {{message}}</p>
<p>Reversed message : {{ReversedMessage}}</p>
<p>Reversed message:{{reversedMessage()}}</p>
</div>
---
var app = new Vue({
el: '#app',
data:{
message: 'hello world!',
},
computed:{
ReversedMessage:function(){
return this.message.split('').reverse().join('')
}
},
methods:{
reversedMessage:function(){
return this.message.split('').reverse().join('')
}
}
})
解讀:
- 通過(guò)Vue實(shí)例的methods接口,我們?cè)谀0逯姓{(diào)用
reversedMessage函數(shù)同樣實(shí)現(xiàn)需求; - methods與computed方法的區(qū)別在于:computed的數(shù)據(jù)依賴于
app.message,只要message未變,則訪問(wèn)ReverseMessage計(jì)算屬性將立即返回之前的計(jì)算結(jié)果,而methods則每次重新渲染時(shí)總是執(zhí)行函數(shù); - 如果有緩存需要,請(qǐng)使用computed方法,否則使用methods替代;
計(jì)算屬性的setter
Vue實(shí)例的computed對(duì)象默認(rèn)只有g(shù)etter,如果你要設(shè)置數(shù)據(jù),可以提供一個(gè)setter,即設(shè)置器;
<div id="app" >
<p>Hi,I'm{{fullName}}</p>
</div>
---
var app = new Vue({
el: '#app',
data:{
message: 'hello world!',
name:'Teren'
},
computed:{
fullName:{
get:function(){
return this.name
},
set:function(value){
this.name = value
}
}
}
})
2.5Class與Style的綁定
綁定Class
<div id="app" >
<!-- 直接綁定對(duì)象的內(nèi)容 -->
<p class='static' v-bind:class="{active:isActive,error:hasError}">Hello world!</p>
<!-- 綁定對(duì)象 -->
<p v-bind:class="classObj">こんにちは </p>
<p v-bind:class='style' >你好</p>
<!-- 綁定數(shù)組 -->
<p v-bind:class="[staticClass,activeClass,errorClass]">
Olá</p>
<button @click='changeColor'>click me</button>
</div>
---
//css
.static{
width: 200px;
height: 100px;
background: #ccc;
}
.active{
color:red;
}
.error{
font-weight: 800;
}
---
var app = new Vue({
el: '#app',
data:{
isActive:true,
hasError:true,
classObj:{
static:true,
active:true,
error:true,
},
staticClass:'static',
activeClass:'active',
errorClass:'error',
},
computed:{
style:function(){
return {
active: this.isActive,
static:true,
error:this.hasError
}
}
},
methods:{
changeColor:function(){
this.isActive = !this.isActive
}
}
})
解讀:
- 通過(guò)
v-bind:class="{}"或v-bind:class=[]方式為模板綁定class - 通過(guò)
v-bind:class="{active:isActive,error:hasError}"綁定class,首先要在css中設(shè)置.active和,error,然后在Vue實(shí)例的data對(duì)象中設(shè)置isActive和hasError的布爾值;也可以直接傳一個(gè)對(duì)象給class,即v-bind:class="classObj,再在data對(duì)象上直接賦值:
data:{
classObj:{
static:true,
active:true,
error:true,
}
- 你也可以通過(guò)傳遞數(shù)組的方式為class賦值
v-bind:class="[staticClass,activeClass,errorClass]",此時(shí)你要在data對(duì)象上為數(shù)組的元素的屬性賦值:
data:{
staticClass:'static',
activeClass:'active',
errorClass:'error',
}
【TIP】無(wú)論是哪種方式,前提都是css中的class要先設(shè)定
綁定style
<div id="app" >
<p v-bind:style='styleObj'>Hello World!</p>
<p v-bind:style='[styleObj,bgObj]'>你好</p>
</div>
---
var app = new Vue({
el: '#app',
data:{
styleObj:{
fontWeight:800,
color:'red'
},
bgObj:{
width:'100px',
height:'80px',
background:'#ccc'
}
},
})
解讀:
- 綁定style到模板的方法有兩種,一是
v-bind:style="styleObj",然后在data對(duì)象上定義styleObj;而是可以通過(guò)數(shù)組方式為style傳入多個(gè)樣式對(duì)象
2.6條件渲染和列表渲染
前面簡(jiǎn)單介紹了一下v-if、v-for和v-on指令,下面的部分將詳細(xì)介紹以上3個(gè)指令;
條件渲染
<div id="app" >
<p v-if='ok'>Hello World!</p>
<p v-else>Hello Universal</p>
<template v-if='motto'>
<h1>Steve Jobs</h1>
<p>motto:stay hungry ! stay foolish</p>
</template>
<p v-show='ok'>Show Me</p>
</div>
---
var app = new Vue({
el: '#app',
data:{
ok:true,
motto:true,
},
})
解讀:
- 通過(guò)
v-if和v-else指令實(shí)現(xiàn)條件渲染,其中v-if="value"的valuey
要在data對(duì)象中賦布爾值,v-if支持<template>語(yǔ)法 -
v-show="value"是另一種條件渲染的方法;
【TIP】 v-if和v-show的區(qū)別
- v-if是真實(shí)的條件渲染,當(dāng)進(jìn)行條件切換時(shí),它會(huì)銷毀和重建條件塊的內(nèi)容,并且它支持
<template>語(yǔ)法; - v-show的條件切換時(shí)基于css的display屬性,所以不會(huì)銷毀和重建條件塊的內(nèi)容;
- 當(dāng)你頻繁需要切換條件時(shí),推薦使用v-show;否則使用v-if;
列表渲染
<div id="app" >
<ol>
<li v-for='car in cars'>
{{car.name}}
</li>
</ol>
<ul>
<li v-for='(food,index) in foods'>
{{index}}---{{food}}---{{delicious}}
</li>
</ul>
<ul>
<li v-for='(value,key,index) in object'>
{{index}}.{{key}}.{{value}}
</li>
</ul>
<div>
<span v-for='n in 10' style="margin-left:5px">{{n}}</span>
</div>
<span v-for='n in evenNumbers' style="margin-left:5px">{{n}}</span>
</div>
<!-- <div>
<span v-for='n in odd(counts)' style="margin-left:5px">{{n}}</span>
</div> -->
</div>
---
var app = new Vue({
el: '#app',
data:{
delicious:'delicious',
cars:[
{name:'Benz'},
{name:'BMW'}
],
foods:[
'tomato',
'potato',
'ice cream'
],
object :{
name:'Benz',
age:'18'
},
numbers:[1,2,3,4,5,6,7,8,9,10],
counts:[1,2,3,4,5]
},
computed:{
evenNumbers:function(){
return this.numbers.filter(function(number){
return number%2 === 0
})
}
},
methods:{
odd:function(counts){
return counts.filter(function(count){
return count%2 === 1;
})
}
}
})
解讀:
-
v-for指令能夠讓我們循環(huán)渲染列表型數(shù)據(jù),數(shù)據(jù)放在data對(duì)象中,類型可以如下:
data:{
//數(shù)字?jǐn)?shù)組
numbers:[1,2,3,4,5,6,7,8,9,10],
counts:[1,2,3,4,5]
//字符串?dāng)?shù)組
foods:[
'tomato',
'potato',
'ice cream'
],
//對(duì)象數(shù)組
cars:[
{name:'Benz'},
{name:'BMW'}
],
//對(duì)象
object :{
name:'Benz',
age:'18'
},
}
- 根據(jù)不同類型的數(shù)據(jù),
v-for指令在模板中具體采用的語(yǔ)法如下:
//數(shù)據(jù)為數(shù)字?jǐn)?shù)組
<div>
<span v-for="n in numbers">{{n}}</span>
</div>
---
//數(shù)據(jù)為字符數(shù)組
<ul>
<ol v-for='food in foods'>{{food}}</ol>
</ul>
---
//數(shù)據(jù)為對(duì)象
<ul>
<ol v-for="value in object">{{value}}</ol>
</ul>
//或者
<ul>
<ol v-for="(value,key,index) in object">{{index}}.{{key}}.{{value}}</ol>
</ul>
---
//數(shù)據(jù)為對(duì)象數(shù)組
<ul>
<ol v-for="car in cars">{{car.name}}</ol>
</ul>
- 在 v-for塊中,我們擁有對(duì)父作用域?qū)傩缘耐耆L問(wèn)權(quán)限;
2.7 事件監(jiān)聽
簡(jiǎn)單的事件監(jiān)聽——直接在指令上處理數(shù)據(jù)
<div id="#app">
<p v-on:click="counter+=1">{{counter}}</p>
</div>
---
var app = new Vue({
el: "#app",
data:{
counter: 0,
}
})
復(fù)雜的事件監(jiān)聽——在methods對(duì)象定義回調(diào)函數(shù)
<div id="#app">
<p v-on:click="greet">{{vue}</p>
</div>
---
var app = new Vue({
el: "#app",
data:{
vue:"hello Vue.js"
},
methods:{
greet:function(event){
console.log(this.vue)
}
}
})
事件修飾符——調(diào)用事件對(duì)象函數(shù)的快捷方式
<div v-on:click.prevent="greet">1</div>//等價(jià)于event.preventDefault()
<div v-on:click.stop="greet">2</div>//等價(jià)于event.stopPropagation()
<div v-on:click.capture="greet">3</div>//等價(jià)于事件回調(diào)函數(shù)采用捕獲階段監(jiān)聽事件
<div v-on:click.self="greet">4</div>//等價(jià)于event.target
按鍵修飾符——按鍵事件的快捷方式
常見按鍵別名包括:
- enter
- tab
- delete
- esc
- space
- up
- down
- left
- right
2.8 表單控件綁定
文本控件
<div id="app">
<p>{{message}}</p>
<input type="text" v-model='message'>
</div>
---
var app = new Vue({
el:'#app',
data:{
message:'Hello World!'
},
})
解讀:
- 通過(guò)
v-model指令可以實(shí)現(xiàn)數(shù)據(jù)的雙向綁定,即View層的數(shù)據(jù)變化可以直接改變Model層的數(shù)據(jù),而Model層的數(shù)據(jù)改變也可以直接反映在View層; - 上述代碼
v-model="message"使得input的value屬性和message屬性綁定,在輸入框輸入值,即改變value同時(shí)也改變message;
單選控件
<input id="man" value="man" type="radio" v-model='picked'>
<label for="man">Man</label>
<br>
<input id="woman" value="woman" type="radio" v-model='picked'>
<label for="woman">Woman</label>
<div style="margin-left:10px">{{picked}}</div>
---
var app = new Vue({
el:'#app',
data:{
message:'Hello World!',
picked:'man'
},
})
解讀:
-
v-model指令綁定data對(duì)象的picked屬性,該屬性默認(rèn)指向type='radio'的input的value;
復(fù)選框
<input type="checkbox" id="Benz" v-model='checked' value='Benz'>
<label for="Benz">Benz</label>
<input type="checkbox" id="BMW" v-model='checked' value="BMW">
<label for="BMW">BMW</label>
<div>Checked Name:{{checked}}</div>
---
var app = new Vue({
el:'#app',
data:{
message:'Hello World!',
picked:'man',
selected:"A",
checked:[],
},
})
2.9 組件
組件可以擴(kuò)展 HTML 元素,封裝可重用的代碼。在較高層面上,組件是自定義元素;
通過(guò)Vue.component()接口將大型應(yīng)用拆分為各個(gè)組件,從而使代碼更好具有維護(hù)性、復(fù)用性以及可讀性
注冊(cè)組件
<div id="app">
<my-component></my-component>
</div>
---
Vue.component('my-component',{
template:'<div>my-first-component</div>'
})
var app = new Vue({
el:'#app',
data:{
}
})
解讀:
- 注冊(cè)行為必須在創(chuàng)建實(shí)例之前;
- component的template接口定義組件的html元素;
局部注冊(cè)組件
<div id="app">
<my-component>
<heading></heading>
</my-component>
</div>
---
Vue.component('my-component',{
template:'<div>my-first-component</div>'
})
var Child = {
template: '<h3>Hello World</h3>'
}
var app = new Vue({
el:'#app',
components:{
'my-component':Child
}
})
解讀:
- 可以定義一個(gè)子組件,在實(shí)例的
components接口中將子組件掛載到父組件上,子組件只在父組件的作用域下有效;
特殊DOM模板將會(huì)限制組件的渲染
像這些包含固定樣式的元素<ul>, <ol>, <table>, <select>,
自定義組件中使用這些受限制的元素時(shí)會(huì)導(dǎo)致渲染失敗;
通的方案是使用特殊的 is屬性:
<table>
<tr is="my-component">
</table>
創(chuàng)建組件的data對(duì)象必須是函數(shù)
<counter></counter>
<counter></counter>
<counter></counter>
---
Vue.component('counter',{
template:'<button @click="count+=1">{{count}}</button>',
data:function(){
return {
count: 0
}
}
})
解讀:
- 在組件當(dāng)中定義的數(shù)據(jù)
count必須以函數(shù)的形式返回;
使用Props實(shí)現(xiàn)父組件向子組件傳遞數(shù)據(jù)
<child some-text='hello'></child>
<br>
<child v-bind:some-text='message'> </child>
---
Vue.component('child',{
template:'<div>{{someText}}</div>',
props:['someText']
})
var app = new Vue({
el:'#app',
components:{
'my-component':Child
},
data:{
message:"你好"
}
})
解讀:
組件實(shí)例的作用域是孤立的。這意味著不能并且不應(yīng)該在子組件的模板內(nèi)直接引用父組件的數(shù)據(jù)??梢允褂?props 把數(shù)據(jù)傳給子組件;
可以用 v-bind動(dòng)態(tài)綁定 props 的值到父組件的數(shù)據(jù)中。每當(dāng)父組件的數(shù)據(jù)變化時(shí),該變化也會(huì)傳導(dǎo)給子組件,注意這種綁定方式是單向綁定;
父組件是使用 props 傳遞數(shù)據(jù)給子組件,但如果子組件要把數(shù)據(jù)傳遞回去則使用自定義事件!
<div id="app">
<p>{{total}}</p>
<button-counter v-on:increment='incrementTotal'></button-counter>
<button-counter @increment='incrementTotal'></button-counter>
</div>
---
Vue.component('button-counter',{
template:'<button v-on:click="increment">{{counter}}</button>',
data:function(){
return {
counter:0
}
},
methods:{
increment:function(){
this.counter +=1;
this.$emit('increment')
}
}
})
var app = new Vue({
el:'#app',
data:{
total:0
},
methods:{
incrementTotal:function(){
this.total += 1;
}
}
})
解讀:
- 父組件可以通過(guò)監(jiān)聽子組件的自定義事件,從而改變父組件的數(shù)據(jù);
- 子組件每點(diǎn)擊一次,觸發(fā)increment函數(shù),該函數(shù)在執(zhí)行過(guò)程中通過(guò)
$emit('increment')發(fā)出increment事件; -
button控件同時(shí)監(jiān)聽increment事件,每次發(fā)出該事件就改變父組件的total值;
【demo】
使用Slots分發(fā)內(nèi)容
內(nèi)容分發(fā)指的是混合父組件的內(nèi)容與子組件自己的模板;
<div id="app">
<h1>I'm the parent title</h1>
<my-component>
<p>This is some original content</p>
<p>This is some more original content</p>
</my-component>
<hr>
</div>
---
Vue.component('my-component',{
template:"<div><h2>I'm the child title</h2><slot>如果沒(méi)有分發(fā)內(nèi)容則顯示我。</slot></div>"
})
var app = new Vue({
el:'#app',
data:{
}.
})
解讀:
- 如果子組件模板一個(gè)
<slot>都不包含,則父組件內(nèi)容將會(huì)被丟棄; - 當(dāng)子組件模板只有一個(gè)沒(méi)有屬性的 slot 時(shí),父組件整個(gè)內(nèi)容片段將插入到 slot 所在的 DOM 位置,并替換掉 slot 標(biāo)簽本身;
- 只有在宿主元素為空,且沒(méi)有要插入的內(nèi)容時(shí)才顯示備用內(nèi)容;
//子組件app-layout模板
<div class="container">
<header>
<slot name="header"></slot>
</header>
<main>
<slot></slot>
</main>
<footer>
<slot name="footer"></slot>
</footer>
</div>
//父組件模板
<app-layout>
<h1 slot="header">Here might be a page title</h1>
<p>A paragraph for the main content.</p>
<p>And another one.</p>
<p slot="footer">Here's some contact info</p>
</app-layout>
//渲染結(jié)果
<div class="container">
<header>
<h1>Here might be a page title</h1>
</header>
<main>
<p>A paragraph for the main content.</p>
<p>And another one.</p>
</main>
<footer>
<p>Here's some contact info</p>
</footer>
</div>
解讀:
- 具名
slot相當(dāng)于給slot設(shè)置標(biāo)識(shí)符,只要在父組件的元素上設(shè)置<div slot="name"></div>就可以把該元素插入子組件定義的模板;
【TIP】關(guān)于組件的命名規(guī)范
- 當(dāng)注冊(cè)組件(或者 props)時(shí),可以使用 kebab-case ,camelCase ,或 TitleCase
// 在組件定義中
components: {
// 使用 camelCase 形式注冊(cè)
'kebab-cased-component': { /* ... */ },
'camelCasedComponent': { /* ... */ },
'TitleCasedComponent': { /* ... */ }
}
- 在 HTML 模版中,請(qǐng)使用 kebab-case 形式:
<kebab-cased-component></kebab-cased-component>
<camel-cased-component></camel-cased-component>
<title-cased-component></title-cased-component>
- 為了記憶方便,建議統(tǒng)一使用kebab-case形式;
2.10 vue-resource插件
使用vue-rescource實(shí)現(xiàn)前后端的通信
在vue實(shí)例中新增ready對(duì)象,當(dāng)頁(yè)面完成加載時(shí)發(fā)出請(qǐng)求
new Vue({
el: '#app',
ready: function() {
this.$http.get('book.json', function(data) {
this.$set('books', data);
}).error(function(data, status, request) {
console.log('fail' + status + "," + request);
})
//post方法:this.$http.post(url,postdata,function callback)
},
data: {
....
books:''
},
.....
【TIP】
這個(gè)$http請(qǐng)求和jquery的ajax還是有點(diǎn)區(qū)別,這里的post的data默認(rèn)不是以form data的形式,而是request payload。解決起來(lái)也很簡(jiǎn)單:在vue實(shí)例中添加headers字段:
http: { headers: {'Content-Type': 'application/x-www-form-urlencoded'} }
3. 實(shí)戰(zhàn)之Vue小作品

上面的Vue小作品是小羊仿照SegmentFault的一篇技博的練手之作,建議各位對(duì)照源碼親手練習(xí)一次,以便初步熟悉Vue的使用;
【注】版權(quán)歸犯迷糊的小羊所有,轉(zhuǎn)載請(qǐng)聯(lián)系作者。
參考資料: