版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)
文檔簡介
第5章-Vue.js組件開發(fā)(4學時)教學目標熟悉組件的命名規(guī)范。掌握全局、局部注冊組件的方法。掌握組件間常用的通信方法。掌握插槽的分類和定義方法。15.1組件基礎(chǔ)
組件(Component)是Vue.js最強大的功能之一。組件可以擴展HTML元素,封裝可重用的代碼。組件也可以看作為自定義的HTML元素??梢允褂锚毩⒖蓮陀玫男〗M件來構(gòu)建大型應用,幾乎任意類型的應用的界面都可以抽象為一個組件樹,如圖所示。5.1.1組件命名
組件注冊前必須給組件命名,組件名應該采用多個單詞構(gòu)成,以免與現(xiàn)有的或未來的HTML元素有沖突。由于所有的HTML元素名稱都是由單個單詞構(gòu)成。Vue組件中通常采用kebab-case(短橫線分隔式)或camelCase(駝峰式)命名方式。(1)kebab-case-命名法
當使用kebab-case定義一個組件時,必須在引用自定義元素時使用kebab-case命名方式。Vueprops命名最好直接使用kebab-case命名。例如my-name、my-component-name等。(2)camelCase命名法
camelCase(也稱為駝峰式)命名法就是當組件名稱是由一個或多個單詞構(gòu)成時,第一個單詞首字母以小寫字母開始,從第二個單詞開始以后的每個單詞的首字母都采用大寫字母。例如:myFirstName、myLastName、myComponent。注意,盡管如此,直接在DOM(即非字符串的模板)中使用時,只有kebab-case是有效的。(3)PascalCase(帕斯卡命名)
與camelCase相比,PascalCase命名時,第一個單詞的首字母是大寫的;但camelCase命名時,第一個單詞的首字母小寫。當使用PascalCase命名法定義一個組件時,在引用自定義元素時兩種命名法都可以使用。也就是說<my-component-name>和<MyComponentName>都是可接受的。
因為HTML不區(qū)分大小寫,所以不管是用Kebab-case還是camelCase命名的組件在寫入HTML后都要改寫為Kebab-case格式。5.1組件基礎(chǔ)5.1組件基礎(chǔ)組件命名基本語法//在組件定義中components:{//使用kebab-case注冊'kebab-cased-component':{/*...*/},//使用camelCase注冊'camelCaseComponent':{/*...*/},//使用PascalCase注冊'PascalCasedComponent':{/*...*/}}在HTML模板中,請使用kebab-case:<!--在HTML模板中始終使用kebab-case--><kebab-cased-component></kebab-cased-component><camel-cased-component></camel-cased-component><pascal-cased-component></pascal-cased-component>//組件中定義components:{'kebab-cased-component':{/*...*/},'camelCaseComponent':{/*...*/},'PascalCasedComponent':{/*...*/}}//在字符串模板中,可以采用以下格式引用constapp=Vue.createApp({});ponent('MyCom',{template:`<div><kebab-cased-component></kebab-cased-component><camel-cased-component></camel-cased-component><camelCaseComponent></camelCaseComponent><pascal-cased-component></pascal-cased-component><pascalCasedComponent></pascalCasedComponent><PascalCasedComponent></PascalCasedComponent></div>`})5.1.2組件注冊
組件注冊通常分為全局注冊和局部注冊。全局組件適用于所有實例,局部組件僅供本實例使用。1.全局注冊組件的定義【基本語法】//全局組件注冊constapp=Vue.createApp({})ponent(tagName,options)//直接定義選項
ponent('myComponet',{//data必須定義為函數(shù),并通過return返回相關(guān)數(shù)據(jù)template:'HTML元素定義'})//也可以鏈式注冊全局組件app.component('ComponentA',ComponentA).component('ComponentB',ComponentB).component('ComponentC',ComponentC)
一個組件的data選項必須是一個函數(shù),因此每個實例可以維護一份被返回對象的獨立的拷貝。
與Vue實例中data選項的定義方法不同。在組件中定義data選項時,必須定義為函數(shù),其中的數(shù)據(jù)通過return返回。具體格式如下:data:function(){return{//定義相關(guān)數(shù)據(jù)屬性}}data(){return{}}//同樣生效。
注冊后,可以調(diào)用組件。調(diào)用方式如下:<tagName></tagName>
在Vue實例中,必須通過components選項來定義自己的組件。也可以使用普通的JavaScript對象來定義組件,然后在全局注冊和局部注冊時直接引用?!净菊Z法】constcomponentA={template:'<h1>h1-Js自定義局部組件-A組件</h1>'};//創(chuàng)建Vue實例const{createApp}=Vue;constApp={//定義根組件components:{//局部注冊子組件mycomp1:componentA, mycomp2:tmp1}}) createApp(App).mount('#app');//也可以采用以下方法createApp({components:{mycomp1:componentA, mycomp2:tmp1}}).mount('#app');2.局部注冊組件的定義【語法說明】
局部注冊時,需要在components選項下注冊組件,mycomp1、mycomp2為組件名,componentA組件對應的JS對象或選項對象。在Vue里,一個組件本質(zhì)上是一個擁有預定義選項的一個Vue實例,在Vue中注冊組件非常簡單?!纠?-1】組件注冊實戰(zhàn)<divid="app">
<fieldset>
<legend>定義全局組件與復用</legend>
<my-com></my-com>
<my-com></my-com>
<my-com></my-com>
</fieldset>
<fieldset>
<legend>定義全局組件</legend>
<mycomp2></mycomp2>
</fieldset>
<fieldset>
<legend>定義局部組件</legend>
<mycomp1></mycomp1>
</fieldset>
</div>
<scripttype="text/javascript">
const{createApp}=Vue;//解構(gòu)賦值createApp
//定義JS對象componentA
varcomponentA={
template:"<h1>h1-Js自定義局部組件-A組件</h1>",
};//定義JS對象componentB
varcomponentB={
data(){
return{title:"我自己定義的標題信息!"
};
},
template:`
<div>
<p>多個HTML元素時,使用根元素div</p>
<h3v-bind:title="title">h3-Js自定義全局組件-B組件,盤旋會有提示</h3>
</div>`,
};【例5-1】組件注冊實戰(zhàn)//局部注冊組件mycomp1
constApp={
components:{mycomp1:componentA},
};
constapp1=createApp(App);
//全局注冊組件my-com,定義1個計算器的按鈕
ponent("my-com",{
data(){return{count:0};
},
template:'<buttonv-on:click="count++">單擊{{count}}次按鈕</button>',
});
//通過JavaScript對象componentB來定義mybutton2組件
ponent("mycomp2",componentB);
//定義App組件,并在根組件中注冊子組件mybutton1
app1.mount("#app");//掛載
</script>5.2組件間通信
在Vue中,父子組件的關(guān)系可以總結(jié)為“props向下傳遞,事件向上傳遞”。父組件通過props給子組件下發(fā)數(shù)據(jù),子組件通過事件給父組件發(fā)送消息,如圖5-3所示。子組件需要顯式地用defineProps()函數(shù)聲明props。props的值可以是兩種:一種是字符串數(shù)組,一種是對象。1.使用props傳遞數(shù)據(jù)【基本語法】<!--HTML模板部分--><divid="app"><my-componentmessage="父組件通過props傳遞參數(shù)"></my-component></div><!--JS部分--><scripttype="text/javascript">constapp=Vue.createApp({});//組件定義ponent('my-component',{props:['message'],template:'<div>{{message}}</div>'});App.mount('#app');</script>5.2.1父組件向子組件傳值【語法說明】<my-component></my-component>為自定義組件,采用kebab-case格式命名,相當于一個HTML元素。message為組件的屬性,其值作為傳遞給子組件的內(nèi)容。props屬性為字符串數(shù)組(用[]包圍),其中的屬性必須使用引號('message')包圍,可以在模板通過文本插值的方式來使用。此種父子組件通信是單向的。組件中的數(shù)據(jù)共有3種形式:data、props、computed。注意:組件中data與props屬性的區(qū)別。
組件中data和props都可以為組件提供數(shù)據(jù),但它們是有區(qū)別的。data選項的類型為對象類型,對象中return出去的數(shù)據(jù)屬于組件內(nèi)部數(shù)據(jù),只能用于為組件本身。props選項的類型可以是字符串數(shù)組,也可以是對象。用來聲明組件從外部接收的數(shù)據(jù)。此兩種數(shù)據(jù)都可以在template模板、計算屬性computed和方法methods中使用。5.2.1父組件向子組件傳值5.2.1父組件向子組件傳值-2組件中使用props接收父組件message屬性傳遞過來的數(shù)據(jù)。2.靜態(tài)props傳遞數(shù)據(jù)HTML中的屬性名是大小寫不敏感的,所以瀏覽器會把所有大寫字符解釋為小寫字符。這意味著當使用DOM中的模板時,camelCase的prop名稱需要使用其等價的kebab-case命名。
通常父組件單向(正向)傳遞數(shù)據(jù)給子組件。需要三個步驟:(1)創(chuàng)建父、子組件構(gòu)造器。通過Vue.extend()方法構(gòu)建組件。(2)注冊父、子組件。可以全局或局部注冊各類組件。(3)在Vue實例范圍內(nèi)使用組件。5.2.1父組件向子組件傳值-3【例5-3】靜態(tài)props傳遞數(shù)據(jù)實戰(zhàn)。5.2.1父組件向子組件傳值-4第18~29行定義Vue實例,并設(shè)置el、data選項,myToDos對象數(shù)組準備數(shù)據(jù)。第33~49行定義兩個組件,分別為todoChid、todoParent,并在todoParent組件中局部注冊子組件todoChild為“todoItem”。第51行將組件todoParent注冊為全局組件“mytodo”。3.動態(tài)Props傳遞數(shù)據(jù)
要動態(tài)地綁定父組件的數(shù)據(jù)到子模板的props,與綁定到任何普通的HTML屬性相類似,就是用v-bind。每當父組件的數(shù)據(jù)發(fā)生變化時,都會實時地將變化后的數(shù)據(jù)傳遞給子組件?!纠?-4】動態(tài)Props傳遞數(shù)據(jù)實戰(zhàn)。5.2.1父組件向子組件傳值-55.2.1父組件向子組件傳值-6第40~44行注冊全局組件my-component-1,在組件內(nèi)的模板屬性中定義文本輸入框,采用v-model綁定message屬性。第18行引用組件my-component-1,此時在組件中修改props傳遞過來的數(shù)據(jù),Vue會發(fā)出警告,如圖5-7所示。所以通常采用computed計算屬性去修改props傳遞過來的值。本地定義屬性,并將props作為初始值,props傳入之后需要進行轉(zhuǎn)換,此時使用代碼中第27~32行的定義即實現(xiàn)此功能?!纠?-5】傳值時v-bind使用問題注意:在使用props對子組件傳值時,如果不使用v-bind傳遞數(shù)字、布爾、數(shù)組、對象類型的數(shù)據(jù),此時傳遞的數(shù)據(jù)都是字符串類型,由于模板中未使用v-bind指令綁定屬性,不會被編譯。第12行通過v-bind綁定message,將屬性值作為數(shù)組,所以長度為4。第14行未通過v-bind綁定message,將屬性值作為字符串,所以長度為17。4.Props數(shù)據(jù)驗證
組件props選項的值可以是數(shù)組類型,也可以是對象類型。props選項的對象類型可以用于對外部傳遞進來的參數(shù)進行數(shù)據(jù)驗證。當封裝了一個組件時,對于內(nèi)部接收的參數(shù)進行校驗是非常必要的。default:表示默認值。required:必選。
//如果是數(shù)組或?qū)ο螅J值必須是一個函數(shù)來返回
propE:
{
type:
Array,
default:
function
()
{
return
{};
}
},
//自定義驗證函數(shù)
propF:
{
viladator:
function
(value)
{
return
value
>
10;
}
}
}
});
</script>
<script>
Vponent('my-comp',{
props:{
//必須是數(shù)字類型
propA:
Number,
//必須是字符串或數(shù)字類型
propB:[String,
Number],
//布爾值,如果沒有定義,默認值就是true
propC:{
type:
Boolean,
default:
true
},
//數(shù)字,而且是必選
propD:
{
type:
Number,
required:
true
},
驗證的type類型可以是:String、Number、Boolean、Object、Array、Function。type也可以是一個自定義構(gòu)造器,使用instanceof檢測。prop驗證失敗時,開發(fā)版本下會在控制臺拋出一條警告?!纠?-6】props數(shù)據(jù)驗證5.2.2子組件向父組件傳值1.自定義事件
當子組件需要向父組件傳遞數(shù)據(jù)時,需要使用自定義事件。子組件用$emit()來觸發(fā)自定義事件,父組件使用$on()來監(jiān)聽子組件的事件。父組件也可以直接在子組件的自定義標記上使用v-on指令來監(jiān)聽子組件觸發(fā)的自定義事件。數(shù)據(jù)就通過自定義事件來傳遞。父組件v-on:自定義事件,傳遞數(shù)據(jù)<child-compv-on:eventName="functionName"></child-comp>//父組件中的Vue實例中定義methods選項
methods:{functionName(postdata){//將傳遞來的數(shù)據(jù)postdata進行處理,并對父組件的數(shù)據(jù)進行運算}}子組件$emit()觸發(fā)自定義事件,傳遞數(shù)據(jù)<button@click='increase'>增加1</button>methods:{'increase':function(){
this.$emit('eventName',data);},…} 【語法說明】子組件通過this.$emit("eventName",data)方式來調(diào)用父組件中的functionName方法,同時子組件傳遞數(shù)據(jù)給父組件。父組件使用v-on:xxx(@xxx)來監(jiān)聽自定義事件。需要注意$emit()函數(shù)的第一個參數(shù)是自定義事件的名稱,第二個參數(shù)為數(shù)據(jù),數(shù)據(jù)可以有多個。
【例5-7】子組件向父組件傳遞數(shù)據(jù)【例5-7】子組件向父組件傳遞數(shù)據(jù)第39~51行定義父組件,并通過子組件<my-comp>來監(jiān)聽自定義事件increase、reduce,當事件發(fā)生時調(diào)用changeTotal方法實現(xiàn)傳值。代碼第55~79行定義子組件,在子組件template標記內(nèi)定義兩個按鈕定義單擊事件,來處理子組件的數(shù)據(jù),并將子組件的數(shù)據(jù)傳出。
5.2.2子組件向父組件傳值5.2.2子組件向父組件傳值2.使用v-model
由于Vue3.x中v-model使用方法已經(jīng)變更。用于自定義組件時,v-modelprop和事件默認名稱已更改為以下格式:prop:value->modelValue;event:input->update:modelValue;
在父組件上使用v-model:modelValue='xxx‘指令,子組件中使用this.$emit('update:modelValue',this.子組件屬性)。
父組件中通過v-model指令綁定數(shù)據(jù)modelValue<divid="app"><my-compv-model:modelValue=modelValue'></my-comp></div>子組件中通過事件觸發(fā)$emit(‘update:modelValue’,data)constapp=Vue.createApp(App);ponent('my-comp',{ template:` <divclass='childClass'> <button@click='increase'>增加1</button> </div>`,methods:{ increase(){//計數(shù)器增1this.counter++;this.$emit('update:modelValue',this.counter); },}})【例5-8】v-model指令傳遞數(shù)據(jù)第39~47行定義父組件,并通過子組件my-comp設(shè)置v-model指令綁定父組件的total屬性來處理“update:total”事件發(fā)生接收來自子組件的數(shù)據(jù)this.amount(相當于total=this.counter)?!纠?-8】v-model指令傳遞數(shù)據(jù)代碼第49~73行定義子組件,在子組件template標記內(nèi)定義兩個按鈕定義單擊事件,來處理子組件的數(shù)據(jù),并將子組件的數(shù)據(jù)傳出。5.2.3父鏈與子組件索引
采用父鏈和子組件索引同樣可以實現(xiàn)組件間通信。
在子組件中,使用this.$parent可以直接訪問該組件的父實例或組件,父組件也可以通過this.$children訪問它所有的子組件,而且可以遞歸向上或向下無限訪問,直到根實例或最內(nèi)層的組件。1.父鏈(this.$parent)實現(xiàn)修改父組件數(shù)據(jù)。2.子組件索引(this.$refs.indexName)修改組件數(shù)據(jù)。1.子組件利用父鏈this.$parent來獲取設(shè)置父組件的數(shù)據(jù)。部分代碼如下:constmsg=this.$parent.message;//獲取數(shù)據(jù)this.$parent.message
=
'消息:組件my-comp修改數(shù)據(jù)'
//設(shè)置父組件的數(shù)據(jù)
2.子組件索引this.$refs.indexName修改組件數(shù)據(jù)。部分代碼如下:<my-comp1
ref="comp1"></my-comp1>
<my-comp2
ref="comp2"></my-comp2>
//在事件處理函數(shù)中或JS代碼中this.message
=
this.$p1.message;
//通過$refs獲取子組件的數(shù)據(jù)this.$p1.message=this.message
//通過$refs設(shè)置子組件的數(shù)據(jù)
注意:$refs只在組件渲染完成后才填充,并且它是非響應式的。5.2.4父鏈與子組件索引5.4插槽
在開發(fā)組件時,組件內(nèi)一些子元素希望是由調(diào)用者來定義,組件只負責核心功能,其他非核心可以用戶自由定義,可以增加組件的靈活性和可擴展性。這種的場景非常適合使用插槽。
插槽(Slot)是Vue提出來的一個概念,用于決定將所攜帶的內(nèi)容插入到指定的某個位置,從而使模板分塊,具有模塊化的特點和更大的重用性。
插槽顯不顯示、怎樣顯示是由父組件來控制的,而插槽在哪里顯示就由子組件來進行控制,父頁面在組件標記內(nèi)插入任意內(nèi)容,子組件內(nèi)插槽slot控制擺放位置(匿名插槽、具名插槽)。插槽分類:
(1)匿名插槽:也稱為默認插槽default。沒有命名,有且只有一個。
(2)具名插槽:相對匿名插槽組件slot標記帶name命名的。
(3)作用域插槽:子組件內(nèi)數(shù)據(jù)可以被父頁面拿到(解決了數(shù)據(jù)只能從父頁面?zhèn)鬟f給子組件)。5.4.1匿名插槽
匿名插槽通常也稱為“默認插槽”。使用<slot></slot>元素來為需要傳遞的內(nèi)容占個位置,類似于內(nèi)容占位符?!净A(chǔ)語法】
(1)父組件中使用子組件標記,并攜帶傳遞的內(nèi)容。
<child><p>父組件需要分發(fā)給子組件的內(nèi)容...</p></child>
(2)子組件中模板中插入插槽標記。constComp1={template:`<divclass="comp"> <h3>這是子組件...</h3> <slot></slot> <slot></slot> … </div>`}//Vue實例中注冊子組件constApp={
components:{
child:Comp1,
},
};反引號【語法說明】
子組件渲染時,會將slot標記使用父組件中子組件標記的內(nèi)容所替換。子組件中如果有多個默認插槽,將會同時被父組件傳遞的內(nèi)容所替換。如果在子組件的模板中沒有插入slot標記的話,則父組件中使用子組件標記的內(nèi)容將被忽略?!纠?-10】默認插槽的使用5.4.2具名插槽slot元素可以用一個特殊的屬性name來配置如何分發(fā)內(nèi)容,多個slot可以有不同的名字,根據(jù)具名slot的name來進行匹配,顯示內(nèi)容。
如果有匿名slot,那么沒有匹配到的內(nèi)容將會顯示到匿名slot中;如果沒有匿名slot,那么沒有匹配到的內(nèi)容將會被拋棄。
在向具名插槽提供內(nèi)容的時候,也可以在一個template元素上使用v-slot指令,并以v-slot的參數(shù)的形式提供其名稱(如v-slot:slotname)。template元素中的所有內(nèi)容都將會被傳入相應的插槽中。任何沒有被包裹在帶有v-slot的template元素中的內(nèi)容都會被視為匿名插槽的內(nèi)容。當然也可以在一個template元素中包裹匿名(默認)插槽的內(nèi)容?!净菊Z法】(1)在父組件中的子組件標記內(nèi),使用帶slot屬性的標記或帶v-slot指令參數(shù)的template元素來攜帶傳遞的內(nèi)容。<child><p>該內(nèi)容將顯示在匿名插槽中。</p><template><p>使用匿名插槽--該內(nèi)容將顯示在匿名插槽中。</p></template><templatev-slot:slot1|#slot1><p>使用v-slot指令--該內(nèi)容將顯示在具名插槽slot1中。</p></template><pslot='slot2'>使用slot屬性--該內(nèi)容將顯示在具名插槽slot2中。</p></child>(2)子組件中模板中插入具名插槽標記(使用name屬性)。constComp1={ template:` <divclass="comp"> <h3>這是子組件...</h3> <slotname='slot1'></slot> <slotname='slot2'></slot> <slot></slot> </div> `}//Vue實例中注冊子組件components:{'child':Comp1,}5.4.2具名插槽【語法說明】
父組件中使用子組件標記,并在其中插入多個帶slot屬性的標記,其屬性值為子組件中定義slot元素所指定的name屬性值。子組件渲染時,匹配到slot元素(name的屬性值)會被父組件中子組件標記的內(nèi)具有相應的slot屬性值的標記的內(nèi)容所替換。在父組件中可以使用帶“v-slot:slotname”參數(shù)的template元素來攜帶傳遞內(nèi)容,同樣會匹配到帶name屬性的具名插槽。V-slot:slot1等價于#slot1,這叫語法糖【例5-11】具名插槽與匿名插槽混合使用5.4.3作用域插槽Vue2.6.0引入v-slot指令,提供支持slot和slot-scope屬性的API替代方案。作用域插槽可用作一個能被傳遞數(shù)據(jù)的可重用模版。
匿名插槽和具名插槽的內(nèi)容和樣式皆由父組件決定,即顯示什么內(nèi)容和怎樣顯示都由父組件決定;作用域插槽的樣式由父組件決定,內(nèi)容卻由子組件控制。簡單來說:前兩種插槽不能綁定數(shù)據(jù),作用域插槽是一個帶綁定數(shù)據(jù)的插槽。獲取子組件slot中攜帶的數(shù)據(jù)的關(guān)鍵步驟:
(1)在slot元素上使用v-bind指令綁定一個特定屬性,這個屬性稱為插槽prop。<slotv-bind:customAttribute="childDataOptions"></slot>customAttribute:為用戶自定義的屬性,為父組件提供數(shù)據(jù)對象;childDataOptions:為子組件data中的屬性或?qū)ο蟆?/p>
(2)在父組件上訪問綁定到slot插槽上的prop對象。<templatev-slot:default|slotname="slotProps"> <p>來自父組件的內(nèi)容</p> <p>{{slotProps.customAttribute}}</p></template>【例5-12】作用域插槽的應用第37~54行全局定義子組件child,在模板選項中插入插槽,綁定item屬性,循環(huán)遍歷items數(shù)組變量中的所有數(shù)據(jù),其中v-for=‘item
in
items’中的item是臨時變量。而綁定在插槽slot元素上的item屬性稱為“插槽prop”,在父級作用域中,可以使用帶值的v-slot來定義子組件提供的插槽prop的名字,方法如第30行中{{props.item.id}}等。
【例5-13】作用域插槽的應用5.4.4動態(tài)插槽名
動態(tài)指令參數(shù)也可以用在v-slot上,來定義動態(tài)的插槽名。部分示例代碼如下:<my-child>
<template
v-slot:[dynamicSlotName]>
...
</template>
</my-child>
動態(tài)插槽名需要使用“[]”來包裹,dynamicSlotName是一個變量,然后在Vue實例的data選項中定義動態(tài)插槽名,并給其賦初值。通過其他事件來改變動態(tài)插槽名,達到動態(tài)渲染子組件?!纠?-13】動態(tài)插槽名的應用。【例5-13】動態(tài)插槽名的應用本章小結(jié)本章主要介紹了組件基礎(chǔ)、組件間通信和插槽的基礎(chǔ)概念和基本使用語法。組件基礎(chǔ)中重點介紹了組件的命名規(guī)范和注冊方法。Vue組件中通常采用camelCase(駝峰式)命名或kebab-case(短橫線分隔式)命名方式。組件可以全局注冊ponent(),也可以局部注冊(在App內(nèi)通過components選項中注冊)。重點講解了匿名插槽、具名插槽、作用域插槽及動態(tài)插槽名的應用場景和基本語法。思考與拓展總結(jié)與提高本章小結(jié)組件間通信主要講解了父組件向子組件傳值、子組件向父組件傳值和兄弟組件之間通信等。在子組件中使用props來使用父組件傳遞過來的數(shù)據(jù),這是單向傳遞,只能從父組向子組件傳遞。子組件用$emit()來觸發(fā)自定義事件,父組件通過$on()或v-on:eventname來監(jiān)聽子組件的事件,父組件也可以使用v-model指令通過input事件來傳遞數(shù)據(jù)。當然也可以通過父鏈與子組件索引來傳遞數(shù)據(jù)。插槽主要講解了匿名插槽、具名插槽(設(shè)置name屬性)、作用域插槽(v-slot:slotname或slot-scope=‘Props’)以及動態(tài)插槽名(v-slot:[dynslot])等方面的父子組件數(shù)據(jù)傳遞的方法。思考與拓展總結(jié)與提高40思政第6章-Vue.js過渡與動畫(4學時)教學目標1.熟悉過渡類名的含義和命名規(guī)范。2.掌握單元素/單組件的過渡方法。3.掌握初始渲染過渡的方法。4.掌握列表進入/離開、排序和交錯過渡的實現(xiàn)方法。5.學會編寫帶有Vue.js過渡和動畫效果的頁面。416.1單元素/組件的過渡Vue在插入、更新或者移除DOM時,提供多種不同方式的應用過渡效果。包括以下工具:(1)在CSS過渡和動畫中自動應用class。(2)可以配合使用第三方CSS動畫庫,如Animate.css。(3)在過渡鉤子函數(shù)中使用JavaScript直接操作DOM。(4)可以配合使用第三方JavaScript動畫庫,如Velocity.js。Vue提供了內(nèi)置的過渡封裝組件,該組件用于包裹要實現(xiàn)過渡效果的組件。Vue提供了<transition>的封裝組件,可以給任何元素和組件添加進入/離開過渡。Vue的transiton標記的語法:<transition
name="slide-fade">
<div>
<p
v-if="flag"><img
src="image-6-1.jpg"></p>
</div>
</transition>
使用情形如下:(1)條件渲染(使用v-if)(2)條件展示(使用v-show)(3)動態(tài)組件(4)組件根節(jié)點【例6-1】單元素(圖像)過渡實戰(zhàn)6.1.1過渡的類名
在進入/離開的過渡中,會有6個class切換(v代表在沒有transitionname的時候調(diào)用)。(1)v-enter-from:定義進入過渡的開始狀態(tài)。在元素被插入之前生效,在元素被插入之后的下一幀移除。(2)v-enter-active:定義進入過渡生效時的狀態(tài)。在整個進入過渡的階段中應用,在元素被插入之前生效,在過渡/動畫完成之后移除。這個類可以被用來定義進入過渡的過程時間,延遲和曲線函數(shù)。(3)v-enter-to:定義進入過渡的結(jié)束狀態(tài)。在元素被插入之后下一幀生效(與此同時v-enter被移除),在過渡/動畫完成之后移除。(4)v-leave-from:定義離開過渡的開始狀態(tài)。在離開過渡被觸發(fā)時立刻生效,下一幀被移除。(5)v-leave-active:定義離開過渡生效時的狀態(tài)。在整個離開過渡的階段中應用,在離開過渡被觸發(fā)時立刻生效,在過渡/動畫完成之后移除。這個類可以被用來定義離開過渡的過程時間,延遲和曲線函數(shù)。(6)v-leave-to:定義離開過渡的結(jié)束狀態(tài)。在離開過渡被觸發(fā)之后下一幀生效(與此同時v-leave被刪除),在過渡/動畫完成之后移除。
對于這些在過渡中切換的類名來說,如果使用不帶name屬性的<transition>,則“v-”將作為這些類名的默認前綴。如果使用了<transitionname="my-transition"></transition>,那么v-enter會替換為my-transition-enter-from。v-enter-active和v-leave-active可以控制進入/離開過渡的不同的緩和曲線。
過渡屬性與不透明度的關(guān)系圖6.1.1過渡的類名6.1.2CSS過渡
常用的過渡都是使用CSS過渡,同時可以設(shè)置持續(xù)時間和動畫函數(shù)。【例6-2】與【例6-1】有些類似,只是在使用CSS過渡時定義動畫函數(shù)。該案例使用兩個transition標記,一個帶有name屬性,一個不帶name屬性。帶name屬性的過渡標記適用類樣式以”slide-fade-”開開頭,不帶name屬性的過渡標記適用樣式以“v-”開頭。以下樣式同時定義了過渡時間函數(shù):.slide-fade-leave-active{transition:all.8scubic-bezier(1.0,0.5,0.8,1.0);}【例6-2】CSS過渡實戰(zhàn)
所謂動畫就是讓一個元素從一個狀態(tài)逐漸向另一個狀態(tài)轉(zhuǎn)變的過程??梢栽谶@個過程中改變元素的CSS屬性。動畫可以反復播放。CSS動畫(CSSAnimations)用法同CSS過渡,區(qū)別是在動畫中v-enter類名在節(jié)點插入DOM后不會立即刪除,而是在animationend事件觸發(fā)時刪除。6.1.3CSS動畫【例6-3】CSS動畫實戰(zhàn)。
第10行和第13行定義類名為“animation-enter-active(入場動畫的時間段)”和“.animation-leave-active(離場動畫的時間段)”的樣式,綁定動畫myAnimations,并設(shè)置延時和反轉(zhuǎn)效果。
第17~21行定義關(guān)鍵幀,指定動畫名稱為“myAnimations”,在其中定義3個過渡狀態(tài),分別0%、50%、100%,并設(shè)置轉(zhuǎn)換效果(縮放一定的倍數(shù))?!纠?-3】CSS動畫實戰(zhàn)6.1.4自定義過渡的類名
可以通過以下屬性(attribute)來自定義過渡類名:enter-from-classenter-active-classenter-to-classleave-from-classleave-active-classleave-to-class
它們的優(yōu)先級高于普通的類名,這對于Vue的過渡系統(tǒng)和其他第三方CSS動畫庫,例如animate.css(https://animate.style/)結(jié)合使用十分有用。
animate.css是一個來自國外的CSS3動畫庫,它預設(shè)了抖動(shake)、閃爍(flash)、翻轉(zhuǎn)(flip)、彈跳(bounce)、旋轉(zhuǎn)(rotateIn/rotateOut)、淡入淡出(fadeIn/fadeOut)等多達60多種動畫效果,幾乎包含了所有常見的動畫效果?!纠?-4】自定義過渡類名實戰(zhàn)
第10行定義了鏈接特定版本的外部樣式表文件“animate.css”。第23~25行給transition標記定義name屬性,值為“custom-classes-transition”。并給該標記添加自定義enter-active-class、leave-active-class屬性,其值分別為“animated
tada(晃動效果)”、“animated
bounceOutRight(動畫從右側(cè)彈跳)”6.1.5同時使用過渡和動畫Vue通過設(shè)置相應的事件監(jiān)聽器來了解過渡完成情況??梢允莟ransitionend或animationend,這取決于給元素應用的CSS規(guī)則。如果使用其中任何一種,Vue能自動識別類型并設(shè)置監(jiān)聽。
但是,在一些場景中,可能需要給同一個元素同時設(shè)置兩種過渡動效,比如animation很快的被觸發(fā)并完成了,而transition效果還沒結(jié)束。在這種情況中,就需要使用type屬性并設(shè)置animation或transition來明確聲明所需要Vue監(jiān)聽的類型。6.1.6顯性的過渡持續(xù)時間
在大多情況下,Vue可以自動得出過渡效果的完成時機。默認情況下,Vue會等待其在過渡效果的根元素的第一個transitionend或animationend事件。然而也可以不這樣設(shè)定,例如,可以精心編排的一系列過渡效果,其中一些嵌套的內(nèi)部元素相比于過渡效果的根元素有延遲的或更長的過渡效果。
在這種情況下,可以用<transition>組件上的duration
prop定制一個顯性的過渡持續(xù)時間(以毫秒計):<transition:duration="1000">...</transition>也可以定制進入和移出的持續(xù)時間:<transition:duration="{enter:500,leave:800}">...</transition>【例6-5】同時使用過渡與動畫和持續(xù)過渡時間實戰(zhàn)6.1.5同時使用過渡和動畫6.1.7JavaScript鉤子可以在屬性中聲明JavaScript鉤子。參考代碼如下所示:注意:當只用JavaScript過渡的時候,在enter和leave中必須使用done進行回調(diào)。否則,它們將被同步調(diào)用,過渡會立即完成。推薦對于僅使用JavaScript過渡的元素添加v-bind:css="false",Vue會跳過CSS的檢測。這也可以避免過渡過程中CSS的影響。6.1.8Velocity動畫庫簡介1.Velocity.js簡介Velocity是一個簡單易用、高性能、功能豐富的輕量級JS動畫庫。它能和jQuery完美協(xié)作,并和$.animate()有相同的API,但它不依賴jQuery,可單獨使用。
Velocity不僅包含了$.animate()的全部功能,還擁有顏色動畫、轉(zhuǎn)換動畫(transforms)、循環(huán)、緩動、SVG動畫、和滾動動畫等特色功能。同時還支持duration、loop、delay、display等動畫配置項的設(shè)置。
Velocity比$.animate()更快更流暢,性能甚至高于CSS3animation,是jQuery和CSS3transition的最佳組合,它支持所有現(xiàn)代瀏覽器。2.velocity的使用Velocity引入方法如下:<scriptsrc="/ajax/libs/velocity/1.5.0/velocity.min.js"></script>也可以將velocity.min.js文件下載到本地項目開發(fā)的公共子文件夾js中,供本地地調(diào)用。<scriptsrc="../js/velocity.min.js"></script>【基本語法】Velocity(element,{property:value},{option:optionvalue});【語法說明】element:表示DOM元素。{}:表示屬性值對,可以有多個屬性值對。要在同一個元素上鏈接另一個動畫,只需在之前的velocity后再添加一個。Velocity(element1,{property:value},{option:optionValue});Velocity(element1,{property:value},{option:optionValue});【例6-6】JavaScript鉤子與velocity.js結(jié)合使用實戰(zhàn)。6.1.8Velocity動畫庫簡介6.2初始渲染的過渡
可以通過appear屬性設(shè)置節(jié)點在初始渲染(出現(xiàn)時)的過渡。這里默認和進入/離開過渡一樣,同樣也可以自定義CSS類名。標記語法如下:<transition
appear
appear-class="custom-appear-class"
appear-to-class="custom-appear-to-class"
appear-active-class="custom-appear-active-class"
>
<!--
...
-->
</transition>
也可以自定義JavaScript鉤子。標記語法如下:<transition
appear
v-on:before-appear="customBeforeAppearHook"
v-on:appear="customAppearHook"
v-on:after-appear="customAfterAppearHook"
v-on:appear-cancelled="customAppearCancelledHook"
>
<!--
...
-->
</transition>
在上面的例子中,無論是appear屬性,還是v-on:appear鉤子都會生成初始渲染過渡。6.3多個元素的過渡
最常見的多標記過渡是一個列表和描述這個列表為空消息的元素。標記語法如下:<transition>
<ul
v-if="items.length
>
0">
<!--
...
-->
</ul>
<p
v-else>對不起,沒有發(fā)現(xiàn)列表項.</p>
</transition>
注意:當有相同標記名的元素切換時,需要通過key屬性設(shè)置唯一的值來標識,以讓Vue區(qū)分它們,否則Vue為了效率只會替換相同標記內(nèi)部的內(nèi)容。即使在技術(shù)上沒有必要,給在<transition></transition>組件中的多個元素設(shè)置key是一個更好的實踐。
在一些場景中,也可以通過給同一個元素的key屬性設(shè)置不同的狀態(tài)來代替v-if和v-else。上面的例子可以改寫如下格式:<transition>
<button
v-bind:key="isEditing">
{{
isEditing
?
'保存'
:
'編輯'
}}
</button>
</transition>
6.3多個元素的過渡
使用多個v-if的多個元素的過渡可以重寫為綁定了動態(tài)property的單個元素過渡。<transition>
<button
v-if="docState
===
'saved'"
key="saved">編輯</button>
<button
v-if="docState
===
'edited'"
key="edited">保存</button>
<button
v-if="docState
===
'editing'"
key="editing">取消</button>
</transition>
這種形式也可以重定義為如下格式:<!--HTML部分
-->
<transition>
<button
v-bind:key="docState">
{{
buttonMessage
}}
</button>
</transition>
…//JS部分
computed:
{
buttonMessage:
function
()
{
switch
(this.docState)
{
case
'saved':
return
'編輯'
case
'edited':
return
'保存'
case
'editing':
return
'取消'
}
}
}
在下列部分代碼中,在“on”按鈕和“off”按鈕的過渡中,兩個按鈕都被重繪了,一個離開過渡的時候,另一個開始進入過渡。這是<transition></transition>的默認行為(進入和離開同時發(fā)生)。<transition
name="no-mode-fade">
<button
v-if="on"
key="on"
@click="on
=
false">on</button>
<button
v-else
key="off"
@click="on
=
true">off</button>
</transition>
<style>
.no-mode-fade-enter-active,
.no-mode-fade-leave-active
{transition:
opacity
.5s}
.no-mode-fade-enter,.no-mode-fade-leave-to
{opacity:
0}
</style>
Vue提供了過渡模式,通過mode屬性來設(shè)置,其值為“in-out/out-in”。其作用:in-out:新元素先進行過渡,完成之后當前元素過渡離開。out-in:當前元素先進行過渡,完成之后新元素過渡進入。<transition
name="with-mode-fade"
mode="out-in">
<button
v-if="on"
key="on"
@click="on
=
false">
on
</button>
<button
v-else=""
key="off"
@click="on
=
true">
off
</button>
</transition>
其中in-out模式不經(jīng)常使用,但對于一些稍微不同的過渡效果還是很有用的。過渡模式-mode屬性【例6-7】多個元素的過渡綜合實戰(zhàn)【例6-7】多個元素的過渡綜合實戰(zhàn)-2【例6-7】多個元素的過渡綜合實戰(zhàn)-36.4多個組件的過渡
多個組件的過渡簡單很多,一般不需要使用key屬性。相反,可以只需要使用動態(tài)組件。使用“內(nèi)置組件+v-bind:is”可以實現(xiàn)動態(tài)組件?!净A(chǔ)語法】
<transition
name="component-fade"
mode="out-in">
<component
v-bind:is="display"></component>
</transition>
【語法說明】<component></component>元素是Vue里面的一個內(nèi)置組件。使用“is”屬性(需要通過v-bind給“is”綁定一個值)。“is”綁定的值(display)傳入一個組件名,就會切換到這個組件?!纠?-8】多組件過渡的實戰(zhàn)第55~57行定義動態(tài)組件,使用component內(nèi)置組件并綁定is屬性(值為“display”)來動態(tài)渲染組件。第23~31行定義過渡類樣式【例6-8】多組件過渡的實戰(zhàn)-2
6.5列表過渡
我們已經(jīng)熟悉了單個節(jié)點、同一時間渲染多個節(jié)點中的一個過渡/動畫的方法。那么如果需要動態(tài)渲染整個列表,例如使用v-for去遍歷所有的列表項呢?在這種場景中,不能使用<transition></transition>組件,需要使用<transition-group></transition-group>組件。
在深入案例之前,先了解一下關(guān)于這個組件的一些特點:(1)不同于<transition></transition>,它會以一個真實元素呈現(xiàn),默認為一個<span></span>??梢酝ㄟ^tag屬性更換為其他元素。代碼舉例如下:<transition-groupname="list"tag="p"><spanv-for="iteminitems"v-bind:key="item"class="list-item">{{item}}</span>
</transition-group>(2)過渡模式不可用,因為不再相互切換特有的元素。(3)內(nèi)部元素總是需要提供唯一的key屬性值。(4)CSS過渡的類將會應用在內(nèi)部的元素中,而不是這個組/容器本身。6.5.1列表的進入/離開過渡
使用<transition-group></transition-group>來渲染列表,通過name屬性來定義過渡的CSS類名。其語法如下:<ul>
<transition-group
name="myList">
<li
v-for="(student,index)
in
students"
:key="">
{{index}}------{{}}------{{student.age}}
</li>
</transition-group>
</ul>
【例6-9】列表的進入/離開過渡?!纠?-9】列表的進入/離開過渡【例6-9】列表的進入/離開過渡-2這是列表過渡初始效果這是列表成員增加時入場過渡效果這是列表成員離場過渡效果6.5.2列表的排序過渡<transition-group>組件不僅可以實現(xiàn)列表的進入和離開動畫,還可以改變定位。要使用這個新功能只需了解新增的類v-move,它會在元素的改變定位的過程中應用。與之前的類名一樣,可以通過name屬性來自定義前綴,也可以通過move-class屬性來手動設(shè)置。v-move對于設(shè)置過渡的切換時機和過渡曲線非常有用。需要借助于lodash.min.js來實現(xiàn)數(shù)組切換的各種效果。1.Lodash.js簡介
Loash.js是一個一致性、模塊化、高性能的JavaScript實用工具庫。通過降低array、number、objects、string等的使用難度,從而讓JavaSc
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
- 6. 下載文件中如有侵權(quán)或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 《跳蹦蹦床的大象》少兒美術(shù)教育繪畫課件創(chuàng)意教程教案
- 蒲公英課件文庫
- 西南林業(yè)大學《產(chǎn)品攝影》2023-2024學年第一學期期末試卷
- 西京學院《設(shè)計模式》2023-2024學年第一學期期末試卷
- 2023年1月福建省普通高中學業(yè)水平合格性考試歷史試題(原卷版)
- 陀螺課件 圖文
- 西京學院《面向?qū)ο蟪绦蛟O(shè)計》2022-2023學年期末試卷
- 西華師范大學《小學數(shù)學課程與教學》2022-2023學年第一學期期末試卷
- 西華師范大學《運動技能學習與控制》2022-2023學年期末試卷
- 臺兒莊介紹課件
- 金手指外觀檢驗重點標準
- 電機維護保養(yǎng)作業(yè)指導書
- 國家開放大學《實用心理學》形考任務1-4參考答案
- 撤回支付令異議申請書
- 公元紀年法-完整版PPT
- 小學語文人教五年級上冊(統(tǒng)編2023年更新)第五單元-群文閱讀《說明方法的妙用》教學設(shè)計
- 高中英語外研版高中選修7Scopeandsequence-英語長難句教學反思
- 內(nèi)部控制案例第06章案例18 樂視
- 科技金融項目銀行工作總結(jié)匯報PPT模板
- 品質(zhì)異常升級管理規(guī)定
- 實驗室ISO17025認證推進計劃表
評論
0/150
提交評論